From bec267092ee09dd14032a6d08eae1be22d9858c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Tue, 15 Aug 2023 09:37:55 -0700 Subject: [PATCH 001/783] [release/8.0] Bump to RC2 (#90557) * [release/8.0] Bump to RC2 Bump the base release/8.0 branch to target RC2. * Set prerelease to 0 in configureplatform.make --- eng/Versions.props | 2 +- eng/native/configureplatform.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 3cccff5761371c..8b6faffed23598 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,7 +10,7 @@ 7.0.8 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) rc - 1 + 2 -$(PreReleaseVersionLabel).$(PreReleaseVersionIteration) $(SdkBandVersion)$(WorkloadVersionSuffix) - + false true - 113.0.5672.63 - 1121455 - <_ChromeBaseSnapshotUrl>https://storage.googleapis.com/chromium-browser-snapshots/Linux_x64/1121461 + 115.0.5790.170 + 1148114 + <_ChromeBaseSnapshotUrl>https://storage.googleapis.com/chromium-browser-snapshots/Linux_x64/1148123 - 113.0.5672.64 - 1121455 - <_ChromeBaseSnapshotUrl>https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/1121477 + 115.0.5790.171 + 1148114 + <_ChromeBaseSnapshotUrl>https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/1148119 From 94f0a7167cfd8fdf9387e57045473190281e1bb9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 18:24:12 -0700 Subject: [PATCH 007/783] [release/8.0-rc1] [mono][ios] Revert LLVM mode for apple mobile tests (#90624) * Revert LLVM mode for apple mobile tests * Add comment --------- Co-authored-by: Milos Kotlar --- eng/testing/tests.ioslike.targets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/testing/tests.ioslike.targets b/eng/testing/tests.ioslike.targets index 9151c7c7db05e5..f93afcf1dfb31b 100644 --- a/eng/testing/tests.ioslike.targets +++ b/eng/testing/tests.ioslike.targets @@ -15,8 +15,8 @@ <_AOTBuildCommand Condition="'$(ContinuousIntegrationBuild)' != 'true'">$(_AOTBuildCommand) /p:RuntimeSrcDir=$(RepoRoot) /p:RuntimeConfig=$(Configuration) - - <_AOTBuildCommand>$(_AOTBuildCommand) /p:XHARNESS_EXECUTION_DIR="$XHARNESS_EXECUTION_DIR" /p:RunAOTCompilation=$(RunAOTCompilation) /p:UseNativeAOTRuntime=$(UseNativeAOTRuntime) /p:TargetOS=$(TargetOS) /p:TargetArchitecture=$(TargetArchitecture) /p:MonoForceInterpreter=$(MonoForceInterpreter) /p:DevTeamProvisioning=$(DevTeamProvisioning) /p:UsePortableRuntimePack=true /p:Configuration=$(Configuration) + + <_AOTBuildCommand>$(_AOTBuildCommand) /p:XHARNESS_EXECUTION_DIR="$XHARNESS_EXECUTION_DIR" /p:RunAOTCompilation=$(RunAOTCompilation) /p:UseNativeAOTRuntime=$(UseNativeAOTRuntime) /p:TargetOS=$(TargetOS) /p:TargetArchitecture=$(TargetArchitecture) /p:MonoForceInterpreter=$(MonoForceInterpreter) /p:MonoEnableLLVM=true /p:DevTeamProvisioning=$(DevTeamProvisioning) /p:UsePortableRuntimePack=true /p:Configuration=$(Configuration) <_AOTBuildCommand>$(_AOTBuildCommand) <_ResetSimulatorSwitch Condition="'$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'tvossimulator'">--reset-simulator From 6222fca7914de6790a96079c75021b8263a87ad0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 21:50:33 -0700 Subject: [PATCH 008/783] [release/8.0-rc1] [workloads] Put quotes around GetFileName call when collecting telemetry (#90606) * [workloads] Put quotes around GetFileName call when collecting telemetry There are cases where `%(ReferencePath)` is empty, so prevent exceptions by quoting the value. Fixes https://github.com/dotnet/runtime/issues/90584 * Feedback --------- Co-authored-by: Steve Pfister Co-authored-by: Steve Pfister --- .../WorkloadTelemetry.targets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets index f9cd6efe170a2c..8f78ce16b62587 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets @@ -38,8 +38,8 @@ - <_WorkloadUsesOther Condition="'$([System.IO.Path]::GetFileName(%(ReferencePath.Identity)).ToLower())' == 'avalonia.dll'">true - <_WorkloadUsesOther Condition="'$([System.IO.Path]::GetFileName(%(ReferencePath.Identity)).ToLower())' == 'uno.dll'">true + <_WorkloadUsesOther Condition="'$([System.IO.Path]::GetFileName("%(ReferencePath.Identity)").ToLowerInvariant())' == 'avalonia.dll'">true + <_WorkloadUsesOther Condition="'$([System.IO.Path]::GetFileName("%(ReferencePath.Identity)").ToLowerInvariant())' == 'uno.dll'">true <_WorkloadUsesMobileSDKOnly Condition="'$(RuntimeIdentifier)' != 'browser-wasm' and '$(UseMaui)' != 'true' and '$(_WorkloadUsesOther)' != 'true'">true From b1225e7c0902f82362afc9cc21b632462a9339b4 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 07:17:22 -0700 Subject: [PATCH 009/783] Update dependencies from https://github.com/dotnet/emsdk build 20230815.5 (#90649) Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rc.1.23411.2 -> To Version 8.0.0-rc.1.23415.5 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 76bf5019cd8ed2..e31341152d13b0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,9 +90,9 @@ 2f4ef297939628143389ddeea569874ded0b1c1b - + https://github.com/dotnet/emsdk - abfa03c97f4175d4d209435cd0e71f558e36c3fd + 66dbaefff04250dc72849f0172e0c53bcfb3ab38 diff --git a/eng/Versions.props b/eng/Versions.props index 3cccff5761371c..ff21c1ee1f07dc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -238,7 +238,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.0-rc.1.23411.2 + 8.0.0-rc.1.23415.5 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda From b33c596d0dd56b509ad4ad144985d00e21d08035 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 07:26:12 -0700 Subject: [PATCH 010/783] [release/8.0] Return false from ComWrappers.Try... methods (#90635) * Return false from ComWrappers.Try... methods Return false from ComWrappers.TryGetComInstance/TryGetObject instead of throwing PNSE. It saves callers from needing to protect against PNSE. Fix #90311 * More efficient IsWindows check --------- Co-authored-by: Jan Kotas --- .../src/System/ComponentModel/TypeDescriptor.cs | 2 +- .../InteropServices/ComWrappers.PlatformNotSupported.cs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs index 874fa6e2e7d03e..2efd53e6223ae7 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs @@ -1542,7 +1542,7 @@ private static TypeDescriptionNode NodeFor(object instance, bool createDelegator { type = ComObjectType; } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + else if (OperatingSystem.IsWindows() && ComWrappers.TryGetComInstance(instance, out nint unknown)) { // ComObjectType uses the Windows Forms provided ComNativeDescriptor. It currently has hard Win32 diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.PlatformNotSupported.cs index 2d2a812cb41a07..37c25f851538a7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.PlatformNotSupported.cs @@ -11,12 +11,14 @@ public abstract partial class ComWrappers { public static unsafe bool TryGetComInstance(object obj, out IntPtr unknown) { - throw new PlatformNotSupportedException(); + unknown = default; + return false; } public static unsafe bool TryGetObject(IntPtr unknown, [NotNullWhen(true)] out object? obj) { - throw new PlatformNotSupportedException(); + obj = default; + return false; } public partial struct ComInterfaceDispatch From d29067bc3bc614ed08a5e6cd94baff0481f435e6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 07:38:41 -0700 Subject: [PATCH 011/783] [release/8.0-rc1] Fix support for non-public default constructors using JsonIncludeAttribute (#90615) * Fix support for non-public constructors using JsonIncludeAttribute * Address feedback. --------- Co-authored-by: Eirik Tsarpalis --- .../DefaultJsonTypeInfoResolver.Helpers.cs | 21 ++++++++++++++- .../Serialization/Metadata/MemberAccessor.cs | 5 ++-- .../ReflectionEmitCachingMemberAccessor.cs | 6 ++--- .../Metadata/ReflectionEmitMemberAccessor.cs | 15 ++++++----- .../Metadata/ReflectionMemberAccessor.cs | 27 +++++++------------ .../ConstructorTests.AttributePresence.cs | 18 +++++++++++++ .../TestClasses/TestClasses.Constructor.cs | 27 +++++++++++++++++++ .../Serialization/ConstructorTests.cs | 6 +++++ 8 files changed, 95 insertions(+), 30 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs index 7ec9db9adc7739..8ee9f3db0283b4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs @@ -49,7 +49,7 @@ private static JsonTypeInfo CreateTypeInfoCore(Type type, JsonConverter converte typeInfo.PopulatePolymorphismMetadata(); typeInfo.MapInterfaceTypesToCallbacks(); - Func? createObject = MemberAccessor.CreateConstructor(typeInfo.Type); + Func? createObject = DetermineCreateObjectDelegate(type, converter); typeInfo.SetCreateObjectIfCompatible(createObject); typeInfo.CreateObjectForExtensionDataProperty = createObject; @@ -411,5 +411,24 @@ internal static void DeterminePropertyAccessors(JsonPropertyInfo jsonPrope break; } } + + [RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)] + [RequiresDynamicCode(JsonSerializer.SerializationRequiresDynamicCodeMessage)] + private static Func? DetermineCreateObjectDelegate(Type type, JsonConverter converter) + { + ConstructorInfo? defaultCtor = null; + + if (converter.ConstructorInfo != null && !converter.ConstructorIsParameterized) + { + // A parameterless constructor has been resolved by the converter + // (e.g. it might be a non-public ctor with JsonConverterAttribute). + defaultCtor = converter.ConstructorInfo; + } + + // Fall back to resolving any public constructors on the type. + defaultCtor ??= type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, binder: null, Type.EmptyTypes, modifiers: null); + + return MemberAccessor.CreateParameterlessConstructor(type, defaultCtor); + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/MemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/MemberAccessor.cs index 326ab657b8899d..ff6c442fa488cb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/MemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/MemberAccessor.cs @@ -9,8 +9,9 @@ namespace System.Text.Json.Serialization.Metadata { internal abstract class MemberAccessor { - public abstract Func? CreateConstructor( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type classType); + public abstract Func? CreateParameterlessConstructor( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type, + ConstructorInfo? constructorInfo); public abstract Func CreateParameterizedConstructor(ConstructorInfo constructor); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitCachingMemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitCachingMemberAccessor.cs index a243f4be4d86a6..e30f87d76da9f1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitCachingMemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitCachingMemberAccessor.cs @@ -21,12 +21,12 @@ internal sealed partial class ReflectionEmitCachingMemberAccessor : MemberAccess => s_cache.GetOrAdd((nameof(CreateAddMethodDelegate), typeof(TCollection), null), static (_) => s_sourceAccessor.CreateAddMethodDelegate()); - public override Func? CreateConstructor([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type classType) - => s_cache.GetOrAdd((nameof(CreateConstructor), classType, null), + public override Func? CreateParameterlessConstructor([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type, ConstructorInfo? ctorInfo) + => s_cache.GetOrAdd((nameof(CreateParameterlessConstructor), type, ctorInfo), [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2077:UnrecognizedReflectionPattern", Justification = "Cannot apply DynamicallyAccessedMembersAttribute to tuple properties.")] #pragma warning disable IL2077 // The suppression doesn't work for the trim analyzer: https://github.com/dotnet/roslyn/issues/59746 - static (key) => s_sourceAccessor.CreateConstructor(key.declaringType)); + static (key) => s_sourceAccessor.CreateParameterlessConstructor(key.declaringType, (ConstructorInfo?)key.member)); #pragma warning restore IL2077 public override Func CreateFieldGetter(FieldInfo fieldInfo) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs index 6e05e5c8057ac7..4b0b426bdaa9ef 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs @@ -13,18 +13,19 @@ namespace System.Text.Json.Serialization.Metadata [RequiresDynamicCode(JsonSerializer.SerializationRequiresDynamicCodeMessage)] internal sealed class ReflectionEmitMemberAccessor : MemberAccessor { - public override Func? CreateConstructor( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) + public override Func? CreateParameterlessConstructor( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type, + ConstructorInfo? constructorInfo) { Debug.Assert(type != null); - ConstructorInfo? realMethod = type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, binder: null, Type.EmptyTypes, modifiers: null); + Debug.Assert(constructorInfo is null || constructorInfo.GetParameters().Length == 0); if (type.IsAbstract) { return null; } - if (realMethod == null && !type.IsValueType) + if (constructorInfo is null && !type.IsValueType) { return null; } @@ -38,8 +39,10 @@ internal sealed class ReflectionEmitMemberAccessor : MemberAccessor ILGenerator generator = dynamicMethod.GetILGenerator(); - if (realMethod == null) + if (constructorInfo is null) { + Debug.Assert(type.IsValueType); + LocalBuilder local = generator.DeclareLocal(type); generator.Emit(OpCodes.Ldloca_S, local); @@ -49,7 +52,7 @@ internal sealed class ReflectionEmitMemberAccessor : MemberAccessor } else { - generator.Emit(OpCodes.Newobj, realMethod); + generator.Emit(OpCodes.Newobj, constructorInfo); if (type.IsValueType) { // Since C# 10 it's now possible to have parameterless constructors in structs diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs index 606ad6aba79c26..8627a24f3f4926 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs @@ -10,35 +10,26 @@ namespace System.Text.Json.Serialization.Metadata { internal sealed class ReflectionMemberAccessor : MemberAccessor { - private sealed class ConstructorContext - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - private readonly Type _type; - - public ConstructorContext([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) - => _type = type; - - public object? CreateInstance() - => Activator.CreateInstance(_type, nonPublic: false); - } - - public override Func? CreateConstructor( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) + public override Func? CreateParameterlessConstructor( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type, + ConstructorInfo? ctorInfo) { Debug.Assert(type != null); - ConstructorInfo? realMethod = type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, binder: null, Type.EmptyTypes, modifiers: null); + Debug.Assert(ctorInfo is null || ctorInfo.GetParameters().Length == 0); if (type.IsAbstract) { return null; } - if (realMethod == null && !type.IsValueType) + if (ctorInfo is null) { - return null; + return type.IsValueType + ? () => Activator.CreateInstance(type, nonPublic: false)! + : null; } - return new ConstructorContext(type).CreateInstance!; + return () => ctorInfo.Invoke(null); } public override Func CreateParameterizedConstructor(ConstructorInfo constructor) diff --git a/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.AttributePresence.cs b/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.AttributePresence.cs index 681d495b8c752c..f54692a5c59a44 100644 --- a/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.AttributePresence.cs +++ b/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.AttributePresence.cs @@ -39,6 +39,24 @@ public async Task NonPublicCtors_WithJsonConstructorAttribute_WorksAsExpected(Ty } } + [Theory] + [InlineData(typeof(PrivateParameterlessCtor_WithAttribute), false)] + [InlineData(typeof(InternalParameterlessCtor_WithAttribute), true)] + [InlineData(typeof(ProtectedParameterlessCtor_WithAttribute), false)] + public async Task NonPublicParameterlessCtors_WithJsonConstructorAttribute_WorksAsExpected(Type type, bool isAccessibleBySourceGen) + { + if (!Serializer.IsSourceGeneratedSerializer || isAccessibleBySourceGen) + { + object? result = await Serializer.DeserializeWrapper("{}", type); + Assert.IsType(type, result); + } + else + { + NotSupportedException ex = await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper("{}", type)); + Assert.Contains("JsonConstructorAttribute", ex.ToString()); + } + } + [Fact] public async Task SinglePublicParameterizedCtor_SingleParameterlessCtor_NoAttribute_Supported_UseParameterlessCtor() { diff --git a/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.Constructor.cs b/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.Constructor.cs index 285c5b78934733..f12cf89e41de59 100644 --- a/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.Constructor.cs +++ b/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.Constructor.cs @@ -74,6 +74,33 @@ public class ProtectedParameterizedCtor_WithAttribute protected ProtectedParameterizedCtor_WithAttribute(int x) => X = x; } + public class PrivateParameterlessCtor_WithAttribute + { + public int X { get; } + + [JsonConstructor] + private PrivateParameterlessCtor_WithAttribute() + => X = 42; + } + + public class ProtectedParameterlessCtor_WithAttribute + { + public int X { get; } + + [JsonConstructor] + protected ProtectedParameterlessCtor_WithAttribute() + => X = 42; + } + + public class InternalParameterlessCtor_WithAttribute + { + public int X { get; } + + [JsonConstructor] + internal InternalParameterlessCtor_WithAttribute() + => X = 42; + } + public class PrivateParameterlessCtor_InternalParameterizedCtor_WithMultipleAttributes { [JsonConstructor] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ConstructorTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ConstructorTests.cs index b2a5fd465da766..d1769f491104db 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ConstructorTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ConstructorTests.cs @@ -41,6 +41,9 @@ protected ConstructorTests_Metadata(JsonSerializerWrapper stringWrapper) [JsonSerializable(typeof(PrivateParameterizedCtor_WithAttribute))] [JsonSerializable(typeof(InternalParameterizedCtor_WithAttribute))] [JsonSerializable(typeof(ProtectedParameterizedCtor_WithAttribute))] + [JsonSerializable(typeof(PrivateParameterlessCtor_WithAttribute))] + [JsonSerializable(typeof(InternalParameterlessCtor_WithAttribute))] + [JsonSerializable(typeof(ProtectedParameterlessCtor_WithAttribute))] [JsonSerializable(typeof(SinglePublicParameterizedCtor))] [JsonSerializable(typeof(SingleParameterlessCtor_MultiplePublicParameterizedCtor))] [JsonSerializable(typeof(SingleParameterlessCtor_MultiplePublicParameterizedCtor_Struct))] @@ -186,6 +189,9 @@ public ConstructorTests_Default(JsonSerializerWrapper jsonSerializer) : base(jso [JsonSerializable(typeof(PrivateParameterizedCtor_WithAttribute))] [JsonSerializable(typeof(InternalParameterizedCtor_WithAttribute))] [JsonSerializable(typeof(ProtectedParameterizedCtor_WithAttribute))] + [JsonSerializable(typeof(PrivateParameterlessCtor_WithAttribute))] + [JsonSerializable(typeof(InternalParameterlessCtor_WithAttribute))] + [JsonSerializable(typeof(ProtectedParameterlessCtor_WithAttribute))] [JsonSerializable(typeof(SinglePublicParameterizedCtor))] [JsonSerializable(typeof(SingleParameterlessCtor_MultiplePublicParameterizedCtor))] [JsonSerializable(typeof(SingleParameterlessCtor_MultiplePublicParameterizedCtor_Struct))] From c79f02af08949a0b2d7b61e5fa40323eb31b64c8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 08:32:09 -0700 Subject: [PATCH 012/783] [release/8.0-rc1] Annotate System.Linq.Expressions with RequiresDynamicCode (#90616) * Annotate System.Linq.Expressions with RequiresDynamicCode All this ended up with an RUC on Expression.Compile due to new arrays. I could potentially silence this warning with a feature flag, but it is a real risk, and one that users could maybe work around if alterted to the problem. * Remove suppression that's no longer needed * Fix tests for new feature switch behavior * Update src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Expression.cs Co-authored-by: Eric Erhardt * Typo in Throws call * Fix assert for net framework * Respond to PR comments * Add suppression * Typo * Update src/libraries/System.Linq.Expressions/src/Resources/Strings.resx Co-authored-by: Stephen Toub * PR feedback --------- Co-authored-by: Andy Gocke Co-authored-by: Andy Gocke Co-authored-by: Eric Erhardt Co-authored-by: Stephen Toub --- .../TestUtilities/System/AssertExtensions.cs | 21 +++++++ .../Expressions/ExpressionResolverBuilder.cs | 11 +++- .../ref/System.Linq.Expressions.cs | 5 ++ .../src/CompatibilitySuppressions.xml | 42 +++++++++++++ .../src/Resources/Strings.resx | 3 + .../src/System.Linq.Expressions.csproj | 2 +- .../src/System/Dynamic/DynamicObject.cs | 9 ++- .../Dynamic/Utils/CachedReflectionInfo.cs | 32 ---------- .../System/Dynamic/Utils/DelegateHelpers.cs | 9 ++- .../src/System/Dynamic/Utils/TypeUtils.cs | 62 +++++++++++++++++++ .../Linq/Expressions/BinaryExpression.cs | 8 ++- .../Linq/Expressions/Compiler/AssemblyGen.cs | 1 + .../Compiler/CompilerScope.Storage.cs | 3 + .../Expressions/Compiler/CompilerScope.cs | 3 + .../Expressions/Compiler/DelegateHelpers.cs | 3 + .../Compiler/LambdaCompiler.Binary.cs | 3 +- .../Expressions/Compiler/LambdaCompiler.cs | 2 + .../Linq/Expressions/Compiler/StackSpiller.cs | 1 + .../Expressions/Compiler/VariableBinder.cs | 1 + .../src/System/Linq/Expressions/Expression.cs | 5 ++ .../Interpreter/ArrayOperations.cs | 5 ++ .../Interpreter/InstructionList.cs | 9 +-- .../Expressions/Interpreter/LightCompiler.cs | 4 ++ .../Linq/Expressions/LambdaExpression.cs | 11 ++++ .../Linq/Expressions/ListInitExpression.cs | 4 ++ .../Linq/Expressions/MethodCallExpression.cs | 4 ++ .../Linq/Expressions/NewArrayExpression.cs | 15 +++++ .../src/System/Linq/Expressions/Strings.cs | 8 +++ .../Linq/Expressions/UnaryExpression.cs | 4 +- .../Runtime/CompilerServices/CallSite.cs | 53 ++++++++++++---- .../CompilerServices/CallSiteBinder.cs | 4 +- .../Runtime/CompilerServices/CallSiteOps.cs | 3 + .../CallSiteOpsReflectionCache.cs | 37 +++++++++++ .../Arithmetic/BinaryMultiplyTests.cs | 38 +++++++----- .../tests/HelperTypes.cs | 2 + .../Lifted/LiftedAddCheckedNullableTests.cs | 13 ++-- .../tests/Lifted/LiftedAddNullableTests.cs | 13 ++-- .../Lifted/LiftedBitwiseAndNullableTests.cs | 13 ++-- .../LiftedBitwiseExclusiveOrNullableTests.cs | 13 ++-- .../Lifted/LiftedBitwiseOrNullableTests.cs | 13 ++-- .../tests/Lifted/LiftedDivideNullableTests.cs | 13 ++-- .../tests/Lifted/LiftedModuloNullableTests.cs | 13 ++-- .../LiftedMultiplyCheckedNullableTests.cs | 13 ++-- .../Lifted/LiftedMultiplyNullableTests.cs | 13 ++-- .../LiftedSubtractCheckedNullableTests.cs | 13 ++-- .../Lifted/LiftedSubtractNullableTests.cs | 13 ++-- .../tests/SequenceTests/SequenceTests.cs | 12 ++-- .../Unary/UnaryDecrementNullableTests.cs | 20 +++--- .../tests/Unary/UnaryDecrementTests.cs | 2 +- .../Unary/UnaryIncrementNullableTests.cs | 20 +++--- 50 files changed, 468 insertions(+), 156 deletions(-) create mode 100644 src/libraries/System.Linq.Expressions/src/System/Runtime/CompilerServices/CallSiteOpsReflectionCache.cs diff --git a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs index bf676b7b6f26be..230e4cb4276a42 100644 --- a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs +++ b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -15,6 +16,26 @@ public static class AssertExtensions { private static bool IsNetFramework => RuntimeInformation.FrameworkDescription.StartsWith(".NET Framework"); + + /// + /// Helper for AOT tests that verifies that the compile succeeds, or throws PlatformNotSupported + /// when AOT is enabled. + /// + public static void ThrowsOnAot(Action action) + where T : Exception + { +#if NETCOREAPP // Dynamic code is always supported on .NET Framework + if (!RuntimeFeature.IsDynamicCodeSupported) + { + Assert.Throws(action); + } + else +#endif + { + action(); + } + } + public static void Throws(Action action, string expectedMessage) where T : Exception { diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/Expressions/ExpressionResolverBuilder.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/Expressions/ExpressionResolverBuilder.cs index c28b9f00bb4e7d..670c62ee2f69a8 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/Expressions/ExpressionResolverBuilder.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/Expressions/ExpressionResolverBuilder.cs @@ -123,6 +123,15 @@ static MethodInfo GetArrayEmptyMethodInfo(Type elementType) return ServiceLookupHelpers.GetArrayEmptyMethodInfo(elementType); } + [UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode", + Justification = "VerifyAotCompatibility ensures elementType is not a ValueType")] + static NewArrayExpression NewArrayInit(Type elementType, IEnumerable expr) + { + Debug.Assert(!ServiceProvider.VerifyAotCompatibility || !elementType.IsValueType, "VerifyAotCompatibility=true will throw during building the IEnumerableCallSite if elementType is a ValueType."); + + return Expression.NewArrayInit(elementType, expr); + } + if (callSite.ServiceCallSites.Length == 0) { return Expression.Constant( @@ -130,7 +139,7 @@ static MethodInfo GetArrayEmptyMethodInfo(Type elementType) .Invoke(obj: null, parameters: Array.Empty())); } - return Expression.NewArrayInit( + return NewArrayInit( callSite.ItemType, callSite.ServiceCallSites.Select(cs => Convert( diff --git a/src/libraries/System.Linq.Expressions/ref/System.Linq.Expressions.cs b/src/libraries/System.Linq.Expressions/ref/System.Linq.Expressions.cs index 98bfd460ddb960..015cfb079d360a 100644 --- a/src/libraries/System.Linq.Expressions/ref/System.Linq.Expressions.cs +++ b/src/libraries/System.Linq.Expressions/ref/System.Linq.Expressions.cs @@ -607,9 +607,13 @@ protected Expression(System.Linq.Expressions.ExpressionType nodeType, System.Typ public static System.Linq.Expressions.NewExpression New(System.Reflection.ConstructorInfo constructor, System.Collections.Generic.IEnumerable? arguments, params System.Reflection.MemberInfo[]? members) { throw null; } public static System.Linq.Expressions.NewExpression New(System.Reflection.ConstructorInfo constructor, params System.Linq.Expressions.Expression[]? arguments) { throw null; } public static System.Linq.Expressions.NewExpression New([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type type) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Creating arrays at runtime requires dynamic code generation.")] public static System.Linq.Expressions.NewArrayExpression NewArrayBounds(System.Type type, System.Collections.Generic.IEnumerable bounds) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Creating arrays at runtime requires dynamic code generation.")] public static System.Linq.Expressions.NewArrayExpression NewArrayBounds(System.Type type, params System.Linq.Expressions.Expression[] bounds) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Creating arrays at runtime requires dynamic code generation.")] public static System.Linq.Expressions.NewArrayExpression NewArrayInit(System.Type type, System.Collections.Generic.IEnumerable initializers) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Creating arrays at runtime requires dynamic code generation.")] public static System.Linq.Expressions.NewArrayExpression NewArrayInit(System.Type type, params System.Linq.Expressions.Expression[] initializers) { throw null; } public static System.Linq.Expressions.UnaryExpression Not(System.Linq.Expressions.Expression expression) { throw null; } public static System.Linq.Expressions.UnaryExpression Not(System.Linq.Expressions.Expression expression, System.Reflection.MethodInfo? method) { throw null; } @@ -1028,6 +1032,7 @@ internal MethodCallExpression() { } System.Linq.Expressions.Expression System.Linq.Expressions.IArgumentProvider.GetArgument(int index) { throw null; } public System.Linq.Expressions.MethodCallExpression Update(System.Linq.Expressions.Expression? @object, System.Collections.Generic.IEnumerable? arguments) { throw null; } } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Creating arrays at runtime requires dynamic code generation.")] public partial class NewArrayExpression : System.Linq.Expressions.Expression { internal NewArrayExpression() { } diff --git a/src/libraries/System.Linq.Expressions/src/CompatibilitySuppressions.xml b/src/libraries/System.Linq.Expressions/src/CompatibilitySuppressions.xml index 8185aa8209fa11..bf51da8ccbe294 100644 --- a/src/libraries/System.Linq.Expressions/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Linq.Expressions/src/CompatibilitySuppressions.xml @@ -97,6 +97,48 @@ ref/net8.0/System.Linq.Expressions.dll lib/net8.0/System.Linq.Expressions.dll + + CP0016 + M:System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression,System.String,System.Type[],System.Linq.Expressions.Expression[]):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] + ref/net8.0/System.Linq.Expressions.dll + lib/net8.0/System.Linq.Expressions.dll + + + CP0016 + M:System.Linq.Expressions.Expression.Call(System.Type,System.String,System.Type[],System.Linq.Expressions.Expression[]):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] + ref/net8.0/System.Linq.Expressions.dll + lib/net8.0/System.Linq.Expressions.dll + + + CP0016 + M:System.Linq.Expressions.Expression.ListInit(System.Linq.Expressions.NewExpression,System.Collections.Generic.IEnumerable{System.Linq.Expressions.Expression}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] + ref/net8.0/System.Linq.Expressions.dll + lib/net8.0/System.Linq.Expressions.dll + + + CP0016 + M:System.Linq.Expressions.Expression.ListInit(System.Linq.Expressions.NewExpression,System.Linq.Expressions.Expression[]):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] + ref/net8.0/System.Linq.Expressions.dll + lib/net8.0/System.Linq.Expressions.dll + + + CP0016 + M:System.Linq.Expressions.Expression.ListInit(System.Linq.Expressions.NewExpression,System.Reflection.MethodInfo,System.Collections.Generic.IEnumerable{System.Linq.Expressions.Expression}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] + ref/net8.0/System.Linq.Expressions.dll + lib/net8.0/System.Linq.Expressions.dll + + + CP0016 + M:System.Linq.Expressions.Expression.ListInit(System.Linq.Expressions.NewExpression,System.Reflection.MethodInfo,System.Linq.Expressions.Expression[]):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] + ref/net8.0/System.Linq.Expressions.dll + lib/net8.0/System.Linq.Expressions.dll + + + CP0016 + M:System.Runtime.CompilerServices.CallSite`1.Create(System.Runtime.CompilerServices.CallSiteBinder):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] + ref/net8.0/System.Linq.Expressions.dll + lib/net8.0/System.Linq.Expressions.dll + CP0020 M:System.Linq.Expressions.DynamicExpressionVisitor.#ctor diff --git a/src/libraries/System.Linq.Expressions/src/Resources/Strings.resx b/src/libraries/System.Linq.Expressions/src/Resources/Strings.resx index 01f6ec7be8ddc5..cfbf09d82e02e9 100644 --- a/src/libraries/System.Linq.Expressions/src/Resources/Strings.resx +++ b/src/libraries/System.Linq.Expressions/src/Resources/Strings.resx @@ -564,4 +564,7 @@ The given key '{0}' was not present in the dictionary. + + Nullable lifting on non-primitive type '{0}' is only supported in expression trees when dynamic code generation is available. + diff --git a/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj b/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj index 47375e1d827797..08f93036a937da 100644 --- a/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj +++ b/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj @@ -3,7 +3,6 @@ $(NetCoreAppCurrent) $(DefineConstants);FEATURE_FAST_CREATE $(NoWarn);CA1859 - false @@ -60,4 +120,7 @@ The meter factory does not allow a custom scope value when creating a meter. - + + Only one wildcard character is allowed in category name. + + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Diagnostics/tests/ListenerSubscriptionTests.cs b/src/libraries/Microsoft.Extensions.Diagnostics/tests/ListenerSubscriptionTests.cs index da59cffc28d6a6..a0c5d281bfaa0f 100644 --- a/src/libraries/Microsoft.Extensions.Diagnostics/tests/ListenerSubscriptionTests.cs +++ b/src/libraries/Microsoft.Extensions.Diagnostics/tests/ListenerSubscriptionTests.cs @@ -214,13 +214,20 @@ public void RuleCanBeTurnedOffAndOnAgain() [InlineData("", "", "")] [InlineData("*", "", "")] [InlineData("lonG", "", "")] + [InlineData("lonG.", "", "")] [InlineData("lonG*", "", "")] [InlineData("lonG.*", "", "")] + [InlineData("lonG.sil", "", "")] + [InlineData("lonG.sil*", "", "")] [InlineData("lonG.sillY.meteR", "", "")] [InlineData("lonG.sillY.meteR*", "", "")] [InlineData("lonG.sillY.meteR.*", "", "")] + [InlineData("*namE", "", "")] + [InlineData("*.namE", "", "")] + [InlineData("*.sillY.meteR.Name", "", "")] + [InlineData("long*Name", "", "")] + [InlineData("lonG.sillY.meter*MeteR.namE", "", "")] // Shouldn't match, but does, left for compatibility with Logging. [InlineData("lonG.sillY.meteR.namE", "", "")] - [InlineData("lonG.sillY.meteR.namE.*", "", "")] [InlineData("", "instrumenTnamE", "")] [InlineData("lonG.sillY.meteR.namE", "instrumenTnamE", "")] [InlineData("", "", "listeneRnamE")] @@ -237,15 +244,13 @@ public void RuleMatchesTest(string meterName, string instrumentName, string list } [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] - [InlineData("*.*", "", "")] [InlineData("", "*", "")] [InlineData("", "", "*")] - [InlineData("lonG.", "", "")] - [InlineData("lonG.sil", "", "")] - [InlineData("lonG.sil*", "", "")] [InlineData("sillY.meteR.namE", "", "")] + [InlineData(".*", "", "")] + [InlineData("*.", "", "")] + [InlineData("lonG.sillY.meteR.namE.*", "", "")] [InlineData("namE", "", "")] - [InlineData("*.namE", "", "")] [InlineData("wrongMeter", "", "")] [InlineData("wrongMeter", "InstrumentName", "")] [InlineData("wrongMeter", "", "ListenerName")] @@ -261,6 +266,17 @@ public void RuleMatchesNegativeTest(string meterName, string instrumentName, str }, meterName, instrumentName, listenerName).Dispose(); } + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void MultipleWildcardsThrows() + { + RemoteExecutor.Invoke(() => { + var rule = new InstrumentRule("*.*", null, null, MeterScope.Global, enable: true); + var meter = new Meter("Long.Silly.Meter.Name"); + var instrument = meter.CreateCounter("InstrumentName"); + Assert.Throws< InvalidOperationException>(() => ListenerSubscription.RuleMatches(rule, instrument, "ListenerName", new FakeMeterFactory())); + }).Dispose(); + } + [Theory] [MemberData(nameof(IsMoreSpecificTestData))] public void IsMoreSpecificTest(InstrumentRule rule, InstrumentRule? best, bool isLocalScope) @@ -388,3 +404,8 @@ private class FakeMeterFactory : IMeterFactory } } } + +internal class SR +{ + public static string MoreThanOneWildcard => "More than one wildcard is not allowed in a rule."; +} From 543e733ea3d0a89372aa6b68bcd09a2b65df1864 Mon Sep 17 00:00:00 2001 From: Juan Sebastian Hoyos Ayala Date: Wed, 16 Aug 2023 18:06:27 +0000 Subject: [PATCH 014/783] Update Microsoft.DiaSymReader.Native to 16.11.29-beta1.23404.4 --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index ff21c1ee1f07dc..82d85ceaaaada5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -161,7 +161,7 @@ 1.0.0-prerelease.23362.5 1.0.0-prerelease.23362.5 - 16.11.27-beta1.23180.1 + 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 3.0.3 2.1.0 From 4d44f2ff0b2a459042cb2eb509c400db4d226e26 Mon Sep 17 00:00:00 2001 From: Alhad Deshpande <97085048+alhad-deshpande@users.noreply.github.com> Date: Wed, 16 Aug 2023 23:56:28 +0530 Subject: [PATCH 015/783] [ppc64le] performance improvements while branching (#90656) --- src/mono/mono/mini/mini-ppc.c | 42 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/mono/mono/mini/mini-ppc.c b/src/mono/mono/mini/mini-ppc.c index 3b9bdf2bcb985c..b3514123b7e941 100644 --- a/src/mono/mono/mini/mini-ppc.c +++ b/src/mono/mono/mini/mini-ppc.c @@ -297,7 +297,7 @@ gboolean mono_ppc_is_direct_call_sequence (guint32 *code) { #ifdef TARGET_POWERPC64 - g_assert(*code == 0x4e800021 || *code == 0x4e800020 || *code == 0x4e800420); + g_assert(*code == 0x4e800021 || *code == 0x4e800020 || *code == 0x4e800421 || *code == 0x4e800420); /* the thunk-less direct call sequence: lis/ori/sldi/oris/ori/mtlr/blrl */ if (ppc_opcode (code [-1]) == 31) { /* mtlr */ @@ -2939,7 +2939,7 @@ ppc_patch_full (MonoCompile *cfg, guchar *code, const guchar *target, gboolean i return; } - if (prim == 15 || ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800420) { + if (prim == 15 || ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800421 || ins == 0x4e800420) { #ifdef TARGET_POWERPC64 #if !defined(PPC_USES_FUNCTION_DESCRIPTOR) handle_thunk (cfg, code, target); @@ -2948,7 +2948,7 @@ ppc_patch_full (MonoCompile *cfg, guchar *code, const guchar *target, gboolean i guint32 *branch_ins; /* the trampoline code will try to patch the blrl, blr, bcctr */ - if (ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800420) { + if (ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800421 || ins == 0x4e800420) { branch_ins = seq; if (ppc_is_load_op (seq [-3]) || ppc_opcode (seq [-3]) == 31) /* ld || lwz || mr */ code -= 32; @@ -2996,7 +2996,7 @@ ppc_patch_full (MonoCompile *cfg, guchar *code, const guchar *target, gboolean i #else guint32 *seq; /* the trampoline code will try to patch the blrl, blr, bcctr */ - if (ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800420) { + if (ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800421 || ins == 0x4e800420) { code -= 12; } /* this is the lis/ori/mtlr/blrl sequence */ @@ -3004,7 +3004,7 @@ ppc_patch_full (MonoCompile *cfg, guchar *code, const guchar *target, gboolean i g_assert ((seq [0] >> 26) == 15); g_assert ((seq [1] >> 26) == 24); g_assert ((seq [2] >> 26) == 31); - g_assert (seq [3] == 0x4e800021 || seq [3] == 0x4e800020 || seq [3] == 0x4e800420); + g_assert (seq [3] == 0x4e800021 || seq [3] == 0x4e800020 || seq [3] == 0x4e800421 || seq [3] == 0x4e800420); /* FIXME: make this thread safe */ ppc_lis (code, PPC_CALL_REG, (guint32)(target) >> 16); ppc_ori (code, PPC_CALL_REG, PPC_CALL_REG, (guint32)(target) & 0xffff); @@ -3426,8 +3426,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); cfg->thunk_area += THUNK_SIZE; #endif - ppc_mtlr (code, PPC_CALL_REG); - ppc_blrl (code); + ppc_mtctr (code, PPC_CALL_REG); + ppc_bcctrl (code, PPC_BR_ALWAYS, 0); } else { ppc_bl (code, 0); } @@ -3913,8 +3913,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); cfg->thunk_area += THUNK_SIZE; #endif - ppc_mtlr (code, PPC_CALL_REG); - ppc_blrl (code); + ppc_mtctr (code, PPC_CALL_REG); + ppc_bcctrl (code, PPC_BR_ALWAYS, 0); } else { ppc_bl (code, 0); } @@ -3945,9 +3945,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) } } #endif - ppc_mtlr (code, ins->sreg1); + ppc_mtctr (code, ins->sreg1); #endif - ppc_blrl (code); + ppc_bcctrl (code, PPC_BR_ALWAYS, 0); /* FIXME: this should be handled somewhere else in the new jit */ code = emit_move_return_value (cfg, ins, code); break; @@ -3965,8 +3965,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) } else { ppc_ldptr (code, ppc_r12, ins->inst_offset, ins->sreg1); } - ppc_mtlr (code, ppc_r12); - ppc_blrl (code); + ppc_mtctr (code, ppc_r12); + ppc_bcctrl (code, PPC_BR_ALWAYS, 0); /* FIXME: this should be handled somewhere else in the new jit */ code = emit_move_return_value (cfg, ins, code); break; @@ -4022,8 +4022,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); cfg->thunk_area += THUNK_SIZE; #endif - ppc_mtlr (code, PPC_CALL_REG); - ppc_blrl (code); + ppc_mtctr (code, PPC_CALL_REG); + ppc_bcctrl (code, PPC_BR_ALWAYS, 0); } else { ppc_bl (code, 0); } @@ -4040,8 +4040,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); cfg->thunk_area += THUNK_SIZE; #endif - ppc_mtlr (code, PPC_CALL_REG); - ppc_blrl (code); + ppc_mtctr (code, PPC_CALL_REG); + ppc_bcctrl (code, PPC_BR_ALWAYS, 0); } else { ppc_bl (code, 0); } @@ -4725,8 +4725,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); cfg->thunk_area += THUNK_SIZE; #endif - ppc_mtlr (code, PPC_CALL_REG); - ppc_blrl (code); + ppc_mtctr (code, PPC_CALL_REG); + ppc_bcctrl (code, PPC_BR_ALWAYS, 0); } else { ppc_bl (code, 0); } @@ -5348,8 +5348,8 @@ mono_arch_emit_prolog (MonoCompile *cfg) ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); cfg->thunk_area += THUNK_SIZE; #endif - ppc_mtlr (code, PPC_CALL_REG); - ppc_blrl (code); + ppc_mtctr (code, PPC_CALL_REG); + ppc_bcctrl (code, PPC_BR_ALWAYS, 0); } else { ppc_bl (code, 0); } From 243a5aea6983e8a36abbabd14d4f95bf8123ce5b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 12:27:32 -0600 Subject: [PATCH 016/783] Fix problems with `Assembler::ReflectionNotation()` (#90655) Do more parameter validation, correct buffer size calculations for security-enhanced CRT functions, and avoid memcpy buffer overrun of locale. Co-authored-by: Bruce Forstall --- src/coreclr/ilasm/assem.cpp | 84 ++++++++++++++++++++++++++++++------- 1 file changed, 69 insertions(+), 15 deletions(-) diff --git a/src/coreclr/ilasm/assem.cpp b/src/coreclr/ilasm/assem.cpp index dd2c91ac093acb..2bd90fadb8f916 100644 --- a/src/coreclr/ilasm/assem.cpp +++ b/src/coreclr/ilasm/assem.cpp @@ -1324,7 +1324,12 @@ OPCODE Assembler::DecodeOpcode(const BYTE *pCode, DWORD *pdwLen) char* Assembler::ReflectionNotation(mdToken tk) { + // We break the global static `wzUniBuf` into 2 equal parts: the first part is used for a Unicode + // string, the second part is used for a converted-into-multibyte (MB) string. Note that the MB string + // length is in bytes. char *sz = (char*)&wzUniBuf[dwUniBuf>>1], *pc; + const size_t szSizeBytes = (dwUniBuf * sizeof(WCHAR)) / 2; // sizeof(WCHAR) is 2, so this is just `dwUniBuf` + const size_t cchUniBuf = dwUniBuf / 2; // only use the first 1/2 of wzUniBuf *sz=0; switch(TypeFromToken(tk)) { @@ -1333,7 +1338,7 @@ char* Assembler::ReflectionNotation(mdToken tk) Class *pClass = m_lstClass.PEEK(RidFromToken(tk)-1); if(pClass) { - strcpy_s(sz,dwUniBuf>>1,pClass->m_szFQN); + strcpy_s(sz,szSizeBytes,pClass->m_szFQN); pc = sz; while((pc = strchr(pc,NESTING_SEP)) != NULL) { @@ -1348,31 +1353,80 @@ char* Assembler::ReflectionNotation(mdToken tk) { ULONG N; mdToken tkResScope; - if(SUCCEEDED(m_pImporter->GetTypeRefProps(tk,&tkResScope,wzUniBuf,dwUniBuf>>1,&N))) + if(SUCCEEDED(m_pImporter->GetTypeRefProps(tk,&tkResScope,wzUniBuf,cchUniBuf,&N))) { - WszWideCharToMultiByte(CP_UTF8,0,wzUniBuf,-1,sz,dwUniBuf>>1,NULL,NULL); + int ret = WszWideCharToMultiByte(CP_UTF8,0,wzUniBuf,-1,sz,szSizeBytes,NULL,NULL); if(TypeFromToken(tkResScope)==mdtAssemblyRef) { AsmManAssembly *pAsmRef = m_pManifest->m_AsmRefLst.PEEK(RidFromToken(tkResScope)-1); if(pAsmRef) { - pc = &sz[strlen(sz)]; - pc+=sprintf_s(pc,(dwUniBuf >> 1),", %s, Version=%d.%d.%d.%d, Culture=",pAsmRef->szName, + // We assume below that if sprintf_s fails due to buffer overrun, + // execution fails fast and sprintf_s doesn't return. + int sprintf_ret; + const size_t szLen = strlen(sz); + pc = &sz[szLen]; + size_t szRemainingSizeBytes = szSizeBytes - szLen; + + sprintf_ret = sprintf_s(pc,szRemainingSizeBytes,", %s, Version=%d.%d.%d.%d, Culture=",pAsmRef->szName, pAsmRef->usVerMajor,pAsmRef->usVerMinor,pAsmRef->usBuild,pAsmRef->usRevision); - ULONG L=0; - if(pAsmRef->pLocale && (L=pAsmRef->pLocale->length())) + pc += sprintf_ret; + szRemainingSizeBytes -= (size_t)sprintf_ret; + + unsigned L=0; + if(pAsmRef->pLocale && ((L=pAsmRef->pLocale->length()) > 0)) + { + // L is in bytes and doesn't include the terminating null. + if (L > (cchUniBuf - 1) * sizeof(WCHAR)) + { + report->error("Locale too long (%d characters, %d allowed).\n",L / sizeof(WCHAR), cchUniBuf - 1); + *sz=0; + break; + } + else if (szRemainingSizeBytes == 0) + { + report->error("TypeRef too long.\n"); + *sz=0; + break; + } + + if (szRemainingSizeBytes > 0) + { + memcpy(wzUniBuf,pAsmRef->pLocale->ptr(),L); + wzUniBuf[L>>1] = 0; + ret = WszWideCharToMultiByte(CP_UTF8,0,wzUniBuf,-1,pc,(int)szRemainingSizeBytes,NULL,NULL); + if (ret <= 0) + { + report->error("Locale too long.\n"); + *sz=0; + break; + } + else + { + pc += ret; + szRemainingSizeBytes -= (size_t)ret; + } + } + } + else { - memcpy(wzUniBuf,pAsmRef->pLocale->ptr(),L); - wzUniBuf[L>>1] = 0; - WszWideCharToMultiByte(CP_UTF8,0,wzUniBuf,-1,pc,dwUniBuf>>1,NULL,NULL); + sprintf_ret = sprintf_s(pc,szRemainingSizeBytes,"neutral"); + pc += sprintf_ret; + szRemainingSizeBytes -= (size_t)sprintf_ret; } - else pc+=sprintf_s(pc,(dwUniBuf >> 1),"neutral"); - pc = &sz[strlen(sz)]; - if(pAsmRef->pPublicKeyToken && (L=pAsmRef->pPublicKeyToken->length())) + if(pAsmRef->pPublicKeyToken && ((L=pAsmRef->pPublicKeyToken->length()) > 0)) { - pc+=sprintf_s(pc,(dwUniBuf >> 1),", Publickeytoken="); + sprintf_ret = sprintf_s(pc,szRemainingSizeBytes,", Publickeytoken="); + pc += sprintf_ret; + szRemainingSizeBytes -= (size_t)sprintf_ret; + BYTE* pb = (BYTE*)(pAsmRef->pPublicKeyToken->ptr()); - for(N=0; N> 1),"%2.2x",*pb); + for(unsigned i=0; i Date: Wed, 16 Aug 2023 12:44:08 -0600 Subject: [PATCH 017/783] Fix NullableAttribute illink test failures (#90680) When we started building with preview 7 in 5549f72da3b3cea9e74bb81cfbb0f2d27731fc42, NullableAttribute in these testcases started to use the attribute definition from the framework, instead of generating it into the code. This broke the `--used-attrs-only` optimization because `skip` assemblies (the default for the framework in these testcases) are treated as if all types in them are kept, for the purposes of the `--used-attrs-only` optimization. (The optimization removes attribute instances unless the attribute type is preserved for some other reason). It's not clear what the intended behavior of `--used-attrs-only` is for `skip` assemblies, and the discussion in https://github.com/dotnet/linker/issues/952 indicates that it's considered experimental, so this fixes the failures by using the `link` action. This represents a more realistic scenario since `skip` is mainly used in testing to avoid linking the framework in every testcase. Co-authored-by: Sven Boemer --- .../Attributes/OnlyKeepUsed/NullableOnConstraints.cs | 1 + .../LinqExpressions/CanPreserveNullableCustomOperators.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/NullableOnConstraints.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/NullableOnConstraints.cs index b396bb3b10b568..b5efaa7dbcae0b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/NullableOnConstraints.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/NullableOnConstraints.cs @@ -7,6 +7,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed { [SetupCSharpCompilerToUse ("csc")] [SetupLinkerArgument ("--used-attrs-only", "true")] + [SetupLinkerTrimMode ("link")] public class NullableOnConstraints { public static void Main () diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinqExpressions/CanPreserveNullableCustomOperators.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinqExpressions/CanPreserveNullableCustomOperators.cs index 32398f667348c4..ec676fe1332211 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinqExpressions/CanPreserveNullableCustomOperators.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinqExpressions/CanPreserveNullableCustomOperators.cs @@ -5,6 +5,7 @@ namespace Mono.Linker.Tests.Cases.LinqExpressions { [SetupCompileArgument ("/unsafe")] [SetupLinkerArgument ("--used-attrs-only")] + [SetupLinkerTrimMode ("link")] public class CanPreserveNullableCustomOperators { public static void Main () From 7cc25f5d8df703d9ba4c0083de0bd43cf0f059f9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 21:42:28 +0200 Subject: [PATCH 018/783] [release/8.0-rc1] Add missing type forwards (#90673) * Add missing type forwards Fixes https://github.com/dotnet/runtime/issues/90578 IDispatchImplAttribute, IDispatchImplType and SetWin32ContextInIDispatchAttribute were removed with https://github.com/dotnet/runtime/commit/9f1dd1aa499a882453b34d4e8810626423fbfed8 and https://github.com/dotnet/runtime/commit/26a91ad6ac02393c6c7463500c030ec07803c5e6 Those dropped types weren't flagged because APICompat only validates reference assemblies. We have three implementation only shim assemblies: mscorlib, System and System.Data. I verified that no other type forwards were lost between .NET 7 and .NET 8. * Update mscorlib.cs --------- Co-authored-by: Viktor Hofer --- src/libraries/shims/mscorlib/src/mscorlib.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libraries/shims/mscorlib/src/mscorlib.cs b/src/libraries/shims/mscorlib/src/mscorlib.cs index 857e2a83bfc48e..eb77227a1130a0 100644 --- a/src/libraries/shims/mscorlib/src/mscorlib.cs +++ b/src/libraries/shims/mscorlib/src/mscorlib.cs @@ -109,3 +109,9 @@ [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<>))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.Sources.ValueTaskSourceOnCompletedFlags))] [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.Sources.ValueTaskSourceStatus))] +// These types are required for back-compatibility with .NET Framework and previous versions of .NETCoreApp. --> +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Reflection.Emit.PEFileKinds))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.InteropServices.AssemblyRegistrationFlags))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.InteropServices.ExporterEventKind))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.InteropServices.RegistrationClassContext))] +[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.InteropServices.RegistrationConnectionType))] From 9dc05ee36e47447b7dedb56d06328bfcf3db2d60 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 13:12:49 -0700 Subject: [PATCH 019/783] Fix gcroot SOS command on arm/arm64 (#90658) Faulted in DAC because the HelperMethodFrame's REGDISPLAY CurrentContextPointers were not initialized correctly. Fixes issue https://github.com/dotnet/diagnostics/issues/3726 Co-authored-by: Mike McLaughlin --- src/coreclr/vm/arm/stubs.cpp | 10 ++++++++++ src/coreclr/vm/arm64/stubs.cpp | 24 ++++++++++++------------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/coreclr/vm/arm/stubs.cpp b/src/coreclr/vm/arm/stubs.cpp index 634eea810a31df..36eaeb51cdc5de 100644 --- a/src/coreclr/vm/arm/stubs.cpp +++ b/src/coreclr/vm/arm/stubs.cpp @@ -671,6 +671,16 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD) pRD->pCurrentContext->R10 = (DWORD)(pUnwoundState->captureR4_R11[6]); pRD->pCurrentContext->R11 = (DWORD)(pUnwoundState->captureR4_R11[7]); + pRD->pCurrentContextPointers->R4 = &pRD->pCurrentContext->R4; + pRD->pCurrentContextPointers->R5 = &pRD->pCurrentContext->R5; + pRD->pCurrentContextPointers->R6 = &pRD->pCurrentContext->R6; + pRD->pCurrentContextPointers->R7 = &pRD->pCurrentContext->R7; + pRD->pCurrentContextPointers->R8 = &pRD->pCurrentContext->R8; + pRD->pCurrentContextPointers->R9 = &pRD->pCurrentContext->R9; + pRD->pCurrentContextPointers->R10 = &pRD->pCurrentContext->R10; + pRD->pCurrentContextPointers->R11 = &pRD->pCurrentContext->R11; + pRD->pCurrentContextPointers->Lr = &pRD->pCurrentContext->Lr; + return; } #endif // DACCESS_COMPILE diff --git a/src/coreclr/vm/arm64/stubs.cpp b/src/coreclr/vm/arm64/stubs.cpp index bc3e2b9609caeb..4ae26363fd2d24 100644 --- a/src/coreclr/vm/arm64/stubs.cpp +++ b/src/coreclr/vm/arm64/stubs.cpp @@ -472,18 +472,18 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD) pRD->pCurrentContext->Fp = (DWORD64)(pUnwoundState->captureX19_X29[10]); pRD->pCurrentContext->Lr = NULL; // Unwind again to get Caller's PC - pRD->pCurrentContextPointers->X19 = pUnwoundState->ptrX19_X29[0]; - pRD->pCurrentContextPointers->X20 = pUnwoundState->ptrX19_X29[1]; - pRD->pCurrentContextPointers->X21 = pUnwoundState->ptrX19_X29[2]; - pRD->pCurrentContextPointers->X22 = pUnwoundState->ptrX19_X29[3]; - pRD->pCurrentContextPointers->X23 = pUnwoundState->ptrX19_X29[4]; - pRD->pCurrentContextPointers->X24 = pUnwoundState->ptrX19_X29[5]; - pRD->pCurrentContextPointers->X25 = pUnwoundState->ptrX19_X29[6]; - pRD->pCurrentContextPointers->X26 = pUnwoundState->ptrX19_X29[7]; - pRD->pCurrentContextPointers->X27 = pUnwoundState->ptrX19_X29[8]; - pRD->pCurrentContextPointers->X28 = pUnwoundState->ptrX19_X29[9]; - pRD->pCurrentContextPointers->Fp = pUnwoundState->ptrX19_X29[10]; - pRD->pCurrentContextPointers->Lr = NULL; + pRD->pCurrentContextPointers->X19 = &pRD->pCurrentContext->X19; + pRD->pCurrentContextPointers->X20 = &pRD->pCurrentContext->X20; + pRD->pCurrentContextPointers->X21 = &pRD->pCurrentContext->X21; + pRD->pCurrentContextPointers->X22 = &pRD->pCurrentContext->X22; + pRD->pCurrentContextPointers->X23 = &pRD->pCurrentContext->X23; + pRD->pCurrentContextPointers->X24 = &pRD->pCurrentContext->X24; + pRD->pCurrentContextPointers->X25 = &pRD->pCurrentContext->X25; + pRD->pCurrentContextPointers->X26 = &pRD->pCurrentContext->X26; + pRD->pCurrentContextPointers->X27 = &pRD->pCurrentContext->X27; + pRD->pCurrentContextPointers->X28 = &pRD->pCurrentContext->X28; + pRD->pCurrentContextPointers->Fp = &pRD->pCurrentContext->Fp; + pRD->pCurrentContextPointers->Lr = &pRD->pCurrentContext->Lr; return; } From c96e5abe28678cc9ebd08d071de534ec7ed8b283 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 13:14:48 -0700 Subject: [PATCH 020/783] [release/8.0-rc1] [mono] Fix InlineArray tests on android platforms (#90679) * Enable inline array tests * Run android jobs only * Add verbose logging * Revert runtime changes * Remove android-arm64 job * Rename common assembly and revert CI changes * Rename assembly name --------- Co-authored-by: Milos Kotlar --- .../Loader/classloader/InlineArray/InlineArrayInvalid.csproj | 2 +- .../Loader/classloader/InlineArray/InlineArrayValid.csproj | 2 +- .../{InvalidCSharp.il => InvalidCSharpInlineArray.il} | 2 +- .../{InvalidCSharp.ilproj => InvalidCSharpInlineArray.ilproj} | 2 +- src/tests/issues.targets | 3 --- 5 files changed, 4 insertions(+), 7 deletions(-) rename src/tests/Loader/classloader/InlineArray/{InvalidCSharp.il => InvalidCSharpInlineArray.il} (98%) rename src/tests/Loader/classloader/InlineArray/{InvalidCSharp.ilproj => InvalidCSharpInlineArray.ilproj} (73%) diff --git a/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.csproj b/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.csproj index c9c4d3b28342f2..2b17f8cac36a5b 100644 --- a/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.csproj +++ b/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/tests/Loader/classloader/InlineArray/InlineArrayValid.csproj b/src/tests/Loader/classloader/InlineArray/InlineArrayValid.csproj index 125a6c3f5432e3..2ed1ccb70a0bbc 100644 --- a/src/tests/Loader/classloader/InlineArray/InlineArrayValid.csproj +++ b/src/tests/Loader/classloader/InlineArray/InlineArrayValid.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/tests/Loader/classloader/InlineArray/InvalidCSharp.il b/src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.il similarity index 98% rename from src/tests/Loader/classloader/InlineArray/InvalidCSharp.il rename to src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.il index ff8d65c09be001..af16b27db42d62 100644 --- a/src/tests/Loader/classloader/InlineArray/InvalidCSharp.il +++ b/src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.il @@ -3,7 +3,7 @@ .assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } -.assembly InvalidCSharp { } +.assembly InvalidCSharpInlineArray { } .class public explicit ansi sealed beforefieldinit Explicit extends [System.Runtime]System.ValueType diff --git a/src/tests/Loader/classloader/InlineArray/InvalidCSharp.ilproj b/src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.ilproj similarity index 73% rename from src/tests/Loader/classloader/InlineArray/InvalidCSharp.ilproj rename to src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.ilproj index d577c8f9c7a1a1..2a82d64591e9d5 100644 --- a/src/tests/Loader/classloader/InlineArray/InvalidCSharp.ilproj +++ b/src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.ilproj @@ -3,6 +3,6 @@ Library - + diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 09e50e73c7dd39..87f8bbf2673dd3 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -3482,9 +3482,6 @@ https://github.com/dotnet/runtime/issues/67359 - - https://github.com/dotnet/runtime/issues/90398 - From 322c85c11a4b8b1fd8ebdc3def52b8172262bb72 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Wed, 16 Aug 2023 13:20:51 -0700 Subject: [PATCH 021/783] [release/8.0-rc1] Bump package version for net7 to 7.0.11 (#90651) Co-authored-by: Steve Pfister Co-authored-by: Larry Ewing --- eng/Versions.props | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index ff21c1ee1f07dc..d75c6567090d01 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,12 +7,14 @@ 0 0 8.0.100 - 7.0.8 + 7.0.11 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) rc 1 -$(PreReleaseVersionLabel).$(PreReleaseVersionIteration) $(SdkBandVersion)$(WorkloadVersionSuffix) + + false $(MajorVersion).$(MinorVersion).0.0 From a37d1382047f6b6e79f4e1a6476fd48589d432a9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 13:22:34 -0700 Subject: [PATCH 022/783] [mono] Add a --path command line argument as an alternative to MONO_PATH. (#90678) Can be specified multiple times. Co-authored-by: Zoltan Varga --- src/mono/mono/mini/driver.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mono/mono/mini/driver.c b/src/mono/mono/mini/driver.c index c5f04a816a1fa8..a49820113d18ad 100644 --- a/src/mono/mono/mini/driver.c +++ b/src/mono/mono/mini/driver.c @@ -1617,6 +1617,7 @@ mini_usage (void) #endif " --handlers Install custom handlers, use --help-handlers for details.\n" " --aot-path=PATH List of additional directories to search for AOT images.\n" + " --path=DIR Add DIR to the list of directories to search for assemblies.\n" ); g_print ("\nOptions:\n"); @@ -2069,6 +2070,7 @@ mono_main (int argc, char* argv[]) char *aot_options = NULL; GPtrArray *agents = NULL; char *extra_bindings_config_file = NULL; + GList *paths = NULL; #ifdef MONO_JIT_INFO_TABLE_TEST int test_jit_info_table = FALSE; #endif @@ -2294,6 +2296,8 @@ mono_main (int argc, char* argv[]) g_free (tmp); split++; } + } else if (strncmp (argv [i], "--path=", 7) == 0) { + paths = g_list_append (paths, argv [i] + 7); } else if (strncmp (argv [i], "--compile-all=", 14) == 0) { action = DO_COMPILE; recompilation_times = atoi (argv [i] + 14); @@ -2503,6 +2507,16 @@ mono_main (int argc, char* argv[]) if (g_hasenv ("MONO_XDEBUG")) enable_debugging = TRUE; + if (paths) { + char **p = g_new0 (char *, g_list_length (paths) + 1); + int pindex = 0; + for (GList *l = paths; l; l = l->next) + p [pindex ++] = (char*)l->data; + g_list_free (paths); + + mono_set_assemblies_path_direct (p); + } + #ifdef MONO_CROSS_COMPILE if (!mono_compile_aot) { fprintf (stderr, "This mono runtime is compiled for cross-compiling. Only the --aot option is supported.\n"); From 1a13ecb5965ad8eed7aa145a4856813441314e52 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 13:24:39 -0700 Subject: [PATCH 023/783] [release/8.0] Add doc for the new invoker classes (#90636) * Add doc new invoker classes * Fix cref typo * Misc errors * Remove arg reference in 0-arg ctor summary --------- Co-authored-by: Steve Harter --- .../System/Reflection/ConstructorInvoker.cs | 62 +++++++++++++++ .../src/System/Reflection/MethodInvoker.cs | 75 +++++++++++++++++++ 2 files changed, 137 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs index 67fc0d31919759..7f3c1a227e3718 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs @@ -11,6 +11,17 @@ namespace System.Reflection { + /// + /// Invokes the method reflected by the provided . + /// + /// + /// Used for better performance than when compatibility with that method + /// is not necessary and when the caller can cache the ConstructorInvoker instance for additional invoke calls.
+ /// Unlike , the invoke methods do not look up default values for arguments when + /// is specified. In addition, the target constructor may be inlined for performance and not + /// appear in stack traces. + ///
+ /// public sealed partial class ConstructorInvoker { private InvokeFunc_ObjSpanArgs? _invokeFunc_ObjSpanArgs; @@ -24,6 +35,17 @@ public sealed partial class ConstructorInvoker private readonly RuntimeConstructorInfo _method; private readonly bool _needsByRefStrategy; + /// + /// Creates a new instance of ConstructorInvoker. + /// + /// + /// For performance, the resulting instance should be cached for additional calls. + /// + /// The constructor that will be invoked. + /// An instance of a ConstructorInvoker. + /// + /// The is not a runtime-based method. + /// public static ConstructorInvoker Create(ConstructorInfo constructor) { ArgumentNullException.ThrowIfNull(constructor, nameof(constructor)); @@ -46,6 +68,21 @@ private ConstructorInvoker(RuntimeConstructorInfo constructor, RuntimeType[] arg Initialize(argumentTypes, out _strategy, out _invokerArgFlags, out _needsByRefStrategy); } + /// + /// Invokes the constructor. + /// + /// + /// An instance of the class associated with the constructor. + /// + /// + /// The type that declares the method is an open generic type. + /// + /// + /// The correct number of arguments were not provided. + /// + /// + /// The calling convention or signature is not supported. + /// public object Invoke() { if (_argCount != 0) @@ -56,6 +93,14 @@ public object Invoke() return InvokeImpl(null, null, null, null); } + /// + /// Invokes the constructor using the specified parameters. + /// + /// + /// The first argument for the invoked method. + /// + /// The arguments do not match the signature of the invoked constructor. + /// public object Invoke(object? arg1) { if (_argCount != 1) @@ -66,6 +111,9 @@ public object Invoke(object? arg1) return InvokeImpl(arg1, null, null, null); } + /// + /// The first argument for the invoked method. + /// The second argument for the invoked method. public object Invoke(object? arg1, object? arg2) { if (_argCount != 2) @@ -76,6 +124,10 @@ public object Invoke(object? arg1, object? arg2) return InvokeImpl(arg1, arg2, null, null); } + /// + /// The first argument for the invoked method. + /// The second argument for the invoked method. + /// The third argument for the invoked method. public object Invoke(object? arg1, object? arg2, object? arg3) { if (_argCount !=3) @@ -86,6 +138,11 @@ public object Invoke(object? arg1, object? arg2, object? arg3) return InvokeImpl(arg1, arg2, arg3, null); } + /// + /// The first argument for the invoked method. + /// The second argument for the invoked method. + /// The third argument for the invoked method. + /// The fourth argument for the invoked method. public object Invoke(object? arg1, object? arg2, object? arg3, object? arg4) { if (_argCount != 4) @@ -137,6 +194,11 @@ private object InvokeImpl(object? arg1, object? arg2, object? arg3, object? arg4 return InvokeDirectByRef(arg1, arg2, arg3, arg4); } + /// + /// The arguments for the invoked constructor. + /// + /// The arguments do not match the signature of the invoked constructor. + /// public object Invoke(Span arguments) { int argLen = arguments.Length; diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs index b5496c37c0cc84..66a35dbd39c74b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs @@ -12,6 +12,17 @@ namespace System.Reflection { + /// + /// Invokes the method reflected by the provided . + /// + /// + /// Used for better performance than when compatibility with that method + /// is not necessary and when the caller can cache the MethodInvoker instance for additional invoke calls.
+ /// Unlike , the invoke methods do not look up default values for arguments when + /// is specified. In addition, the target method may be inlined for performance and not + /// appear in stack traces. + ///
+ /// public sealed partial class MethodInvoker { private InvokeFunc_ObjSpanArgs? _invokeFunc_ObjSpanArgs; @@ -26,6 +37,17 @@ public sealed partial class MethodInvoker private readonly bool _needsByRefStrategy; private readonly bool _isStatic; + /// + /// Creates a new instance of MethodInvoker. + /// + /// + /// For performance, the resulting instance should be cached for additional calls. + /// + /// The method that will be invoked. + /// An instance of a MethodInvoker. + /// + /// The is not a runtime-based method. + /// public static MethodInvoker Create(MethodBase method) { ArgumentNullException.ThrowIfNull(method, nameof(method)); @@ -60,6 +82,32 @@ private MethodInvoker(MethodBase method, RuntimeType[] argumentTypes) Initialize(argumentTypes, out _strategy, out _invokerArgFlags, out _needsByRefStrategy); } + /// + /// Invokes the method using the specified parameters. + /// + /// + /// The object on which to invoke the method. If the method is static, this argument is ignored. + /// + /// + /// An object containing the return value of the invoked method, + /// or null if the invoked method does not have a return value. + /// + /// + /// The obj parameter is null and the method is not static. + /// + /// -or- + /// + /// The method is not declared or inherited by the class of obj. + /// + /// + /// The type that declares the method is an open generic type. + /// + /// + /// The correct number of arguments were not provided. + /// + /// + /// The calling convention or signature is not supported. + /// public object? Invoke(object? obj) { if (_argCount != 0) @@ -70,6 +118,12 @@ private MethodInvoker(MethodBase method, RuntimeType[] argumentTypes) return InvokeImpl(obj, null, null, null, null); } + /// + /// The object on which to invoke the method. If the method is static, this argument is ignored. + /// The first argument for the invoked method. + /// + /// The arguments do not match the signature of the invoked method. + /// public object? Invoke(object? obj, object? arg1) { if (_argCount != 1) @@ -80,6 +134,10 @@ private MethodInvoker(MethodBase method, RuntimeType[] argumentTypes) return InvokeImpl(obj, arg1, null, null, null); } + /// + /// The object on which to invoke the method. If the method is static, this argument is ignored. + /// The first argument for the invoked method. + /// The second argument for the invoked method. public object? Invoke(object? obj, object? arg1, object? arg2) { if (_argCount != 2) @@ -90,6 +148,11 @@ private MethodInvoker(MethodBase method, RuntimeType[] argumentTypes) return InvokeImpl(obj, arg1, arg2, null, null); } + /// + /// The object on which to invoke the method. If the method is static, this argument is ignored. + /// The first argument for the invoked method. + /// The second argument for the invoked method. + /// The third argument for the invoked method. public object? Invoke(object? obj, object? arg1, object? arg2, object? arg3) { if (_argCount != 3) @@ -100,6 +163,12 @@ private MethodInvoker(MethodBase method, RuntimeType[] argumentTypes) return InvokeImpl(obj, arg1, arg2, arg3, null); } + /// + /// The object on which to invoke the method. If the method is static, this argument is ignored. + /// The first argument for the invoked method. + /// The second argument for the invoked method. + /// The third argument for the invoked method. + /// The fourth argument for the invoked method. public object? Invoke(object? obj, object? arg1, object? arg2, object? arg3, object? arg4) { if (_argCount != 4) @@ -156,6 +225,12 @@ private MethodInvoker(MethodBase method, RuntimeType[] argumentTypes) return InvokeDirectByRef(obj, arg1, arg2, arg3, arg4); } + /// + /// The object on which to invoke the method. If the method is static, this argument is ignored. + /// The arguments for the invoked method. + /// + /// The arguments do not match the signature of the invoked method. + /// public object? Invoke(object? obj, Span arguments) { int argLen = arguments.Length; From 68213d01c2d49361c1a3aaba7cc935dd906b9fd5 Mon Sep 17 00:00:00 2001 From: Matt Mitchell Date: Wed, 16 Aug 2023 15:38:38 -0700 Subject: [PATCH 024/783] Do not set fetch depth on source-build (#90703) --- eng/pipelines/common/global-build-job.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index 7e24fd3d045d5a..b870ba34757c21 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -147,7 +147,10 @@ jobs: steps: - checkout: self clean: true - fetchDepth: $(checkoutFetchDepth) + # If running in source build mode, a git stash will be used for the inner clone. Avoid setting a fetch depth, + # as a stash of a shallow cloned repo is not currently supported. + ${{ if ne(parameters.isSourceBuild, true) }}: + fetchDepth: $(checkoutFetchDepth) - ${{ if and(eq(parameters.isOfficialBuild, true), notin(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator')) }}: - template: /eng/pipelines/common/restore-internal-tools.yml From f84caca6fce726501f6722dab5f78db8bc0d88fd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:39:04 -0700 Subject: [PATCH 025/783] Do not set fetch depth on source-build (#90704) Co-authored-by: Matt Mitchell --- eng/pipelines/common/global-build-job.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index 7e24fd3d045d5a..b870ba34757c21 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -147,7 +147,10 @@ jobs: steps: - checkout: self clean: true - fetchDepth: $(checkoutFetchDepth) + # If running in source build mode, a git stash will be used for the inner clone. Avoid setting a fetch depth, + # as a stash of a shallow cloned repo is not currently supported. + ${{ if ne(parameters.isSourceBuild, true) }}: + fetchDepth: $(checkoutFetchDepth) - ${{ if and(eq(parameters.isOfficialBuild, true), notin(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator')) }}: - template: /eng/pipelines/common/restore-internal-tools.yml From b5a0345e44924bcbba2a29234d77c8f5b96c87ec Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 16:36:32 -0700 Subject: [PATCH 026/783] Update dependencies from https://github.com/dotnet/arcade build 20230815.4 (#90665) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23411.1 -> To Version 8.0.0-beta.23415.4 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23408.1 -> To Version 1.0.0-beta.23415.1 (parent: Microsoft.DotNet.Arcade.Sdk Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- eng/Version.Details.xml | 76 +++++++++++++------------- eng/Versions.props | 30 +++++----- eng/common/SetupNugetSources.ps1 | 8 +-- eng/common/SetupNugetSources.sh | 6 +- eng/common/native/init-distro-rid.sh | 6 +- eng/common/sdl/trim-assets-version.ps1 | 75 +++++++++++++++++++++++++ eng/common/tools.ps1 | 6 +- global.json | 6 +- 8 files changed, 145 insertions(+), 68 deletions(-) create mode 100644 eng/common/sdl/trim-assets-version.ps1 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e31341152d13b0..6d255bdbc9f2af 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -107,79 +107,79 @@ - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/xliff-tasks - 493329204079519072f0241ed26f692bdee0d60c + 649a1e75101b701d753ee41efbe9038f9b23a0db - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d https://github.com/dotnet/runtime-assets @@ -330,9 +330,9 @@ https://github.com/dotnet/xharness 480b9159eb7e69b182a87581d5a336e97e0b6dae - + https://github.com/dotnet/arcade - 9b2af35a6702526dc8a7c5fcadcc44efd0dca170 + 46ff142f43e887d5f9a4d87ef39d72166f61db8d https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index d75c6567090d01..fd3e699e214032 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -85,21 +85,21 @@ 8.0.100-preview.7.23329.3 - 8.0.0-beta.23411.1 - 8.0.0-beta.23411.1 - 8.0.0-beta.23411.1 - 8.0.0-beta.23411.1 - 8.0.0-beta.23411.1 - 2.5.1-beta.23411.1 - 8.0.0-beta.23411.1 - 8.0.0-beta.23411.1 - 8.0.0-beta.23411.1 - 8.0.0-beta.23411.1 - 8.0.0-beta.23411.1 - 8.0.0-beta.23411.1 - 8.0.0-beta.23411.1 - 8.0.0-beta.23411.1 - 8.0.0-beta.23411.1 + 8.0.0-beta.23415.4 + 8.0.0-beta.23415.4 + 8.0.0-beta.23415.4 + 8.0.0-beta.23415.4 + 8.0.0-beta.23415.4 + 2.5.1-beta.23415.4 + 8.0.0-beta.23415.4 + 8.0.0-beta.23415.4 + 8.0.0-beta.23415.4 + 8.0.0-beta.23415.4 + 8.0.0-beta.23415.4 + 8.0.0-beta.23415.4 + 8.0.0-beta.23415.4 + 8.0.0-beta.23415.4 + 8.0.0-beta.23415.4 6.0.0-preview.1.102 diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1 index 2dc86ea2cdda1a..6c65e81925f2a3 100644 --- a/eng/common/SetupNugetSources.ps1 +++ b/eng/common/SetupNugetSources.ps1 @@ -2,7 +2,7 @@ # This file should be removed as part of this issue: https://github.com/dotnet/arcade/issues/4080 # # What the script does is iterate over all package sources in the pointed NuGet.config and add a credential entry -# under for each Maestro managed private feed. Two additional credential +# under for each Maestro managed private feed. Two additional credential # entries are also added for the two private static internal feeds: dotnet3-internal and dotnet3-internal-transport. # # This script needs to be called in every job that will restore packages and which the base repo has @@ -37,7 +37,7 @@ Set-StrictMode -Version 2.0 # Add source entry to PackageSources function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Username, $Password) { $packageSource = $sources.SelectSingleNode("add[@key='$SourceName']") - + if ($packageSource -eq $null) { $packageSource = $doc.CreateElement("add") @@ -48,7 +48,7 @@ function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Usern else { Write-Host "Package source $SourceName already present." } - + AddCredential -Creds $creds -Source $SourceName -Username $Username -Password $Password } @@ -89,7 +89,7 @@ function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $Passw $maestroPrivateSources = $Sources.SelectNodes("add[contains(@key,'darc-int')]") Write-Host "Inserting credentials for $($maestroPrivateSources.Count) Maestro's private feeds." - + ForEach ($PackageSource in $maestroPrivateSources) { Write-Host "`tInserting credential for Maestro's feed:" $PackageSource.Key AddCredential -Creds $creds -Source $PackageSource.Key -Username $Username -Password $Password diff --git a/eng/common/SetupNugetSources.sh b/eng/common/SetupNugetSources.sh index a8bb8acd3be180..d387c7eac95e54 100644 --- a/eng/common/SetupNugetSources.sh +++ b/eng/common/SetupNugetSources.sh @@ -4,7 +4,7 @@ # This file should be removed as part of this issue: https://github.com/dotnet/arcade/issues/4080 # # What the script does is iterate over all package sources in the pointed NuGet.config and add a credential entry -# under for each Maestro's managed private feed. Two additional credential +# under for each Maestro's managed private feed. Two additional credential # entries are also added for the two private static internal feeds: dotnet3-internal and dotnet3-internal-transport. # # This script needs to be called in every job that will restore packages and which the base repo has @@ -68,7 +68,7 @@ if [ "$?" != "0" ]; then sed -i.bak "s|$ConfigNodeHeader|$ConfigNodeHeader${NL}$PackageSourcesTemplate|" $ConfigFile fi -# Ensure there is a ... section. +# Ensure there is a ... section. grep -i "" $ConfigFile if [ "$?" != "0" ]; then echo "Adding ... section." @@ -142,7 +142,7 @@ IFS=$PrevIFS for FeedName in ${PackageSources[@]} ; do # Check if there is no existing credential for this FeedName - grep -i "<$FeedName>" $ConfigFile + grep -i "<$FeedName>" $ConfigFile if [ "$?" != "0" ]; then echo "Adding credentials for $FeedName." diff --git a/eng/common/native/init-distro-rid.sh b/eng/common/native/init-distro-rid.sh index aba9fe24028b0f..de1687b2ccbe79 100644 --- a/eng/common/native/init-distro-rid.sh +++ b/eng/common/native/init-distro-rid.sh @@ -79,7 +79,6 @@ getNonPortableDistroRid() # Input: # os: (str) # arch: (str) -# isPortable: (int) # rootfsDir?: (nullable:string) # # Return: @@ -97,10 +96,9 @@ initDistroRidGlobal() { local targetOs="$1" local targetArch="$2" - local isPortable="$3" local rootfsDir="" - if [ "$#" -ge 4 ]; then - rootfsDir="$4" + if [ "$#" -ge 3 ]; then + rootfsDir="$3" fi if [ -n "${rootfsDir}" ]; then diff --git a/eng/common/sdl/trim-assets-version.ps1 b/eng/common/sdl/trim-assets-version.ps1 new file mode 100644 index 00000000000000..d8cfec910c77e6 --- /dev/null +++ b/eng/common/sdl/trim-assets-version.ps1 @@ -0,0 +1,75 @@ +<# +.SYNOPSIS +Install and run the 'Microsoft.DotNet.VersionTools.Cli' tool with the 'trim-artifacts-version' command to trim the version from the NuGet assets file name. + +.PARAMETER InputPath +Full path to directory where artifact packages are stored + +.PARAMETER Recursive +Search for NuGet packages recursively + +#> + +Param( + [string] $InputPath, + [bool] $Recursive = $true +) + +$CliToolName = "Microsoft.DotNet.VersionTools.Cli" + +function Install-VersionTools-Cli { + param( + [Parameter(Mandatory=$true)][string]$Version + ) + + Write-Host "Installing the package '$CliToolName' with a version of '$version' ..." + $feed = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" + + $argumentList = @("tool", "install", "--local", "$CliToolName", "--add-source $feed", "--no-cache", "--version $Version") + Start-Process "$dotnet" -Verbose -ArgumentList $argumentList -NoNewWindow -Wait +} + +# ------------------------------------------------------------------- + +if (!(Test-Path $InputPath)) { + Write-Host "Input Path '$InputPath' does not exist" + ExitWithExitCode 1 +} + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version 2.0 + +$disableConfigureToolsetImport = $true +$global:LASTEXITCODE = 0 + +# `tools.ps1` checks $ci to perform some actions. Since the SDL +# scripts don't necessarily execute in the same agent that run the +# build.ps1/sh script this variable isn't automatically set. +$ci = $true +. $PSScriptRoot\..\tools.ps1 + +try { + $dotnetRoot = InitializeDotNetCli -install:$true + $dotnet = "$dotnetRoot\dotnet.exe" + + $toolsetVersion = Read-ArcadeSdkVersion + Install-VersionTools-Cli -Version $toolsetVersion + + $cliToolFound = (& "$dotnet" tool list --local | Where-Object {$_.Split(' ')[0] -eq $CliToolName}) + if ($null -eq $cliToolFound) { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "The '$CliToolName' tool is not installed." + ExitWithExitCode 1 + } + + Exec-BlockVerbosely { + & "$dotnet" $CliToolName trim-assets-version ` + --assets-path $InputPath ` + --recursive $Recursive + Exit-IfNZEC "Sdl" + } +} +catch { + Write-Host $_ + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_ + ExitWithExitCode 1 +} \ No newline at end of file diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index c9eced9f7df4c6..aa74ab4a81e782 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -671,6 +671,10 @@ function InitializeNativeTools() { } } +function Read-ArcadeSdkVersion() { + return $GlobalJson.'msbuild-sdks'.'Microsoft.DotNet.Arcade.Sdk' +} + function InitializeToolset() { if (Test-Path variable:global:_ToolsetBuildProj) { return $global:_ToolsetBuildProj @@ -678,7 +682,7 @@ function InitializeToolset() { $nugetCache = GetNuGetPackageCachePath - $toolsetVersion = $GlobalJson.'msbuild-sdks'.'Microsoft.DotNet.Arcade.Sdk' + $toolsetVersion = Read-ArcadeSdkVersion $toolsetLocationFile = Join-Path $ToolsetDir "$toolsetVersion.txt" if (Test-Path $toolsetLocationFile) { diff --git a/global.json b/global.json index b4ca83d356c283..cf4ac698e3e8cb 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.100-preview.7.23376.3" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23411.1", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23411.1", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23411.1", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23415.4", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23415.4", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23415.4", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From a9b1d3c86611b0e49bedec766ebe1110e1ac1b9f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 09:25:09 -0600 Subject: [PATCH 027/783] Fix PortableRuntimeIdentifierGraph.json not found during runtime repo source build (#90714) Co-authored-by: Elinor Fung --- eng/liveBuilds.targets | 6 ------ 1 file changed, 6 deletions(-) diff --git a/eng/liveBuilds.targets b/eng/liveBuilds.targets index 118601229cf8b7..370e19805cc3a0 100644 --- a/eng/liveBuilds.targets +++ b/eng/liveBuilds.targets @@ -260,10 +260,4 @@ DependsOnTargets=" ResolveLibrariesRefAssembliesFromLocalBuild; ResolveLibrariesRuntimeFilesFromLocalBuild" /> - - - - $([MSBuild]::NormalizePath('$(ArtifactsBinDir)', 'Microsoft.NETCore.Platforms', 'runtime.json')) - $([MSBuild]::NormalizePath('$(LibrariesProjectRoot)', 'Microsoft.NETCore.Platforms', 'src', 'runtime.json')) - From 3924341ea7216d9b313d5d8e0590fbd3dca4be00 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 09:44:10 -0700 Subject: [PATCH 028/783] Release the stream once the response is sent (#90722) Co-authored-by: ManickaP --- .../Net/Http/Http3LoopbackConnection.cs | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs index ec5c7a022c65a6..9d6fef5fb3a720 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs @@ -108,11 +108,6 @@ public static int GetRequestId(QuicStream stream) return checked((int)stream.Id + 1); } - public Http3LoopbackStream GetOpenRequest(int requestId = 0) - { - return requestId == 0 ? _currentStream : _openStreams[requestId - 1]; - } - public override Task InitializeConnectionAsync() { throw new NotImplementedException(); @@ -195,6 +190,17 @@ public async Task EstablishControlStreamAsync(SettingsEntry[] settingsEntries) await _outboundControlStream.SendSettingsFrameAsync(settingsEntries); } + public async Task DisposeCurrentStream() + { + Assert.NotNull(_currentStream); + Assert.True(_currentStreamId >= 0); + + await _currentStream.DisposeAsync().ConfigureAwait(false); + _openStreams.Remove((int)_currentStreamId); + _currentStream = null; + _currentStreamId = -4; + } + public override async Task ReadRequestBodyAsync() { return await _currentStream.ReadRequestBodyAsync().ConfigureAwait(false); @@ -206,24 +212,32 @@ public override async Task ReadRequestDataAsync(bool readBody = return await stream.ReadRequestDataAsync(readBody).ConfigureAwait(false); } - public override Task SendResponseAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "", bool isFinal = true) + public override async Task SendResponseAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "", bool isFinal = true) { - return GetOpenRequest().SendResponseAsync(statusCode, headers, content, isFinal); + await _currentStream.SendResponseAsync(statusCode, headers, content, isFinal); + if (isFinal) + { + await DisposeCurrentStream().ConfigureAwait(false); + } } - public override Task SendResponseBodyAsync(byte[] content, bool isFinal = true) + public override async Task SendResponseBodyAsync(byte[] content, bool isFinal = true) { - return GetOpenRequest().SendResponseBodyAsync(content, isFinal); + await _currentStream.SendResponseBodyAsync(content, isFinal); + if (isFinal) + { + await DisposeCurrentStream().ConfigureAwait(false); + } } public override Task SendResponseHeadersAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null) { - return GetOpenRequest().SendResponseHeadersAsync(statusCode, headers); + return _currentStream.SendResponseHeadersAsync(statusCode, headers); } public override Task SendPartialResponseHeadersAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null) { - return GetOpenRequest().SendPartialResponseHeadersAsync(statusCode, headers); + return _currentStream.SendPartialResponseHeadersAsync(statusCode, headers); } public override async Task HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") @@ -310,7 +324,7 @@ public async Task WaitForClientDisconnectAsync(bool refuseNewRequests = true) public override async Task WaitForCancellationAsync(bool ignoreIncomingData = true) { - await GetOpenRequest().WaitForCancellationAsync(ignoreIncomingData).ConfigureAwait(false); + await _currentStream.WaitForCancellationAsync(ignoreIncomingData).ConfigureAwait(false); } public override Task WaitForCloseAsync(CancellationToken cancellationToken) From e20cc4e3e4e90540659b78c8938aba3c2238fae7 Mon Sep 17 00:00:00 2001 From: Matt Mitchell Date: Thu, 17 Aug 2023 10:02:09 -0700 Subject: [PATCH 029/783] Call SetupNuGetSources for installer jobs (#90754) --- eng/pipelines/installer/jobs/build-job.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/eng/pipelines/installer/jobs/build-job.yml b/eng/pipelines/installer/jobs/build-job.yml index 5a0e37157e45c5..04be011a540758 100644 --- a/eng/pipelines/installer/jobs/build-job.yml +++ b/eng/pipelines/installer/jobs/build-job.yml @@ -296,6 +296,25 @@ jobs: - checkout: self clean: true fetchDepth: $(checkoutFetchDepth) + + - ${{ if ne(variables['System.TeamProject'], 'public') }}: + - ${{ if ne(parameters.osGroup, 'windows') }}: + - task: Bash@3 + displayName: Setup Private Feeds Credentials + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh + arguments: $(Build.SourcesDirectory)/NuGet.config $Token + env: + Token: $(dn-bot-dnceng-artifact-feeds-rw) + - ${{ else }}: + - task: PowerShell@2 + displayName: Setup Private Feeds Credentials + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 + arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token + env: + Token: $(dn-bot-dnceng-artifact-feeds-rw) + - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}: - template: /eng/pipelines/common/download-artifact-step.yml parameters: From 3ab4246e5a3913786dd846da5cbbfa96435a3243 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 10:27:20 -0700 Subject: [PATCH 030/783] [release/8.0] JIT: Disallow mismatched GC-ness for physical promotions (#90739) * JIT: Disallow mismatched GC-ness for physical promotions Physical promotion was working under the assumption that reinterpreting GC pointers is undefined behavior, and would happily promote GC pointers as integers if it saw such accesses. However, physical promotion is function wide while the UB accesses can be happening in a restricted (dynamically unreachable) scope. This exact situation happens in MemoryExtensions.Contains. The issue was uncovered under jit stress where we did not fold away the guard early enough, meaning that promotion then saw a `TYP_LONG` access of a `struct { object, int }` and proceeded to promote it as such. Fix #90602 * Address feedback --------- Co-authored-by: Jakob Botsch Nielsen --- src/coreclr/jit/layout.cpp | 34 ++++++++++++++++++++++++++++++++ src/coreclr/jit/layout.h | 2 ++ src/coreclr/jit/promotion.cpp | 37 ++++++++++++++++++++++++++++++++--- 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/layout.cpp b/src/coreclr/jit/layout.cpp index 113414ddfd7f7a..918fd4ab6521d4 100644 --- a/src/coreclr/jit/layout.cpp +++ b/src/coreclr/jit/layout.cpp @@ -421,6 +421,7 @@ void ClassLayout::InitializeGCPtrs(Compiler* compiler) // // Return value: // true if at least one GC ByRef, false otherwise. +// bool ClassLayout::HasGCByRef() const { unsigned slots = GetSlotCount(); @@ -435,6 +436,39 @@ bool ClassLayout::HasGCByRef() const return false; } +//------------------------------------------------------------------------ +// IntersectsGCPtr: check if the specified interval intersects with a GC +// pointer. +// +// Parameters: +// offset - The start offset of the interval +// size - The size of the interval +// +// Return value: +// True if it does. +// +bool ClassLayout::IntersectsGCPtr(unsigned offset, unsigned size) const +{ + if (!HasGCPtr()) + { + return false; + } + + unsigned startSlot = offset / TARGET_POINTER_SIZE; + unsigned endSlot = (offset + size - 1) / TARGET_POINTER_SIZE; + assert((startSlot < GetSlotCount()) && (endSlot < GetSlotCount())); + + for (unsigned i = startSlot; i <= endSlot; i++) + { + if (IsGCPtr(i)) + { + return true; + } + } + + return false; +} + //------------------------------------------------------------------------ // AreCompatible: check if 2 layouts are the same for copying. // diff --git a/src/coreclr/jit/layout.h b/src/coreclr/jit/layout.h index 0e9d6ed65d03d3..59ecaa9405485d 100644 --- a/src/coreclr/jit/layout.h +++ b/src/coreclr/jit/layout.h @@ -216,6 +216,8 @@ class ClassLayout } } + bool IntersectsGCPtr(unsigned offset, unsigned size) const; + static bool AreCompatible(const ClassLayout* layout1, const ClassLayout* layout2); private: diff --git a/src/coreclr/jit/promotion.cpp b/src/coreclr/jit/promotion.cpp index e2c4e797a3c9d8..5982ed79283355 100644 --- a/src/coreclr/jit/promotion.cpp +++ b/src/coreclr/jit/promotion.cpp @@ -621,6 +621,38 @@ class LocalUses bool EvaluateReplacement( Compiler* comp, unsigned lclNum, const Access& access, unsigned inducedCount, weight_t inducedCountWtd) { + // Verify that this replacement has proper GC ness compared to the + // layout. While reinterpreting GC fields to integers can be considered + // UB, there are scenarios where it can happen safely: + // + // * The user code could have guarded the access with a dynamic check + // that it doesn't contain a GC pointer, so that the access is actually + // in dead code. This happens e.g. in span functions in SPC. + // + // * For byrefs, reinterpreting as an integer could be ok in a + // restricted scope due to pinning. + // + // In theory we could allow these promotions in the restricted scope, + // but currently physical promotion works on a function-wide basis. + + LclVarDsc* lcl = comp->lvaGetDesc(lclNum); + ClassLayout* layout = lcl->GetLayout(); + if (layout->IntersectsGCPtr(access.Offset, genTypeSize(access.AccessType))) + { + if (((access.Offset % TARGET_POINTER_SIZE) != 0) || + (layout->GetGCPtrType(access.Offset / TARGET_POINTER_SIZE) != access.AccessType)) + { + return false; + } + } + else + { + if (varTypeIsGC(access.AccessType)) + { + return false; + } + } + unsigned countOverlappedCallArg = 0; unsigned countOverlappedStoredFromCall = 0; @@ -678,9 +710,8 @@ class LocalUses // Now look at the overlapping struct uses that promotion will make more expensive. - unsigned countReadBacks = 0; - weight_t countReadBacksWtd = 0; - LclVarDsc* lcl = comp->lvaGetDesc(lclNum); + unsigned countReadBacks = 0; + weight_t countReadBacksWtd = 0; // For parameters or OSR locals we always need one read back. if (lcl->lvIsParam || lcl->lvIsOSRLocal) { From 77884726ecf744ea5bb2037b7cb52f0ed1ed6bc5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 10:55:24 -0700 Subject: [PATCH 031/783] [wasm] Pin sdk version to 8.0.100-rc.1.23415.5 for workload testing (#90748) .. because `dotnet-install --channel 8.0` is returning 9.0-alpha sdks right now. Co-authored-by: Ankit Jain --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index fd3e699e214032..760c9e8b76e3f7 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -206,7 +206,7 @@ 2.45.0 2.45.0 - + 8.0.100-rc.1.23415.5 1.1.2-beta1.23323.1 7.0.0-preview-20221010.1 From 38a117099c2bc6e32c9fb3eaec324450448128eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 14:33:37 -0700 Subject: [PATCH 032/783] Expose TC_* vars (#90761) Co-authored-by: EgorBo --- src/coreclr/inc/clrconfigvalues.h | 5 +++-- src/coreclr/vm/eeconfig.cpp | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h index ed61a56b976d26..7b356b07443999 100644 --- a/src/coreclr/inc/clrconfigvalues.h +++ b/src/coreclr/inc/clrconfigvalues.h @@ -574,9 +574,10 @@ RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TC_QuickJitForLoops, W("TC_QuickJitForLoops RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TC_QuickJitForLoops, W("TC_QuickJitForLoops"), 0, "When quick JIT is enabled, quick JIT may also be used for methods that contain loops.") #endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) RETAIL_CONFIG_DWORD_INFO(EXTERNAL_TC_AggressiveTiering, W("TC_AggressiveTiering"), 0, "Transition through tiers aggressively.") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_TC_CallCountThreshold, W("TC_CallCountThreshold"), TC_CallCountThreshold, "Number of times a method must be called in tier 0 after which it is promoted to the next tier.") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_TC_CallCountingDelayMs, W("TC_CallCountingDelayMs"), TC_CallCountingDelayMs, "A perpetual delay in milliseconds that is applied to call counting in tier 0 and jitting at higher tiers, while there is startup-like activity.") + RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_BackgroundWorkerTimeoutMs, W("TC_BackgroundWorkerTimeoutMs"), TC_BackgroundWorkerTimeoutMs, "How long in milliseconds the background worker thread may remain idle before exiting.") -RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_CallCountThreshold, W("TC_CallCountThreshold"), TC_CallCountThreshold, "Number of times a method must be called in tier 0 after which it is promoted to the next tier.") -RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_CallCountingDelayMs, W("TC_CallCountingDelayMs"), TC_CallCountingDelayMs, "A perpetual delay in milliseconds that is applied to call counting in tier 0 and jitting at higher tiers, while there is startup-like activity.") RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_DelaySingleProcMultiplier, W("TC_DelaySingleProcMultiplier"), TC_DelaySingleProcMultiplier, "Multiplier for TC_CallCountingDelayMs that is applied on a single-processor machine or when the process is affinitized to a single processor.") RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_CallCounting, W("TC_CallCounting"), 1, "Enabled by default (only activates when TieredCompilation is also enabled). If disabled immediately backpatches prestub, and likely prevents any promotion to higher tiers") RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_UseCallCountingStubs, W("TC_UseCallCountingStubs"), 1, "Uses call counting stubs for faster call counting.") diff --git a/src/coreclr/vm/eeconfig.cpp b/src/coreclr/vm/eeconfig.cpp index 417910eb183bc0..566a0c17ad4aa5 100644 --- a/src/coreclr/vm/eeconfig.cpp +++ b/src/coreclr/vm/eeconfig.cpp @@ -721,7 +721,8 @@ HRESULT EEConfig::sync() fTieredCompilation_CallCounting = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TC_CallCounting) != 0; DWORD tieredCompilation_ConfiguredCallCountThreshold = - CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TC_CallCountThreshold); + Configuration::GetKnobDWORDValue(W("System.Runtime.TC_CallCountThreshold"), CLRConfig::EXTERNAL_TC_CallCountThreshold); + if (tieredCompilation_ConfiguredCallCountThreshold == 0) { tieredCompilation_CallCountThreshold = 1; @@ -735,8 +736,9 @@ HRESULT EEConfig::sync() tieredCompilation_CallCountThreshold = (UINT16)tieredCompilation_ConfiguredCallCountThreshold; } - tieredCompilation_CallCountingDelayMs = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TC_CallCountingDelayMs); - + tieredCompilation_CallCountingDelayMs = + Configuration::GetKnobDWORDValue(W("System.Runtime.TC_CallCountingDelayMs"), CLRConfig::EXTERNAL_TC_CallCountingDelayMs); + bool hasSingleProcessor = GetCurrentProcessCpuCount() == 1; if (hasSingleProcessor) { From 64dc1fc29a27a7d7139f7619a102bbfdc6f37253 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 14:35:36 -0700 Subject: [PATCH 033/783] Call SetupNuGetSources for installer jobs (#90759) Co-authored-by: Matt Mitchell --- eng/pipelines/installer/jobs/build-job.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/eng/pipelines/installer/jobs/build-job.yml b/eng/pipelines/installer/jobs/build-job.yml index 5a0e37157e45c5..04be011a540758 100644 --- a/eng/pipelines/installer/jobs/build-job.yml +++ b/eng/pipelines/installer/jobs/build-job.yml @@ -296,6 +296,25 @@ jobs: - checkout: self clean: true fetchDepth: $(checkoutFetchDepth) + + - ${{ if ne(variables['System.TeamProject'], 'public') }}: + - ${{ if ne(parameters.osGroup, 'windows') }}: + - task: Bash@3 + displayName: Setup Private Feeds Credentials + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh + arguments: $(Build.SourcesDirectory)/NuGet.config $Token + env: + Token: $(dn-bot-dnceng-artifact-feeds-rw) + - ${{ else }}: + - task: PowerShell@2 + displayName: Setup Private Feeds Credentials + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 + arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token + env: + Token: $(dn-bot-dnceng-artifact-feeds-rw) + - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}: - template: /eng/pipelines/common/download-artifact-step.yml parameters: From 515e5d1b905a86d2adfe8775a9b1ca215c8e535d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 14:38:32 -0700 Subject: [PATCH 034/783] [release/8.0] Update Get/SetFieldValue to Account for EnC (#90623) * update Get/SetFieldValue * get the address of the instance * Update src/coreclr/vm/invokeutil.cpp --------- Co-authored-by: Mikelle Co-authored-by: Jan Kotas --- src/coreclr/vm/invokeutil.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/coreclr/vm/invokeutil.cpp b/src/coreclr/vm/invokeutil.cpp index c4ba804a4c493f..e6ed2103393e37 100644 --- a/src/coreclr/vm/invokeutil.cpp +++ b/src/coreclr/vm/invokeutil.cpp @@ -906,9 +906,13 @@ void InvokeUtil::SetValidField(CorElementType fldType, { void* pFieldData; if (pField->IsStatic()) + { pFieldData = pField->GetCurrentStaticAddress(); + } else - pFieldData = (*((BYTE**)target)) + pField->GetOffset() + sizeof(Object); + { + pFieldData = pField->GetInstanceAddress(*target); + } if (*valueObj == NULL) InitValueClass(pFieldData, pMT); @@ -1049,9 +1053,12 @@ OBJECTREF InvokeUtil::GetFieldValue(FieldDesc* pField, TypeHandle fieldType, OBJ GCPROTECT_BEGIN(obj); // calculate the offset to the field... if (pField->IsStatic()) + { p = pField->GetCurrentStaticAddress(); - else { - p = (*((BYTE**)target)) + pField->GetOffset() + sizeof(Object); + } + else + { + p = pField->GetInstanceAddress(*target); } GCPROTECT_END(); From a2953d7ac31164d605434ceec911210c9cf74493 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 14:43:10 -0700 Subject: [PATCH 035/783] [release/8.0] [JIT] ARM64 - Temporary fix for ldp/stp optimizations - with test fix (#90758) * Added regression test 85765 * Mark M4 as NoInlining * Check current and last ins format to determine whether to proceed with the optimized ldr/str pair * Additional test * Feedback * Fix test * Fixing test again... --------- Co-authored-by: TIHan --- src/coreclr/jit/emitarm64.cpp | 9 +++ .../JitBlue/Runtime_85765/Runtime_85765.cs | 63 +++++++++++++++++++ .../Runtime_85765/Runtime_85765.csproj | 9 +++ 3 files changed, 81 insertions(+) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.csproj diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index b4e81322e2a696..f01ad548d2ee04 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -16615,6 +16615,15 @@ emitter::RegisterOrder emitter::IsOptimizableLdrStrWithPair( emitAttr prevSize = emitLastIns->idOpSize(); ssize_t prevImm = emitGetInsSC(emitLastIns); + // If we have this format, the 'imm' and/or 'prevImm' are not scaled(encoded), + // therefore we cannot proceed. + // TODO: In this context, 'imm' and 'prevImm' are assumed to be scaled(encoded). + // They should never be scaled(encoded) until its about to be written to the buffer. + if (fmt == IF_LS_2C || lastInsFmt == IF_LS_2C) + { + return eRO_none; + } + // Signed, *raw* immediate value fits in 7 bits, so for LDP/ STP the raw value is from -64 to +63. // For LDR/ STR, there are 9 bits, so we need to limit the range explicitly in software. if ((imm < -64) || (imm > 63) || (prevImm < -64) || (prevImm > 63)) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs b/src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs new file mode 100644 index 00000000000000..89c22ae90dc821 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_85765 +{ + public struct S0 + { + public S0(bool f1): this() + { + } + } + + public struct S1 + { + public byte F0; + public bool F1; + public bool F2; + } + + [Fact] + public static void Test() + { + S1 vr2 = M4(); + vr2.F2 |= vr2.F1; + Assert.False(Consume(vr2.F2)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static S1 M4() + { + S1 var1 = default(S1); + var vr0 = new S0(false); + return var1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool Consume(bool value) + { + return value; + } + + // ------ + + [Fact] + public unsafe static void Test2() + { + byte* bytes = stackalloc byte[1024]; + bytes[0x1A] = 1; + bytes[0x1B] = 2; + int sum = Foo(bytes); + Assert.True(sum == 515); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public unsafe static int Foo(byte* b) + { + return Unsafe.ReadUnaligned(ref b[0x1A]) + Unsafe.ReadUnaligned(ref b[0x1B]); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.csproj new file mode 100644 index 00000000000000..a4cc9d0594f93e --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.csproj @@ -0,0 +1,9 @@ + + + True + True + + + + + From e64cdbb17b1023f30d1349badc4e045ded3a7a15 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 14:49:13 -0700 Subject: [PATCH 036/783] [release/8.0] Switch fx_ver_t::as_str from stringstream to append/to_string (#90760) * Switch fx_ver_t::as_str from stringstream to append/to_string * Switch version_t::as_str * Remove unnecessary include --------- Co-authored-by: Elinor Fung --- src/native/corehost/fxr/fx_ver.cpp | 31 ++++++-------------- src/native/corehost/fxr/fx_ver.h | 2 -- src/native/corehost/hostmisc/pal.unix.cpp | 1 - src/native/corehost/hostmisc/pal.windows.cpp | 1 - src/native/corehost/hostpolicy/version.cpp | 16 +++++----- 5 files changed, 18 insertions(+), 33 deletions(-) diff --git a/src/native/corehost/fxr/fx_ver.cpp b/src/native/corehost/fxr/fx_ver.cpp index 254f408effe9b8..7a857cdff473b0 100644 --- a/src/native/corehost/fxr/fx_ver.cpp +++ b/src/native/corehost/fxr/fx_ver.cpp @@ -70,31 +70,18 @@ bool fx_ver_t::operator >=(const fx_ver_t& b) const pal::string_t fx_ver_t::as_str() const { - pal::stringstream_t stream; - stream << m_major << _X(".") << m_minor << _X(".") << m_patch; + pal::string_t version = pal::to_string(m_major); + version += _X('.'); + version += pal::to_string(m_minor); + version += _X('.'); + version += pal::to_string(m_patch); if (!m_pre.empty()) - { - stream << m_pre; - } - if (!m_build.empty()) - { - stream << m_build; - } - return stream.str(); -} + version += m_pre; -pal::string_t fx_ver_t::prerelease_glob() const -{ - pal::stringstream_t stream; - stream << m_major << _X(".") << m_minor << _X(".") << m_patch << _X("-*"); - return stream.str(); -} + if (!m_build.empty()) + version += m_build; -pal::string_t fx_ver_t::patch_glob() const -{ - pal::stringstream_t stream; - stream << m_major << _X(".") << m_minor << _X(".*"); - return stream.str(); + return version; } static pal::string_t getId(const pal::string_t &ids, size_t idStart) diff --git a/src/native/corehost/fxr/fx_ver.h b/src/native/corehost/fxr/fx_ver.h index 5f5348386897b0..29f010876e04ae 100644 --- a/src/native/corehost/fxr/fx_ver.h +++ b/src/native/corehost/fxr/fx_ver.h @@ -26,8 +26,6 @@ struct fx_ver_t bool is_empty() const { return m_major == -1; } pal::string_t as_str() const; - pal::string_t prerelease_glob() const; - pal::string_t patch_glob() const; bool operator ==(const fx_ver_t& b) const; bool operator !=(const fx_ver_t& b) const; diff --git a/src/native/corehost/hostmisc/pal.unix.cpp b/src/native/corehost/hostmisc/pal.unix.cpp index 46ffaf951adfb9..34520aefd7365a 100644 --- a/src/native/corehost/hostmisc/pal.unix.cpp +++ b/src/native/corehost/hostmisc/pal.unix.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include "config.h" #include diff --git a/src/native/corehost/hostmisc/pal.windows.cpp b/src/native/corehost/hostmisc/pal.windows.cpp index 98e4efbed72f07..b11610492d3214 100644 --- a/src/native/corehost/hostmisc/pal.windows.cpp +++ b/src/native/corehost/hostmisc/pal.windows.cpp @@ -7,7 +7,6 @@ #include "longfile.h" #include -#include #include #include diff --git a/src/native/corehost/hostpolicy/version.cpp b/src/native/corehost/hostpolicy/version.cpp index ea643605ac88f2..c08316fe4b5a87 100644 --- a/src/native/corehost/hostpolicy/version.cpp +++ b/src/native/corehost/hostpolicy/version.cpp @@ -51,29 +51,31 @@ bool version_t::operator >=(const version_t& b) const pal::string_t version_t::as_str() const { - pal::stringstream_t stream; - + pal::string_t version; if (m_major >= 0) { - stream << m_major; + version += pal::to_string(m_major); if (m_minor >= 0) { - stream << _X(".") << m_minor; + version += _X('.'); + version += pal::to_string(m_minor); if (m_build >= 0) { - stream << _X(".") << m_build; + version += _X('.'); + version += pal::to_string(m_build); if (m_revision >= 0) { - stream << _X(".") << m_revision; + version += _X('.'); + version += pal::to_string(m_revision); } } } } - return stream.str(); + return version; } /*static*/ int version_t::compare(const version_t&a, const version_t& b) From 702d02c87b1601a6ec5f6cd6fa008bc9bb1b8adc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 15:58:58 -0700 Subject: [PATCH 037/783] [release/8.0-rc1] Improve filtering of candidate binding invocations in config binder gen (#90746) * Improve filtering of candidate binding invocations in config binder gen * Address feedback * Address feedback: rename helper; further tighten constraint * Add follow-up TODO * Revert TypeSyntax clause to fix failing tests --------- Co-authored-by: Layomi Akinrinade --- .../ConfigurationBindingGenerator.Parser.cs | 10 +--- .../gen/ConfigurationBindingGenerator.cs | 8 +-- .../gen/Helpers/Parser/BinderInvocation.cs | 59 ++++++++----------- 3 files changed, 31 insertions(+), 46 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs index 758311958c4515..b0f53ef074078f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs @@ -7,7 +7,6 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Operations; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { @@ -44,13 +43,10 @@ public Parser(SourceProductionContext context, KnownTypeSymbols typeSymbols, Imm foreach (BinderInvocation invocation in _invocations) { - IInvocationOperation invocationOperation = invocation.Operation!; - if (!invocationOperation.TargetMethod.IsExtensionMethod) - { - continue; - } + IMethodSymbol targetMethod = invocation.Operation.TargetMethod; + INamedTypeSymbol? candidateBinderType = targetMethod.ContainingType; + Debug.Assert(targetMethod.IsExtensionMethod); - INamedTypeSymbol? candidateBinderType = invocationOperation.TargetMethod.ContainingType; if (SymbolEqualityComparer.Default.Equals(candidateBinderType, _typeSymbols.ConfigurationBinder)) { RegisterMethodInvocation_ConfigurationBinder(invocation); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.cs index 5d7a830c729542..70da582dddf0cd 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.cs @@ -31,11 +31,11 @@ public void Initialize(IncrementalGeneratorInitializationContext context) ? new CompilationData((CSharpCompilation)compilation) : null); - IncrementalValuesProvider inputCalls = context.SyntaxProvider + IncrementalValuesProvider inputCalls = context.SyntaxProvider .CreateSyntaxProvider( - (node, _) => node is InvocationExpressionSyntax invocation, + (node, _) => BinderInvocation.IsCandidateSyntaxNode(node), BinderInvocation.Create) - .Where(operation => operation is not null); + .Where(invocation => invocation is not null); IncrementalValueProvider<(CompilationData?, ImmutableArray)> inputData = compilationData.Combine(inputCalls.Collect()); @@ -59,7 +59,7 @@ private static void Execute(CompilationData compilationData, ImmutableArray IsCandidateMethodName_ConfigurationBinder(name) || @@ -52,23 +40,24 @@ static bool IsCandidateBindingMethodName(string name) => IsValidMethodName_OptionsConfigurationServiceCollectionExtensions(name); } - private static bool IsCandidateInvocation(IInvocationOperation operation) + private static bool IsBindingOperation(IInvocationOperation operation) { if (operation.TargetMethod is not IMethodSymbol { IsExtensionMethod: true, Name: string methodName, - ContainingType: ITypeSymbol + ContainingType: INamedTypeSymbol { Name: string containingTypeName, - ContainingNamespace: INamespaceSymbol { } containingNamespace, - } containingType - } method || - containingNamespace.ToDisplayString() is not string containingNamespaceName) + ContainingNamespace: INamespaceSymbol containingNamespace, + } + }) { return false; } + string containingNamespaceName = containingNamespace.ToDisplayString(); + return (containingTypeName) switch { "ConfigurationBinder" => From 149a289ddcdb0bb319e50ccf05010f02efc97049 Mon Sep 17 00:00:00 2001 From: mikelle-rogers <45022607+mikelle-rogers@users.noreply.github.com> Date: Thu, 17 Aug 2023 16:00:36 -0700 Subject: [PATCH 038/783] Revert "Put HasNativeCodeReJITAware into GetFunctionAddress (#90049)" (#90696) This reverts commit eacb32e400b3f9d3522bed193bd534d02e8b170a. Need to investigate changes because they caused a test failure. --- src/coreclr/debug/daccess/dacimpl.h | 11 ++++++ src/coreclr/debug/daccess/task.cpp | 4 +- src/coreclr/debug/di/breakpoint.cpp | 2 - src/coreclr/debug/ee/controller.cpp | 24 ++++++++++-- src/coreclr/debug/ee/debugger.cpp | 56 +++++++++++++++++++++------ src/coreclr/debug/ee/debugger.h | 4 +- src/coreclr/debug/ee/functioninfo.cpp | 12 +++++- src/coreclr/debug/inc/dbgipcevents.h | 1 - src/coreclr/vm/dbginterface.h | 7 +++- src/coreclr/vm/eedbginterfaceimpl.cpp | 1 + src/coreclr/vm/encee.cpp | 4 +- src/coreclr/vm/method.cpp | 19 ++++----- src/coreclr/vm/method.hpp | 8 ++-- 13 files changed, 113 insertions(+), 40 deletions(-) diff --git a/src/coreclr/debug/daccess/dacimpl.h b/src/coreclr/debug/daccess/dacimpl.h index 8de684a5dae9a2..ddf61370f416e9 100644 --- a/src/coreclr/debug/daccess/dacimpl.h +++ b/src/coreclr/debug/daccess/dacimpl.h @@ -1253,6 +1253,17 @@ class ClrDataAccess /* [out] */ union STUB_BUF* outBuffer, /* [out] */ ULONG32* outFlags); + DebuggerJitInfo* GetDebuggerJitInfo(MethodDesc* methodDesc, + TADDR addr) + { + if (g_pDebugger) + { + return g_pDebugger->GetJitInfo(methodDesc, (PBYTE)addr, NULL); + } + + return NULL; + } + HRESULT GetMethodExtents(MethodDesc* methodDesc, METH_EXTENTS** extents); HRESULT GetMethodVarInfo(MethodDesc* methodDesc, diff --git a/src/coreclr/debug/daccess/task.cpp b/src/coreclr/debug/daccess/task.cpp index ddbf251b7b9825..9e428e81adef2b 100644 --- a/src/coreclr/debug/daccess/task.cpp +++ b/src/coreclr/debug/daccess/task.cpp @@ -5225,7 +5225,7 @@ EnumMethodInstances::Next(ClrDataAccess* dac, } } - if (!m_methodIter.Current()->HasNativeCodeAnyVersion()) + if (!m_methodIter.Current()->HasNativeCodeReJITAware()) { goto NextMethod; } @@ -5243,7 +5243,7 @@ EnumMethodInstances::CdStart(MethodDesc* methodDesc, CLRDATA_ENUM* handle) { if (!methodDesc->HasClassOrMethodInstantiation() && - !(methodDesc->HasNativeCodeAnyVersion())) + !methodDesc->HasNativeCodeReJITAware()) { *handle = 0; return S_FALSE; diff --git a/src/coreclr/debug/di/breakpoint.cpp b/src/coreclr/debug/di/breakpoint.cpp index 568d7fc9fc66ad..ad45df5c618ace 100644 --- a/src/coreclr/debug/di/breakpoint.cpp +++ b/src/coreclr/debug/di/breakpoint.cpp @@ -211,13 +211,11 @@ HRESULT CordbFunctionBreakpoint::Activate(BOOL fActivate) if (codeIsIL) { pEvent->BreakpointData.nativeCodeMethodDescToken = pEvent->BreakpointData.nativeCodeMethodDescToken.NullPtr(); - pEvent->BreakpointData.codeStartAddress = 0; } else { pEvent->BreakpointData.nativeCodeMethodDescToken = (m_code.GetValue()->AsNativeCode())->GetVMNativeCodeMethodDescToken().ToLsPtr(); - pEvent->BreakpointData.codeStartAddress = (m_code.GetValue()->AsNativeCode())->GetAddress(); } // Note: we're sending a two-way event, so it blocks here diff --git a/src/coreclr/debug/ee/controller.cpp b/src/coreclr/debug/ee/controller.cpp index 58e63ab399db2c..7dd186b4113d44 100644 --- a/src/coreclr/debug/ee/controller.cpp +++ b/src/coreclr/debug/ee/controller.cpp @@ -1247,8 +1247,26 @@ bool DebuggerController::BindPatch(DebuggerControllerPatch *patch, startAddr = (CORDB_ADDRESS_TYPE *) CORDB_ADDRESS_TO_PTR(patch->GetDJI()->m_addrOfCode); _ASSERTE(startAddr != NULL); } - //We should never be calling this function with both a NULL startAddr and a DJI that doesn't have code. - _ASSERTE(startAddr != NULL); + if (startAddr == NULL) + { + // Should not be trying to place patches on MethodDecs's for stubs. + // These stubs will never get jitted. + CONSISTENCY_CHECK_MSGF(!pMD->IsWrapperStub(), ("Can't place patch at stub md %p, %s::%s", + pMD, pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); + + startAddr = (CORDB_ADDRESS_TYPE *)g_pEEInterface->GetFunctionAddress(pMD); + // + // Code is not available yet to patch. The prestub should + // notify us when it is executed. + // + if (startAddr == NULL) + { + LOG((LF_CORDB, LL_INFO10000, + "DC::BP: Patch at 0x%zx not bindable yet.\n", patch->offset)); + + return false; + } + } } _ASSERTE(!g_pEEInterface->IsStub((const BYTE *)startAddr)); @@ -8638,7 +8656,7 @@ bool DebuggerFuncEvalComplete::SendEvent(Thread *thread, bool fIpChanged) // DebuggerEnCBreakpoint constructor - creates and activates a new EnC breakpoint // // Arguments: -// offset - IL offset in the function to place the patch +// offset - native offset in the function to place the patch // jitInfo - identifies the function in which the breakpoint is being placed // fTriggerType - breakpoint type: either REMAP_PENDING or REMAP_COMPLETE // pAppDomain - the breakpoint applies to the specified AppDomain only diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index d58a987244a8ea..a44a9e235f36cd 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -2841,8 +2841,6 @@ HRESULT Debugger::GetILToNativeMapping(PCODE pNativeCodeStartAddress, ULONG32 cM } CONTRACTL_END; - _ASSERTE(pNativeCodeStartAddress != NULL); - #ifdef PROFILING_SUPPORTED // At this point, we're pulling in the debugger. if (!HasLazyData()) @@ -3009,7 +3007,6 @@ HRESULT Debugger::GetILToNativeMappingIntoArrays( _ASSERTE(pcMap != NULL); _ASSERTE(prguiILOffset != NULL); _ASSERTE(prguiNativeOffset != NULL); - _ASSERTE(pNativeCodeStartAddress != NULL); // Any caller of GetILToNativeMappingIntoArrays had better call // InitializeLazyDataIfNecessary first! @@ -5414,6 +5411,28 @@ void Debugger::ReleaseAllRuntimeThreads(AppDomain *pAppDomain) g_pEEInterface->ResumeFromDebug(pAppDomain); } +// Given a method, get's its EnC version number. 1 if the method is not EnCed. +// Note that MethodDescs are reused between versions so this will give us +// the most recent EnC number. +int Debugger::GetMethodEncNumber(MethodDesc * pMethod) +{ + CONTRACTL + { + THROWS; + GC_NOTRIGGER; + } + CONTRACTL_END; + + DebuggerJitInfo * dji = GetLatestJitInfoFromMethodDesc(pMethod); + if (dji == NULL) + { + // If there's no DJI, couldn't have been EnCed. + return 1; + } + return (int) dji->m_encVersion; +} + + bool Debugger::IsJMCMethod(Module* pModule, mdMethodDef tkMethod) { CONTRACTL @@ -6200,6 +6219,25 @@ void Debugger::LockAndSendEnCRemapCompleteEvent(MethodDesc *pMD) Thread *thread = g_pEEInterface->GetThread(); // Note that the debugger lock is reentrant, so we may or may not hold it already. SENDIPCEVENT_BEGIN(this, thread); + + EX_TRY + { + // Ensure the DJI for the latest version of this method has been pre-created. + // It's not clear whether this is necessary or not, but it shouldn't hurt since + // we're going to need to create it anyway since we'll be debugging inside it. + DebuggerJitInfo *dji = g_pDebugger->GetLatestJitInfoFromMethodDesc(pMD); + (void)dji; //prevent "unused variable" error from GCC + _ASSERTE( dji != NULL ); + } + EX_CATCH + { + // GetLatestJitInfo could throw on OOM, but the debugger isn't resiliant to OOM. + // I'm not aware of any other legitimate reason why it may throw, so we'll ASSERT + // if it fails. + _ASSERTE(!"Unexpected exception from Debugger::GetLatestJitInfoFromMethodDesc on EnC remap complete"); + } + EX_END_CATCH(RethrowTerminalExceptions); + // Send an EnC remap complete event to the Right Side. DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer(); InitIPCEvent(ipce, @@ -7827,7 +7865,6 @@ void Debugger::FirstChanceManagedExceptionCatcherFound(Thread *pThread, // Implements DebugInterface // Call by EE/exception. Must be on managed thread _ASSERTE(GetThreadNULLOk() != NULL); - _ASSERTE(pMethodAddr != NULL); // Quick check. if (!CORDebuggerAttached()) @@ -10461,7 +10498,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) DebuggerJitInfo * pDJI = NULL; if ((pMethodDesc != NULL) && (pDMI != NULL)) { - pDJI = pDMI->FindOrCreateInitAndAddJitInfo(pMethodDesc, PINSTRToPCODE(dac_cast(pEvent->BreakpointData.codeStartAddress))); + pDJI = pDMI->FindOrCreateInitAndAddJitInfo(pMethodDesc, NULL /* startAddr */); } { @@ -12588,7 +12625,7 @@ DWORD Debugger::GetThreadIdHelper(Thread *pThread) // does not own the memory provided via vars outparameter. //----------------------------------------------------------------------------- void Debugger::GetVarInfo(MethodDesc * fd, // [IN] method of interest - CORDB_ADDRESS nativeCodeAddress, // [IN] which edit version + void *DebuggerVersionToken, // [IN] which edit version SIZE_T * cVars, // [OUT] size of 'vars' const ICorDebugInfo::NativeVarInfo **vars // [OUT] map telling where local vars are stored ) @@ -12600,7 +12637,7 @@ void Debugger::GetVarInfo(MethodDesc * fd, // [IN] method of interest } CONTRACTL_END; - DebuggerJitInfo * ji = g_pDebugger->GetJitInfo(fd, (const BYTE *)nativeCodeAddress); + DebuggerJitInfo * ji = (DebuggerJitInfo *)DebuggerVersionToken; // If we didn't supply a DJI, then we're asking for the most recent version. if (ji == NULL) @@ -12924,11 +12961,6 @@ HRESULT Debugger::UpdateFunction(MethodDesc* pMD, SIZE_T encVersion) // For each offset in the IL->Native map, set a new EnC breakpoint on the // ones that we know could be remap points. - - // Depending on which DJI was picked, the code might compute different IL offsets. The JIT may not guarantee it produces - // the same set of sequence points for every generic instantiation. - // Inside ENCSequencePointHelper there is logic that skips IL offsets that map to the same native offset. - // Its possible that one version of the code maps two IL offsets to the same native offset but another version of the code maps them to different offsets. PTR_DebuggerILToNativeMap seqMap = pJitInfo->GetSequenceMap(); for (unsigned int i = 0; i < pJitInfo->GetSequenceMapCount(); i++) { diff --git a/src/coreclr/debug/ee/debugger.h b/src/coreclr/debug/ee/debugger.h index 2c2440ddaf6977..26edd26a96140b 100644 --- a/src/coreclr/debug/ee/debugger.h +++ b/src/coreclr/debug/ee/debugger.h @@ -1933,6 +1933,8 @@ class Debugger : public DebugInterface bool IsJMCMethod(Module* pModule, mdMethodDef tkMethod); + int GetMethodEncNumber(MethodDesc * pMethod); + bool FirstChanceManagedException(Thread *pThread, SIZE_T currentIP, SIZE_T currentSP); @@ -1978,7 +1980,7 @@ class Debugger : public DebugInterface #endif // EnC_SUPPORTED void GetVarInfo(MethodDesc * fd, // [IN] method of interest - CORDB_ADDRESS nativeCodeAddress, // [IN] which edit version + void *DebuggerVersionToken, // [IN] which edit version SIZE_T * cVars, // [OUT] size of 'vars' const ICorDebugInfo::NativeVarInfo **vars // [OUT] map telling where local vars are stored ); diff --git a/src/coreclr/debug/ee/functioninfo.cpp b/src/coreclr/debug/ee/functioninfo.cpp index 19910c6429a9c6..76d4be3ab232f2 100644 --- a/src/coreclr/debug/ee/functioninfo.cpp +++ b/src/coreclr/debug/ee/functioninfo.cpp @@ -1565,7 +1565,9 @@ DebuggerJitInfo *DebuggerMethodInfo::FindOrCreateInitAndAddJitInfo(MethodDesc* f GC_NOTRIGGER; } CONTRACTL_END; + _ASSERTE(fd != NULL); + // The debugger doesn't track Lightweight-codegen methods b/c they have no metadata. if (fd->IsDynamicMethod()) { @@ -1574,8 +1576,16 @@ DebuggerJitInfo *DebuggerMethodInfo::FindOrCreateInitAndAddJitInfo(MethodDesc* f if (startAddr == NULL) { + // This will grab the start address for the current code version. startAddr = g_pEEInterface->GetFunctionAddress(fd); - _ASSERTE(startAddr != NULL); + if (startAddr == NULL) + { + startAddr = fd->GetNativeCodeReJITAware(); + if (startAddr == NULL) + { + return NULL; + } + } } else { diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h index e9643e50f480a2..9fe1afd31a54ba 100644 --- a/src/coreclr/debug/inc/dbgipcevents.h +++ b/src/coreclr/debug/inc/dbgipcevents.h @@ -2011,7 +2011,6 @@ struct MSLAYOUT DebuggerIPCEvent SIZE_T offset; SIZE_T encVersion; LSPTR_METHODDESC nativeCodeMethodDescToken; // points to the MethodDesc if !isIL - CORDB_ADDRESS codeStartAddress; } BreakpointData; struct MSLAYOUT diff --git a/src/coreclr/vm/dbginterface.h b/src/coreclr/vm/dbginterface.h index 85b9785bccbb9b..daa57d25c86cf3 100644 --- a/src/coreclr/vm/dbginterface.h +++ b/src/coreclr/vm/dbginterface.h @@ -203,7 +203,7 @@ class DebugInterface // Get debugger variable information for a specific version of a method virtual void GetVarInfo(MethodDesc * fd, // [IN] method of interest - CORDB_ADDRESS nativeCodeAddress, // [IN] which edit version + void *DebuggerVersionToken, // [IN] which edit version SIZE_T * cVars, // [OUT] size of 'vars' const ICorDebugInfo::NativeVarInfo **vars // [OUT] map telling where local vars are stored ) = 0; @@ -262,6 +262,11 @@ class DebugInterface virtual bool IsJMCMethod(Module* pModule, mdMethodDef tkMethod) = 0; + // Given a method, get's its EnC version number. 1 if the method is not EnCed. + // Note that MethodDescs are reused between versions so this will give us + // the most recent EnC number. + virtual int GetMethodEncNumber(MethodDesc * pMethod) = 0; + virtual void SendLogSwitchSetting (int iLevel, int iReason, _In_z_ LPCWSTR pLogSwitchName, diff --git a/src/coreclr/vm/eedbginterfaceimpl.cpp b/src/coreclr/vm/eedbginterfaceimpl.cpp index 352a534d5c1a88..792c608918a61d 100644 --- a/src/coreclr/vm/eedbginterfaceimpl.cpp +++ b/src/coreclr/vm/eedbginterfaceimpl.cpp @@ -630,6 +630,7 @@ PCODE EEDbgInterfaceImpl::GetFunctionAddress(MethodDesc *pFD) SUPPORTS_DAC; } CONTRACTL_END; + return pFD->GetNativeCode(); } diff --git a/src/coreclr/vm/encee.cpp b/src/coreclr/vm/encee.cpp index 3339462ad7fe77..1dcfb8bf091f4c 100644 --- a/src/coreclr/vm/encee.cpp +++ b/src/coreclr/vm/encee.cpp @@ -806,8 +806,8 @@ NOINLINE void EditAndContinueModule::FixContextAndResume( // Get the var info which the codemanager will use for updating // enregistered variables correctly, or variables whose lifetimes differ // at the update point - g_pDebugInterface->GetVarInfo(pMD, oldCodeInfo.GetCodeAddress(), &oldVarInfoCount, &pOldVarInfo); - g_pDebugInterface->GetVarInfo(pMD, newCodeInfo.GetCodeAddress(), &newVarInfoCount, &pNewVarInfo); + g_pDebugInterface->GetVarInfo(pMD, oldDebuggerFuncHandle, &oldVarInfoCount, &pOldVarInfo); + g_pDebugInterface->GetVarInfo(pMD, NULL, &newVarInfoCount, &pNewVarInfo); #ifdef TARGET_X86 // save the frame pointer as FixContextForEnC might step on it. diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 29910d6cb4c1c3..62b24e3dc091c6 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -913,6 +913,7 @@ PCODE MethodDesc::GetNativeCode() WRAPPER_NO_CONTRACT; SUPPORTS_DAC; _ASSERTE(!IsDefaultInterfaceMethod() || HasNativeCodeSlot()); + if (HasNativeCodeSlot()) { // When profiler is enabled, profiler may ask to rejit a code even though we @@ -934,7 +935,7 @@ PCODE MethodDesc::GetNativeCode() return GetStableEntryPoint(); } -PCODE MethodDesc::GetNativeCodeAnyVersion() +PCODE MethodDesc::GetNativeCodeReJITAware() { WRAPPER_NO_CONTRACT; SUPPORTS_DAC; @@ -945,23 +946,19 @@ PCODE MethodDesc::GetNativeCodeAnyVersion() return pDefaultCode; } - else { CodeVersionManager *pCodeVersionManager = GetCodeVersionManager(); CodeVersionManager::LockHolder codeVersioningLockHolder; - ILCodeVersionCollection ilVersionCollection = pCodeVersionManager->GetILCodeVersions(PTR_MethodDesc(this)); - for (ILCodeVersionIterator curIL = ilVersionCollection.Begin(), endIL = ilVersionCollection.End(); curIL != endIL; curIL++) + ILCodeVersion ilVersion = pCodeVersionManager->GetActiveILCodeVersion(PTR_MethodDesc(this)); + if (!ilVersion.IsDefaultVersion()) { - NativeCodeVersionCollection nativeCollection = curIL->GetNativeCodeVersions(PTR_MethodDesc(this)); - for (NativeCodeVersionIterator curNative = nativeCollection.Begin(), endNative = nativeCollection.End(); curNative != endNative; curNative++) + NativeCodeVersion activeNativeCodeVersion = ilVersion.GetActiveNativeCodeVersion(PTR_MethodDesc(this)); + if (!activeNativeCodeVersion.IsNull()) { - PCODE native = curNative->GetNativeCode(); - if(native != NULL) - { - return native; - } + return activeNativeCodeVersion.GetNativeCode(); } } + return NULL; } } diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index aaecfb20779f34..4b34045b57671e 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -1373,11 +1373,11 @@ class MethodDesc } // Perf warning: takes the CodeVersionManagerLock on every call - BOOL HasNativeCodeAnyVersion() + BOOL HasNativeCodeReJITAware() { LIMITED_METHOD_DAC_CONTRACT; - return GetNativeCodeAnyVersion() != NULL; + return GetNativeCodeReJITAware() != NULL; } BOOL SetNativeCodeInterlocked(PCODE addr, PCODE pExpected = NULL); @@ -1437,9 +1437,9 @@ class MethodDesc PCODE GetNativeCode(); // Returns GetNativeCode() if it exists, but also checks to see if there - // is a non-default code version that is populated with a code body and returns that. + // is a non-default IL code version and returns that. // Perf warning: takes the CodeVersionManagerLock on every call - PCODE GetNativeCodeAnyVersion(); + PCODE GetNativeCodeReJITAware(); #if defined(FEATURE_JIT_PITCHING) bool IsPitchable(); From f7df78f4c9b3944d1b937b264601d7b5da55f3ab Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 16:02:08 -0700 Subject: [PATCH 039/783] [release/8.0] Limit language version on Logger and Options source gens (#90709) * Limit language version on Logger and Options source gens * Exclude test in browser * Address the feedback * Fix Json test and apply more feedback * Remove quotes from language versions in source gen diagnostics. (#90720) --------- Co-authored-by: Tarek Mahmoud Sayed Co-authored-by: Eirik Tsarpalis --- docs/project/list-of-diagnostics.md | 10 +-- .../gen/DiagnosticDescriptors.cs | 8 +++ .../gen/LoggerMessageGenerator.Parser.cs | 7 ++ .../gen/Resources/Strings.resx | 6 ++ .../gen/Resources/xlf/Strings.cs.xlf | 10 +++ .../gen/Resources/xlf/Strings.de.xlf | 10 +++ .../gen/Resources/xlf/Strings.es.xlf | 10 +++ .../gen/Resources/xlf/Strings.fr.xlf | 10 +++ .../gen/Resources/xlf/Strings.it.xlf | 10 +++ .../gen/Resources/xlf/Strings.ja.xlf | 10 +++ .../gen/Resources/xlf/Strings.ko.xlf | 10 +++ .../gen/Resources/xlf/Strings.pl.xlf | 10 +++ .../gen/Resources/xlf/Strings.pt-BR.xlf | 10 +++ .../gen/Resources/xlf/Strings.ru.xlf | 10 +++ .../gen/Resources/xlf/Strings.tr.xlf | 10 +++ .../gen/Resources/xlf/Strings.zh-Hans.xlf | 10 +++ .../gen/Resources/xlf/Strings.zh-Hant.xlf | 10 +++ .../LoggerMessageGeneratorParserTests.cs | 54 +++++++++++++- .../gen/DiagDescriptors.cs | 7 ++ .../gen/Parser.cs | 7 ++ .../gen/Resources/Strings.resx | 6 ++ .../gen/Resources/xlf/Strings.cs.xlf | 70 +++++++++++-------- .../gen/Resources/xlf/Strings.de.xlf | 70 +++++++++++-------- .../gen/Resources/xlf/Strings.es.xlf | 70 +++++++++++-------- .../gen/Resources/xlf/Strings.fr.xlf | 70 +++++++++++-------- .../gen/Resources/xlf/Strings.it.xlf | 70 +++++++++++-------- .../gen/Resources/xlf/Strings.ja.xlf | 70 +++++++++++-------- .../gen/Resources/xlf/Strings.ko.xlf | 70 +++++++++++-------- .../gen/Resources/xlf/Strings.pl.xlf | 70 +++++++++++-------- .../gen/Resources/xlf/Strings.pt-BR.xlf | 70 +++++++++++-------- .../gen/Resources/xlf/Strings.ru.xlf | 70 +++++++++++-------- .../gen/Resources/xlf/Strings.tr.xlf | 70 +++++++++++-------- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 70 +++++++++++-------- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 70 +++++++++++-------- .../tests/SourceGeneration.Unit.Tests/Main.cs | 57 +++++++++++++++ .../Resources/Strings.resx | 6 ++ .../Resources/Strings.resx | 6 ++ .../gen/Resources/Strings.resx | 56 +++++++-------- .../gen/Resources/xlf/Strings.cs.xlf | 4 +- .../gen/Resources/xlf/Strings.de.xlf | 4 +- .../gen/Resources/xlf/Strings.es.xlf | 4 +- .../gen/Resources/xlf/Strings.fr.xlf | 4 +- .../gen/Resources/xlf/Strings.it.xlf | 4 +- .../gen/Resources/xlf/Strings.ja.xlf | 4 +- .../gen/Resources/xlf/Strings.ko.xlf | 4 +- .../gen/Resources/xlf/Strings.pl.xlf | 4 +- .../gen/Resources/xlf/Strings.pt-BR.xlf | 4 +- .../gen/Resources/xlf/Strings.ru.xlf | 4 +- .../gen/Resources/xlf/Strings.tr.xlf | 4 +- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 4 +- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 4 +- .../JsonSourceGeneratorDiagnosticsTests.cs | 8 +-- 52 files changed, 876 insertions(+), 454 deletions(-) diff --git a/docs/project/list-of-diagnostics.md b/docs/project/list-of-diagnostics.md index 4f78e9e711653d..75d252218f8392 100644 --- a/docs/project/list-of-diagnostics.md +++ b/docs/project/list-of-diagnostics.md @@ -142,10 +142,10 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL | __`SYSLIB1023`__ | Generating more than 6 arguments is not supported | | __`SYSLIB1024`__ | Argument is using the unsupported out parameter modifier | | __`SYSLIB1025`__ | Multiple logging methods cannot use the same event name within a class | -| __`SYSLIB1026`__ | _`SYSLIB1026`-`SYSLIB1029` reserved for logging._ | -| __`SYSLIB1027`__ | _`SYSLIB1026`-`SYSLIB1029` reserved for logging._ | -| __`SYSLIB1028`__ | _`SYSLIB1026`-`SYSLIB1029` reserved for logging._ | -| __`SYSLIB1029`__ | _`SYSLIB1026`-`SYSLIB1029` reserved for logging._ | +| __`SYSLIB1026`__ | C# language version not supported by the logging source generator. | +| __`SYSLIB1027`__ | _`SYSLIB1001`-`SYSLIB1029` reserved for logging._ | +| __`SYSLIB1028`__ | _`SYSLIB1001`-`SYSLIB1029` reserved for logging._ | +| __`SYSLIB1029`__ | _`SYSLIB1001`-`SYSLIB1029` reserved for logging._ | | __`SYSLIB1030`__ | JsonSourceGenerator did not generate serialization metadata for type | | __`SYSLIB1031`__ | JsonSourceGenerator encountered a duplicate JsonTypeInfo property name | | __`SYSLIB1032`__ | JsonSourceGenerator encountered a context class that is not partial | @@ -250,7 +250,7 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL | __`SYSLIB1213`__ | Options validation generator: Member potentially missing enumerable validation. | | __`SYSLIB1214`__ | Options validation generator: Can't validate constants, static fields or properties. | | __`SYSLIB1215`__ | Options validation generator: Validation attribute on the member is inaccessible from the validator type. | -| __`SYSLIB1216`__ | *_`SYSLIB1201`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* | +| __`SYSLIB1216`__ | C# language version not supported by the options validation source generator. | | __`SYSLIB1217`__ | *_`SYSLIB1201`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* | | __`SYSLIB1218`__ | *_`SYSLIB1201`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* | | __`SYSLIB1219`__ | *_`SYSLIB1201`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* | diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/DiagnosticDescriptors.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/DiagnosticDescriptors.cs index ed51ed6164188d..ec89ae4a42bc9a 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/DiagnosticDescriptors.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/DiagnosticDescriptors.cs @@ -200,5 +200,13 @@ public static class DiagnosticDescriptors category: "LoggingGenerator", DiagnosticSeverity.Warning, isEnabledByDefault: true); + + public static DiagnosticDescriptor LoggingUnsupportedLanguageVersion { get; } = new DiagnosticDescriptor( + id: "SYSLIB1026", + title: new LocalizableResourceString(nameof(SR.LoggingUnsupportedLanguageVersionTitle), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Logging.Generators.SR)), + messageFormat: new LocalizableResourceString(nameof(SR.LoggingUnsupportedLanguageVersionMessageFormat), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Logging.Generators.SR)), + category: "LoggingGenerator", + defaultSeverity: DiagnosticSeverity.Error, + isEnabledByDefault: true); } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs index 2b5b8ca6a1a498..038b71bef0759b 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs @@ -591,6 +591,13 @@ static bool IsAllowedKind(SyntaxKind kind) => } } + if (results.Count > 0 && _compilation is CSharpCompilation { LanguageVersion : LanguageVersion version and < LanguageVersion.CSharp8 }) + { + // we only support C# 8.0 and above + Diag(DiagnosticDescriptors.LoggingUnsupportedLanguageVersion, null, version.ToDisplayString(), LanguageVersion.CSharp8.ToDisplayString()); + return Array.Empty(); + } + return results; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/Strings.resx index 529263fda731fb..602e6f4730d216 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/Strings.resx @@ -231,4 +231,10 @@ Logging method contains malformed format strings + + C# language version not supported by the source generator. + + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.cs.xlf index ac5ddc07ceb05f..00e8b1cc7d91a1 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.cs.xlf @@ -67,6 +67,16 @@ Metody protokolování musí být statické. + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. + + Logging method '{0}' contains malformed format strings Metoda protokolování {0} obsahuje řetězce s poškozeným formátem. diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.de.xlf index c57008e516a5be..2e962cd97ac902 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.de.xlf @@ -67,6 +67,16 @@ Protokollierungsmethoden müssen statisch sein. + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. + + Logging method '{0}' contains malformed format strings Die Protokollierungsmethode „{0}“ enthält nicht wohlgeformte Formatzeichenfolgen. diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.es.xlf index 29cce5c24f3f77..46073f102868a1 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.es.xlf @@ -67,6 +67,16 @@ Los métodos de registro deben ser estáticos + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. + + Logging method '{0}' contains malformed format strings El método de registro “{0}” contiene cadenas con formato incorrecto diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.fr.xlf index afd2c184fc42fa..2497ea11a88a04 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.fr.xlf @@ -67,6 +67,16 @@ Les méthodes de journalisation doivent être statiques + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. + + Logging method '{0}' contains malformed format strings La méthode de journalisation « {0} »contient des chaînes de format incorrectes diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.it.xlf index 99b2e817511ae8..06dadffd497939 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.it.xlf @@ -67,6 +67,16 @@ I metodi di registrazione devono essere statici + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. + + Logging method '{0}' contains malformed format strings Il metodo di registrazione '{0}' contiene stringhe in formato non valido diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ja.xlf index a8c79393a42f23..bd03905bfba997 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ja.xlf @@ -67,6 +67,16 @@ ログ メソッドは静的である必要があります + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. + + Logging method '{0}' contains malformed format strings ログ メソッド '{0}' に、形式の正しくない文字列が含まれています diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ko.xlf index 0b77d9c65adb5f..eea8ef2203ac1d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ko.xlf @@ -67,6 +67,16 @@ 로깅 메서드는 정적이어야 함 + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. + + Logging method '{0}' contains malformed format strings 로깅 메서드 '{0}'에 잘못된 형식의 문자열이 포함되어 있습니다. diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pl.xlf index 2784dfa601576b..6dbecb86f7fc43 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pl.xlf @@ -67,6 +67,16 @@ Metody rejestrowania muszą być statyczne + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. + + Logging method '{0}' contains malformed format strings Metoda rejestrowania „{0}” zawiera źle sformułowane ciągi formatu diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pt-BR.xlf index 22b9fabb3b2965..f7de3a39c5a055 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pt-BR.xlf @@ -67,6 +67,16 @@ Os métodos de registro em log devem ser estáticos + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. + + Logging method '{0}' contains malformed format strings O método de registro '{0}' contém strings de formato malformado diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ru.xlf index 4446666caf4828..9599e0f6b9b809 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ru.xlf @@ -67,6 +67,16 @@ Методы ведения журнала должны быть статическими + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. + + Logging method '{0}' contains malformed format strings Метод ведения журнала событий "{0}" содержит строки неправильного формата diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.tr.xlf index fb21d7e0bd62ed..529a109ef75304 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.tr.xlf @@ -67,6 +67,16 @@ Günlüğe kaydetme yöntemleri statik olmalıdır + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. + + Logging method '{0}' contains malformed format strings '{0}' günlüğe kaydetme yöntemi hatalı biçimlendirilmiş biçim dizeleri içeriyor diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hans.xlf index 021f321ddf4b9f..879c6a773643a1 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -67,6 +67,16 @@ 日志记录方法必须为静态方法 + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. + + Logging method '{0}' contains malformed format strings 日志记录方法“{0}”包含格式错误的字符串 diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hant.xlf index c50c7054e6ee2a..42061caa455c27 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -67,6 +67,16 @@ 記錄方法必須是靜態 + + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. + + Logging method '{0}' contains malformed format strings 記錄方法 '{0}' 包含格式錯誤的格式字串 diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs index 462111ad00c372..dc677e81cfc4a0 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs @@ -4,10 +4,12 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using SourceGenerators.Tests; using Xunit; @@ -108,7 +110,7 @@ partial class C {{ [LoggerMessage({argumentList})] static partial void M1(ILogger logger, string foo); - + [LoggerMessage({argumentList})] static partial void M2(ILogger logger, LogLevel level, string foo); }} @@ -911,6 +913,56 @@ static partial void M1(ILogger logger) Assert.Equal(DiagnosticDescriptors.LoggingMethodHasBody.Id, diagnostics[0].Id); } + [Fact] + public async Task LanguageVersionTest() + { + string source = """ + using Microsoft.Extensions.Logging; + + internal partial class Program + { + static void Main() { } + + [LoggerMessage( + EventId = 0, + Level = LogLevel.Critical, + Message = "Could not open socket to `{hostName}`")] + static partial void CouldNotOpenSocket(ILogger logger, string hostName); + } + """; + + Assembly[]? refs = new[] { typeof(ILogger).Assembly, typeof(LoggerMessageAttribute).Assembly }; + + // Run the generator with C# 7.0 and verify that it fails. + var (diagnostics, generatedSources) = await RoslynTestUtils.RunGenerator( + new LoggerMessageGenerator(), refs, new[] { source }, includeBaseReferences: true, LanguageVersion.CSharp7).ConfigureAwait(false); + + Assert.NotEmpty(diagnostics); + Assert.Equal("SYSLIB1026", diagnostics[0].Id); + Assert.Empty(generatedSources); + + // Run the generator with C# 8.0 and verify that it succeeds. + (diagnostics, generatedSources) = await RoslynTestUtils.RunGenerator( + new LoggerMessageGenerator(), refs, new[] { source }, includeBaseReferences: true, LanguageVersion.CSharp8).ConfigureAwait(false); + + Assert.Empty(diagnostics); + Assert.Single(generatedSources); + + // Compile the generated code with C# 7.0 and verify that it fails. + CSharpParseOptions parseOptions = new CSharpParseOptions(LanguageVersion.CSharp7); + SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(generatedSources[0].SourceText.ToString(), parseOptions); + var diags = syntaxTree.GetDiagnostics().ToArray(); + Assert.Equal(1, diags.Length); + // error CS8107: Feature 'nullable reference types' is not available in C# 7.0. Please use language version 8.0 or greater. + Assert.Equal("CS8107", diags[0].Id); + + // Compile the generated code with C# 8.0 and verify that it succeeds. + parseOptions = new CSharpParseOptions(LanguageVersion.CSharp8); + syntaxTree = SyntaxFactory.ParseSyntaxTree(generatedSources[0].SourceText.ToString(), parseOptions); + diags = syntaxTree.GetDiagnostics().ToArray(); + Assert.Equal(0, diags.Length); + } + private static async Task> RunGenerator( string code, bool wrap = true, diff --git a/src/libraries/Microsoft.Extensions.Options/gen/DiagDescriptors.cs b/src/libraries/Microsoft.Extensions.Options/gen/DiagDescriptors.cs index 474686189fb126..141fc6b9c7f9ae 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/DiagDescriptors.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/DiagDescriptors.cs @@ -105,5 +105,12 @@ internal sealed class DiagDescriptors : DiagDescriptorsBase messageFormat: SR.InaccessibleValidationAttributeMessage, category: Category, defaultSeverity: DiagnosticSeverity.Info); + + public static DiagnosticDescriptor OptionsUnsupportedLanguageVersion { get; } = Make( + id: "SYSLIB1216", + title: SR.OptionsUnsupportedLanguageVersionTitle, + messageFormat: SR.OptionsUnsupportedLanguageVersionMessage, + category: Category, + defaultSeverity: DiagnosticSeverity.Error); } } diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs b/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs index 07ea7de51bf9a4..0c8e216e488c7f 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs @@ -143,6 +143,13 @@ public IReadOnlyList GetValidatorTypes(IEnumerable<(TypeDeclarati results.AddRange(_synthesizedValidators.Values); _synthesizedValidators.Clear(); + if (results.Count > 0 && _compilation is CSharpCompilation { LanguageVersion : LanguageVersion version and < LanguageVersion.CSharp8 }) + { + // we only support C# 8.0 and above + Diag(DiagDescriptors.OptionsUnsupportedLanguageVersion, null, version.ToDisplayString(), LanguageVersion.CSharp8.ToDisplayString()); + return new List(); + } + return results; } diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Options/gen/Resources/Strings.resx index ef074f147f915e..6293431eb7f90e 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/Strings.resx @@ -207,4 +207,10 @@ Validation attribute on the member is inaccessible from the validator type.. + + C# language version not supported by the source generator. + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf index fadfdec9e3b7ad..7054599d224576 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf @@ -4,152 +4,162 @@ Type {0} already implements the Validate method. - Typ {0} již implementuje metodu Validate. + Type {0} already implements the Validate method. A type already includes an implementation of the 'Validate' method. - Typ už obsahuje implementaci metody Validate. + A type already includes an implementation of the 'Validate' method. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] nelze použít pro statickou třídu {0}. + [OptionsValidator] cannot be applied to static class {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - OptionsValidatorAttribute nelze použít pro statickou třídu. + 'OptionsValidatorAttribute' can't be applied to a static class. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - U polí nebo vlastností s otevřeným obecným typem {0} nelze použít [ValidateObjectMembers] nebo [ValidateEnumeratedItems]. + Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - U polí nebo vlastností s otevřenými obecnými typy nelze použít ValidateObjectMembersAttribute nebo ValidateEnumeratedItemsAttribute. + Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. Can't apply validation attributes to constant or static member {0}. - Atributy ověřování nelze použít u konstantního ani statického člena {0}. + Can't apply validation attributes to constant or static member {0}. Can't validate constants, static fields or properties. - Nelze ověřit konstanty, statická pole ani vlastnosti. + Can't validate constants, static fields or properties. There is a circular type reference involving type {0} preventing it from being used for static validation. - Existuje cyklický odkaz obsahující typ {0}, který brání jeho použití pro statické ověření. + There is a circular type reference involving type {0} preventing it from being used for static validation. Unsupported circular references in model types. - Nepodporované cyklické odkazy v typech modelů. + Unsupported circular references in model types. Type {0} does not implement the required IValidateOptions<{1}> interface. - Typ {0} neimplementuje požadované rozhraní IValidateOptions<{1}> . + Type {0} does not implement the required IValidateOptions<{1}> interface. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - Typ anotovaný třídou OptionsValidatorAttribute neimplementuje nezbytné rozhraní. + A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Ověřovací atribut „{0}“ u člena „{1}“ není přístupný z typu validátoru „{2}“. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. Validation attribute on the member is inaccessible from the validator type.. - Ověřovací atribut u člena není přístupný z typu validátoru. + Validation attribute on the member is inaccessible from the validator type.. Can't apply validation attributes to private field or property {0}. - Ověřovací atributy nelze použít u privátního pole nebo vlastnosti {0}. + Can't apply validation attributes to private field or property {0}. Can't validate private fields or properties. - Nelze ověřit privátní pole nebo vlastnosti. + Can't validate private fields or properties. Type {0} has no fields or properties to validate, referenced from member {1}. - Typ {0} nemá žádná pole ani vlastnosti k ověření, na které odkazuje člen {1}. + Type {0} has no fields or properties to validate, referenced from member {1}. A member type has no fields or properties to validate. - Typ člena nemá žádná pole ani vlastnosti k ověření. + A member type has no fields or properties to validate. Type {0} has no fields or properties to validate, referenced by type {1}. - Typ {0} nemá žádná pole ani vlastnosti k ověření, na které odkazuje typ {1}. + Type {0} has no fields or properties to validate, referenced by type {1}. A type has no fields or properties to validate. - Typ nemá žádná pole ani vlastnosti k ověření. + A type has no fields or properties to validate. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] nelze použít u členů typu {0}, protože neimplementuje rozhraní IEnumerable<T>. + [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. Member type is not enumerable. - Typ členu není výčtový. + Member type is not enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Typ validátoru s hodnotou null zadaný v atributech [ValidateObjectMembers] nebo [ValidateEnumeratedItems]. + Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Pro atributy ValidateObjectMembersAttribute nebo ValidateEnumeratedItemsAttribute byl specifikovaný typ validátoru s hodnotou null. + Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Typ {0} obsahuje validační anotace, ale člen {1} neurčuje [ValidateEnumeratedItems], což může být přehlédnutí. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. Member potentially missing enumerable validation. - U člena potenciálně chybí ověření výčtu. + Member potentially missing enumerable validation. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Typ {0} obsahuje validační anotace, ale člen {1} neurčuje [ValidateObjectMembers], což může být přehlédnutí. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. Member potentially missing transitive validation. - U člena potenciálně chybí přenositelné ověření. + Member potentially missing transitive validation. Validator type {0} doesn't have a parameterless constructor. - Typ validátoru {0} nemá konstruktor bez parametrů. + Validator type {0} doesn't have a parameterless constructor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validátory používané pro přenositelné nebo výčtové ověřování musí mít konstruktor bez parametrů. + Validators used for transitive or enumerable validation must have a constructor with no parameters. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf index badb9618ac043b..5f6febba85c205 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf @@ -4,152 +4,162 @@ Type {0} already implements the Validate method. - Der Typ "{0}" implementiert bereits die Validate-Methode. + Type {0} already implements the Validate method. A type already includes an implementation of the 'Validate' method. - Ein Typ enthält bereits eine Implementierung der Validate-Methode. + A type already includes an implementation of the 'Validate' method. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] kann nicht auf die statische Klasse "{0}" angewendet werden. + [OptionsValidator] cannot be applied to static class {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - "OptionsValidatorAttribute" kann nicht auf eine statische Klasse angewendet werden. + 'OptionsValidatorAttribute' can't be applied to a static class. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - "ValidateObjectMembers" oder "ValidateEnumeratedItems" kann nicht für Felder oder Eigenschaften mit offenem generischen Typ {0} verwendet werden. + Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - "ValidateObjectMembersAttribute" oder "ValidateEnumeratedItemsAttribute" kann nicht für Felder oder Eigenschaften mit offenen generischen Typen verwendet werden. + Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. Can't apply validation attributes to constant or static member {0}. - Validierungsattribute können nicht auf konstanten oder statischen Member {0} angewendet werden. + Can't apply validation attributes to constant or static member {0}. Can't validate constants, static fields or properties. - Konstanten, statische Felder oder Eigenschaften können nicht überprüft werden. + Can't validate constants, static fields or properties. There is a circular type reference involving type {0} preventing it from being used for static validation. - Es gibt einen Zirkelverweis, der den Typ "{0}" verhindert, dass er für die statische Validierung verwendet wird. + There is a circular type reference involving type {0} preventing it from being used for static validation. Unsupported circular references in model types. - Nicht unterstützte Zirkelverweise in Modelltypen. + Unsupported circular references in model types. Type {0} does not implement the required IValidateOptions<{1}> interface. - Der Typ "{0}" implementiert nicht die erforderliche IValidateOptions<{1}>-Schnittstelle. + Type {0} does not implement the required IValidateOptions<{1}> interface. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - Ein mit "OptionsValidatorAttribute" versehener Typ implementiert nicht die erforderliche Schnittstelle. + A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Auf das Validierungsattribut "{0}" für den Member "{1}" kann vom Validierungssteuerelementtyp "{2}" nicht zugegriffen werden. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. Validation attribute on the member is inaccessible from the validator type.. - Auf das Validierungsattribut für den Member kann vom Validierungssteuerelementtyp nicht zugegriffen werden. + Validation attribute on the member is inaccessible from the validator type.. Can't apply validation attributes to private field or property {0}. - Validierungsattribute können nicht auf private Felder oder Eigenschaften {0} angewendet werden. + Can't apply validation attributes to private field or property {0}. Can't validate private fields or properties. - Private Felder oder Eigenschaften können nicht überprüft werden. + Can't validate private fields or properties. Type {0} has no fields or properties to validate, referenced from member {1}. - Der Typ "{0}" weist keine zu überprüfenden Felder oder Eigenschaften auf, auf die von Member "{1}" verwiesen wird. + Type {0} has no fields or properties to validate, referenced from member {1}. A member type has no fields or properties to validate. - Ein Membertyp weist keine zu überprüfenden Felder oder Eigenschaften auf. + A member type has no fields or properties to validate. Type {0} has no fields or properties to validate, referenced by type {1}. - Der Typ "{0}" weist keine zu überprüfenden Felder oder Eigenschaften auf, auf die vom Typ "{1}" verwiesen wird. + Type {0} has no fields or properties to validate, referenced by type {1}. A type has no fields or properties to validate. - Ein Typ weist keine zu überprüfenden Felder oder Eigenschaften auf. + A type has no fields or properties to validate. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] kann nicht für Member vom Typ "{0}" verwendet werden, da es IEnumerable<T> nicht implementiert. + [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. Member type is not enumerable. - Der Membertyp ist nicht aufzählbar. + Member type is not enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Der in den Attributen [ValidateObjectMembers] oder [ValidateEnumeratedItems] angegebene NULL-Validierungssteuerelementtyp. + Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Für die Attribute "ValidateObjectMembersAttribute" oder "ValidateEnumeratedItemsAttribute" wurde ein NULL-Validierungssteuerelementtyp angegeben. + Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Der Typ "{0}" weist Validierungsanmerkungen auf, der Member "{1}" gibt jedoch keine [ValidateEnumeratedItems] an, die eine Vorhersage darstellen könnten. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. Member potentially missing enumerable validation. - Dem Mitglied fehlt möglicherweise eine aufzählbare Validierung. + Member potentially missing enumerable validation. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Der Typ "{0}" weist Validierungsanmerkungen auf, aber Member "{1}" gibt [ValidateObjectMembers] nicht an, was ein Versehen sein könnte. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. Member potentially missing transitive validation. - Dem Member fehlt möglicherweise die transitive Validierung. + Member potentially missing transitive validation. Validator type {0} doesn't have a parameterless constructor. - Der Validierungssteuerelementtyp "{0}" hat keinen parameterlosen Konstruktor. + Validator type {0} doesn't have a parameterless constructor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validierungssteuerelemente, die für die transitive oder enumerierbare Validierung verwendet werden, müssen über einen Konstruktor ohne Parameter verfügen. + Validators used for transitive or enumerable validation must have a constructor with no parameters. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf index 9637c745a081e0..84c12b9739ab1a 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf @@ -4,152 +4,162 @@ Type {0} already implements the Validate method. - El tipo {0} ya implementa el método Validate. + Type {0} already implements the Validate method. A type already includes an implementation of the 'Validate' method. - Un tipo ya incluye una implementación del método “Validate”. + A type already includes an implementation of the 'Validate' method. [OptionsValidator] cannot be applied to static class {0}. - No se puede aplicar [OptionsValidator] a la clase estática {0}. + [OptionsValidator] cannot be applied to static class {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - “OptionsValidatorAttribute” no se puede aplicar a una clase estática. + 'OptionsValidatorAttribute' can't be applied to a static class. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - No se puede usar [ValidateObjectMembers] ni [ValidateEnumeratedItems] en campos o propiedades con tipos genéricos abiertos {0}. + Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - No se puede usar “ValidateObjectMembersAttribute” o “ValidateEnumeratedItemsAttribute” en campos o propiedades con tipos genéricos abiertos. + Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. Can't apply validation attributes to constant or static member {0}. - No se pueden aplicar atributos de validación a un miembro {0}constante o estático. + Can't apply validation attributes to constant or static member {0}. Can't validate constants, static fields or properties. - No se pueden validar constantes, campos estáticos ni propiedades. + Can't validate constants, static fields or properties. There is a circular type reference involving type {0} preventing it from being used for static validation. - Hay una referencia de tipo circular que implica al tipo {0} que impide que se use para la validación estática. + There is a circular type reference involving type {0} preventing it from being used for static validation. Unsupported circular references in model types. - Referencias circulares no admitidas en los tipos de modelo. + Unsupported circular references in model types. Type {0} does not implement the required IValidateOptions<{1}> interface. - El tipo {0} no implementa la interfaz IValidateOptions<{1}> necesaria. + Type {0} does not implement the required IValidateOptions<{1}> interface. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - Un tipo anotado con “OptionsValidatorAttribute” no implementa la interfaz necesaria. + A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - No se puede obtener acceso al atributo de validación '{0}' en el miembro '{1}' desde el tipo de validador '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. Validation attribute on the member is inaccessible from the validator type.. - No se puede obtener acceso al atributo de validación en el miembro desde el tipo de validador. + Validation attribute on the member is inaccessible from the validator type.. Can't apply validation attributes to private field or property {0}. - No se pueden aplicar atributos de validación a la propiedad o campo privado {0}. + Can't apply validation attributes to private field or property {0}. Can't validate private fields or properties. - No se pueden validar los campos o propiedades privadas. + Can't validate private fields or properties. Type {0} has no fields or properties to validate, referenced from member {1}. - El tipo {0} no tiene campos ni propiedades para validar, al que hace referencia el tipo {1}. + Type {0} has no fields or properties to validate, referenced from member {1}. A member type has no fields or properties to validate. - Un tipo de miembro no tiene campos ni propiedades para validar. + A member type has no fields or properties to validate. Type {0} has no fields or properties to validate, referenced by type {1}. - El tipo {0} no tiene campos ni propiedades para validar, al que hace referencia el tipo {1}. + Type {0} has no fields or properties to validate, referenced by type {1}. A type has no fields or properties to validate. - Un tipo no tiene campos ni propiedades para validar. + A type has no fields or properties to validate. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] no se puede usar en miembros de tipo {0} porque no implementa IEnumerable<T>. + [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. Member type is not enumerable. - El tipo de miembro no es enumerable. + Member type is not enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Se especificó un tipo de validador nulo en los atributos [ValidateObjectMembers] o [ValidateEnumeratedItems]. + Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Se especificó un tipo de validador nulo para los atributos “ValidateObjectMembersAttribute” o “ValidateEnumeratedItemsAttribute”. + Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - El tipo {0} tiene anotaciones de validación, pero el miembro {1} no especifica [ValidateEnumeratedItems], lo que podría ser un error. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. Member potentially missing enumerable validation. - Posiblemente falta la validación enumerable en el miembro. + Member potentially missing enumerable validation. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - El tipo {0} tiene anotaciones de validación, pero el miembro {1} no especifica [ValidateObjectMembers], lo que podría ser un error. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. Member potentially missing transitive validation. - Posiblemente falta la validación transitiva en el miembro. + Member potentially missing transitive validation. Validator type {0} doesn't have a parameterless constructor. - El tipo de validador {0} no tiene un constructor sin parámetros. + Validator type {0} doesn't have a parameterless constructor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Los validadores usados para la validación transitiva o enumerable deben tener un constructor sin parámetros. + Validators used for transitive or enumerable validation must have a constructor with no parameters. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf index 93817f52c7ddf7..58a27f1e4b33cb 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf @@ -4,152 +4,162 @@ Type {0} already implements the Validate method. - Le type {0} implémente déjà la méthode Validate. + Type {0} already implements the Validate method. A type already includes an implementation of the 'Validate' method. - Un type inclut déjà une implémentation de la méthode 'Validate'. + A type already includes an implementation of the 'Validate' method. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] ne peut pas être appliqué à la classe statique {0}. + [OptionsValidator] cannot be applied to static class {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' ne peut pas être appliqué à une classe statique. + 'OptionsValidatorAttribute' can't be applied to a static class. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Impossible d’utiliser [ValidateObjectMembers] ou [ValidateEnumeratedItems] sur des champs ou des propriétés avec un type générique ouvert {0}. + Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Impossible d’utiliser 'ValidateObjectMembersAttribute' ou 'ValidateEnumeratedItemsAttribute' sur des champs ou des propriétés avec des types génériques ouverts. + Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. Can't apply validation attributes to constant or static member {0}. - Impossible d’appliquer les attributs de validation au membre constant ou statique {0}. + Can't apply validation attributes to constant or static member {0}. Can't validate constants, static fields or properties. - Impossible de valider les constantes, les champs statiques ou les propriétés. + Can't validate constants, static fields or properties. There is a circular type reference involving type {0} preventing it from being used for static validation. - Une référence de type circulaire implique un type {0} l’empêche d’être utilisé pour la validation statique. + There is a circular type reference involving type {0} preventing it from being used for static validation. Unsupported circular references in model types. - Références circulaires non prises en charge dans les types de modèle. + Unsupported circular references in model types. Type {0} does not implement the required IValidateOptions<{1}> interface. - Le type {0} n’implémente pas l’interface<{1}> IValidateOptions requise. + Type {0} does not implement the required IValidateOptions<{1}> interface. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - Un type annoté avec 'OptionsValidatorAttribute' n’implémente pas l’interface nécessaire. + A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - L’attribut de validation '{0}' sur le membre '{1}' n’est pas accessible à partir du type de validateur '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. Validation attribute on the member is inaccessible from the validator type.. - L’attribut de validation sur le membre n’est pas accessible à partir du type de validateur. + Validation attribute on the member is inaccessible from the validator type.. Can't apply validation attributes to private field or property {0}. - Impossible d’appliquer les attributs de validation au champ privé ou à la propriété {0}. + Can't apply validation attributes to private field or property {0}. Can't validate private fields or properties. - Impossible de valider les champs ou propriétés privés. + Can't validate private fields or properties. Type {0} has no fields or properties to validate, referenced from member {1}. - Le type {0} n’a aucun champ ou propriété à valider, référencé à partir du membre {1}. + Type {0} has no fields or properties to validate, referenced from member {1}. A member type has no fields or properties to validate. - Un type de membre n’a aucun champ ou propriété à valider. + A member type has no fields or properties to validate. Type {0} has no fields or properties to validate, referenced by type {1}. - Le type {0} n’a pas de champs ou de propriétés à valider, référencé par type {1}. + Type {0} has no fields or properties to validate, referenced by type {1}. A type has no fields or properties to validate. - Un type n’a pas de champs ou de propriétés à valider. + A type has no fields or properties to validate. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] ne peut pas être utilisé sur des membres de type {0}, car il n’implémente pas IEnumerable<T>. + [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. Member type is not enumerable. - Le type de membre n’est pas énumérable. + Member type is not enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Type de validateur Null spécifié dans les attributs [ValidateObjectMembers] ou [ValidateEnumeratedItems]. + Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Type de validateur Null spécifié pour les attributs 'ValidateObjectMembersAttribute' ou 'ValidateEnumeratedItemsAttribute'. + Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Le type {0} a des annotations de validation, mais le membre {1} ne spécifie pas [ValidateEnumeratedItems] qui peut être une supervision. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. Member potentially missing enumerable validation. - Le membre n’a peut-être pas de validation énumérable. + Member potentially missing enumerable validation. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Le type {0} a des annotations de validation, mais le membre {1} ne spécifie pas [ValidateObjectMembers] qui pourrait être une méthode de récupération. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. Member potentially missing transitive validation. - Le membre n’a peut-être pas de validation transitive. + Member potentially missing transitive validation. Validator type {0} doesn't have a parameterless constructor. - Le type de validateur {0} n’a pas de constructeur sans paramètre. + Validator type {0} doesn't have a parameterless constructor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Les validateurs utilisés pour la validation transitive ou énumérable doivent avoir un constructeur sans paramètres. + Validators used for transitive or enumerable validation must have a constructor with no parameters. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf index b80d8e27bcec22..2355a93c01db99 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf @@ -4,152 +4,162 @@ Type {0} already implements the Validate method. - Il tipo {0} implementa già il metodo Validate. + Type {0} already implements the Validate method. A type already includes an implementation of the 'Validate' method. - Un tipo include già un'implementazione del metodo 'Validate'. + A type already includes an implementation of the 'Validate' method. [OptionsValidator] cannot be applied to static class {0}. - impossibile applicare [OptionsValidator] alla classe statica {0}. + [OptionsValidator] cannot be applied to static class {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' non può essere applicato a una classe statica. + 'OptionsValidatorAttribute' can't be applied to a static class. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Non è possibile usare [ValidateObjectMembers] o [ValidateEnumeratedItems] in campi o proprietà con tipo generico aperto {0}. + Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Non è possibile usare 'ValidateObjectMembersAttribute' o 'ValidateEnumeratedItemsAttribute' nei campi o nelle proprietà con tipi generici aperti. + Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. Can't apply validation attributes to constant or static member {0}. - Non è possibile applicare attributi di convalida a un membro costante o statico {0}. + Can't apply validation attributes to constant or static member {0}. Can't validate constants, static fields or properties. - Non è possibile convalidare costanti, campi statici o proprietà. + Can't validate constants, static fields or properties. There is a circular type reference involving type {0} preventing it from being used for static validation. - Esiste un riferimento di tipo circolare che interessa il tipo {0} e ne impedisce l'utilizzo per la convalida statica. + There is a circular type reference involving type {0} preventing it from being used for static validation. Unsupported circular references in model types. - Riferimenti circolari non supportati nei tipi di modello. + Unsupported circular references in model types. Type {0} does not implement the required IValidateOptions<{1}> interface. - Il tipo {0} non implementa l'interfaccia IValidateOptions<{1}> richiesta. + Type {0} does not implement the required IValidateOptions<{1}> interface. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - Un tipo annotato con 'OptionsValidatorAttribute' non implementa l'interfaccia necessaria. + A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - L'attributo di convalida '{0}' nel membro '{1}' non è accessibile dal tipo di validator '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. Validation attribute on the member is inaccessible from the validator type.. - L'attributo di convalida nel membro non è accessibile dal tipo di validator. + Validation attribute on the member is inaccessible from the validator type.. Can't apply validation attributes to private field or property {0}. - Non è possibile applicare gli attributi di convalida al campo privato o alla proprietà {0}. + Can't apply validation attributes to private field or property {0}. Can't validate private fields or properties. - Non è possibile convalidare proprietà o campi privati. + Can't validate private fields or properties. Type {0} has no fields or properties to validate, referenced from member {1}. - Il tipo {0} non contiene campi o proprietà da convalidare, riferiti dal membro {1}. + Type {0} has no fields or properties to validate, referenced from member {1}. A member type has no fields or properties to validate. - Un tipo di membro non contiene campi o proprietà da convalidare. + A member type has no fields or properties to validate. Type {0} has no fields or properties to validate, referenced by type {1}. - Il tipo {0} non contiene campi o proprietà da convalidare, riferiti per tipo {1}. + Type {0} has no fields or properties to validate, referenced by type {1}. A type has no fields or properties to validate. - Un tipo non contiene campi o proprietà da convalidare. + A type has no fields or properties to validate. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] non può essere usato nei membri di tipo {0} perché non implementa IEnumerable<T>. + [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. Member type is not enumerable. - Il tipo di membro non è enumerabile. + Member type is not enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Tipo di validator Null specificato negli attributi [ValidateObjectMembers] o [ValidateEnumeratedItems]. + Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Tipo di validator Null specificato per gli attributi 'ValidateObjectMembersAttribute' o 'ValidateEnumeratedItemsAttribute'. + Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Il tipo {0} include annotazioni di convalida, ma il membro {1} non specifica [ValidateEnumeratedItems] che potrebbe essere una supervisione. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. Member potentially missing enumerable validation. - Convalida enumerabile potenzialmente mancante nel membro. + Member potentially missing enumerable validation. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Il tipo {0} include annotazioni di convalida, ma il membro {1} non specifica [ValidateObjectMembers] che potrebbe essere una supervisione. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. Member potentially missing transitive validation. - Il membro potrebbe non avere una convalida transitiva. + Member potentially missing transitive validation. Validator type {0} doesn't have a parameterless constructor. - Il tipo di convalida {0} non dispone di un costruttore senza parametri. + Validator type {0} doesn't have a parameterless constructor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - I convalidatori usati per la convalida transitiva o enumerabile devono avere un costruttore senza parametri. + Validators used for transitive or enumerable validation must have a constructor with no parameters. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf index b9b44dd4afd5e5..60e9a7db80c8d4 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf @@ -4,152 +4,162 @@ Type {0} already implements the Validate method. - 型 {0} に Validate メソッドが既に実装されています。 + Type {0} already implements the Validate method. A type already includes an implementation of the 'Validate' method. - 型には 'Validate' メソッドの実装が既に含まれています。 + A type already includes an implementation of the 'Validate' method. [OptionsValidator] cannot be applied to static class {0}. - 静的クラス {0} には [OptionsValidator] を適用できません。 + [OptionsValidator] cannot be applied to static class {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' は静的クラスに適用できません。 + 'OptionsValidatorAttribute' can't be applied to a static class. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - [ValidateObjectMembers] または [ValidateEnumeratedItems] は、オープンジェネリック型 {0} を持つフィールドまたはプロパティでは使用できません。 + Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - 'ValidateObjectMembersAttribute' または 'ValidateEnumeratedItemsAttribute' は、オープンジェネリック型を持つフィールドまたはプロパティでは使用できません。 + Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. Can't apply validation attributes to constant or static member {0}. - 定数または静的メンバー {0} に検証属性を適用できません。 + Can't apply validation attributes to constant or static member {0}. Can't validate constants, static fields or properties. - 定数、静的フィールド、またはプロパティを検証できません。 + Can't validate constants, static fields or properties. There is a circular type reference involving type {0} preventing it from being used for static validation. - 型{0}を含む循環型参照があるため、静的検証に使用できません。 + There is a circular type reference involving type {0} preventing it from being used for static validation. Unsupported circular references in model types. - モデル型でサポートされていない循環参照です。 + Unsupported circular references in model types. Type {0} does not implement the required IValidateOptions<{1}> interface. - 必要な IValidateOptions<{1}> インターフェイスが型 {0} に実装されていません。 + Type {0} does not implement the required IValidateOptions<{1}> interface. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - 'OptionsValidatorAttribute' の注釈が付けられた型が、必要とされるインターフェイスを実装していません。 + A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - メンバー '{0}' の検証属性 '{1}' は、検証コントロールの種類 '{2}'からアクセスできません。 + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. Validation attribute on the member is inaccessible from the validator type.. - メンバーの検証属性は、検証コントロールの種類からアクセスできません... + Validation attribute on the member is inaccessible from the validator type.. Can't apply validation attributes to private field or property {0}. - プライベート フィールドまたはプロパティ {0} には検証属性を適用できません。 + Can't apply validation attributes to private field or property {0}. Can't validate private fields or properties. - プライベート フィールドまたはプロパティを検証できません。 + Can't validate private fields or properties. Type {0} has no fields or properties to validate, referenced from member {1}. - 型 {0} にメンバー {1} から参照されている検証対象のフィールドまたはプロパティがありません。 + Type {0} has no fields or properties to validate, referenced from member {1}. A member type has no fields or properties to validate. - メンバー型に検証対象のフィールドまたはプロパティがありません。 + A member type has no fields or properties to validate. Type {0} has no fields or properties to validate, referenced by type {1}. - 型 {0} に型 {1} で参照されている検証対象のフィールドまたはプロパティがありません。 + Type {0} has no fields or properties to validate, referenced by type {1}. A type has no fields or properties to validate. - 型に検証対象のフィールドまたはプロパティがありません。 + A type has no fields or properties to validate. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] は IEnumerable<T> を実装していないため、型 {0} のメンバーでは使用できません。 + [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. Member type is not enumerable. - メンバー型は列挙型ではありません。 + Member type is not enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - [ValidateObjectMembers] 属性または [ValidateEnumeratedItems] 属性で null のバリデーター型が指定されています。 + Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - 'ValidateObjectMembersAttribute' 属性または 'ValidateEnumeratedItemsAttribute' 属性に対して NULL のバリデーター型が指定されています。 + Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - 型 {0} には検証の注釈がありますが、メンバー {1} では [ValidateEnumeratedItem] が指定されていません。これは誤りである可能性があります。 + Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. Member potentially missing enumerable validation. - 列挙型の検証がメンバーに存在しない可能性があります。 + Member potentially missing enumerable validation. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - 型 {0} には検証の注釈がありますが、メンバー {1} では [ValidateObjectMembers] が指定されていません。これは誤りである可能性があります。 + Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. Member potentially missing transitive validation. - メンバーに推移性の検証がない可能性があります。 + Member potentially missing transitive validation. Validator type {0} doesn't have a parameterless constructor. - バリデーター型 {0} にパラメーターなしのコンストラクターがありません。 + Validator type {0} doesn't have a parameterless constructor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - 推移性または列挙型の検証に使用されるバリデーターには、パラメーターのないコンストラクターが必要です。 + Validators used for transitive or enumerable validation must have a constructor with no parameters. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf index 45819c9f750a5a..e350b2f6f437de 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf @@ -4,152 +4,162 @@ Type {0} already implements the Validate method. - 형식 {0}은(는) Validate 메서드를 이미 구현하고 있습니다. + Type {0} already implements the Validate method. A type already includes an implementation of the 'Validate' method. - 형식에 'Validate' 메서드 구현이 이미 포함되어 있습니다. + A type already includes an implementation of the 'Validate' method. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator]은(는) 정적 클래스 {0}에 적용할 수 없습니다. + [OptionsValidator] cannot be applied to static class {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute'는 정적 클래스에 적용할 수 없습니다. + 'OptionsValidatorAttribute' can't be applied to a static class. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - 열린 제네릭 형식 {0}의 필드 또는 속성에는 [ValidateObjectMembers] 또는 [ValidateEnumeratedItems]을(를) 사용할 수 없습니다. + Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - 열린 제네릭 형식의 필드 또는 속성에는 'ValidateObjectMembersAttribute' 또는 'ValidateEnumeratedItemsAttribute'를 사용할 수 없습니다. + Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. Can't apply validation attributes to constant or static member {0}. - 상수 또는 정적 멤버 {0}에 유효성 검사 특성을 적용할 수 없습니다. + Can't apply validation attributes to constant or static member {0}. Can't validate constants, static fields or properties. - 상수, 정적 필드 또는 속성을 확인할 수 없습니다. + Can't validate constants, static fields or properties. There is a circular type reference involving type {0} preventing it from being used for static validation. - 정적 유효성 검사에 사용할 수 없으므로 형식 {0} 관련된 순환 형식 참조가 있습니다. + There is a circular type reference involving type {0} preventing it from being used for static validation. Unsupported circular references in model types. - 모델 형식에 지원되지 않는 순환 참조가 있습니다. + Unsupported circular references in model types. Type {0} does not implement the required IValidateOptions<{1}> interface. - 형식 {0}은(는) 필요한 IValidateOptions<{1}> 인터페이스를 구현하지 않습니다. + Type {0} does not implement the required IValidateOptions<{1}> interface. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - 'OptionsValidatorAttribute'로 주석이 추가된 형식은 필요한 인터페이스를 구현하지 않습니다. + A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - 유효성 검사기 유형 '{2}'에서 '{1}' 멤버의 '{0}' 유효성 검사 특성에 액세스할 수 없습니다. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. Validation attribute on the member is inaccessible from the validator type.. - 유효성 검사기 유형에서 멤버의 유효성 검사 특성에 액세스할 수 없습니다. + Validation attribute on the member is inaccessible from the validator type.. Can't apply validation attributes to private field or property {0}. - 프라이빗 필드 또는 속성 {0}에 유효성 검사 특성을 적용할 수 없습니다. + Can't apply validation attributes to private field or property {0}. Can't validate private fields or properties. - 프라이빗 필드 또는 속성의 유효성을 검사할 수 없습니다. + Can't validate private fields or properties. Type {0} has no fields or properties to validate, referenced from member {1}. - 형식 {0}은(는) 유효성을 검사할 필드 또는 속성이 없으므로 멤버 {1}을(를) 참조합니다. + Type {0} has no fields or properties to validate, referenced from member {1}. A member type has no fields or properties to validate. - 멤버 형식에 유효성을 검사할 필드 또는 속성이 없습니다. + A member type has no fields or properties to validate. Type {0} has no fields or properties to validate, referenced by type {1}. - 형식 {0}은(는) 유효성을 검사할 필드 또는 속성이 없으므로 형식 {1}을(를) 참조합니다. + Type {0} has no fields or properties to validate, referenced by type {1}. A type has no fields or properties to validate. - 형식에 유효성을 검사할 필드 또는 속성이 없습니다. + A type has no fields or properties to validate. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems]은(는) IEnumerable<T>을(를) 구현하지 않으므로 형식 {0}의 멤버에 사용할 수 없습니다. + [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. Member type is not enumerable. - 멤버 형식을 열거할 수 없습니다. + Member type is not enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - [ValidateObjectMembers] 또는 [ValidateEnumeratedItems] 특성에 Null 유효성 검사기 형식이 지정되었습니다. + Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - 'ValidateObjectMembersAttribute' 또는 'ValidateEnumeratedItemsAttribute' 특성에 Null 유효성 검사기 형식이 지정되었습니다. + Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - 형식 {0}은(는) 유효성 검사 주석이 있지만 멤버 {1}은(는) 참조할 수 있는 [ValidateEnumeratedItems]을(를) 지정하지 않습니다. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. Member potentially missing enumerable validation. - 멤버에 열거 가능한 유효성 검사가 누락되었을 수 있습니다. + Member potentially missing enumerable validation. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - 형식 {0}은(는) 유효성 검사 주석이 있지만 멤버 {1}은(는) 참조할 수 있는 [ValidateObjectMembers]을(를) 지정하지 않습니다. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. Member potentially missing transitive validation. - 멤버에 전이적 유효성 검사가 누락되었을 수 있습니다. + Member potentially missing transitive validation. Validator type {0} doesn't have a parameterless constructor. - 유효성 검사기 형식 {0}은(는) 매개 변수가 없는 생성자가 없습니다. + Validator type {0} doesn't have a parameterless constructor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - 전이적 또는 열거형 유효성 검사에 사용되는 유효성 검사기에는 매개 변수가 없는 생성자가 있어야 합니다. + Validators used for transitive or enumerable validation must have a constructor with no parameters. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf index 0b57a0ac378924..edaf8b9d00e9ba 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf @@ -4,152 +4,162 @@ Type {0} already implements the Validate method. - Typ {0} już implementuje metodę Validate. + Type {0} already implements the Validate method. A type already includes an implementation of the 'Validate' method. - Typ zawiera już implementację metody „Validate”. + A type already includes an implementation of the 'Validate' method. [OptionsValidator] cannot be applied to static class {0}. - Nie można zastosować elementu [OptionsValidator] do klasy statycznej {0}. + [OptionsValidator] cannot be applied to static class {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - Nie można zastosować elementu „OptionsValidatorAttribute” do klasy statycznej. + 'OptionsValidatorAttribute' can't be applied to a static class. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Nie można użyć atrybutu [ValidateObjectMembers] lub [ValidateEnumeratedItems] w polach lub właściwościach z otwartymi typami ogólnymi {0}. + Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Nie można użyć atrybutu „ValidateObjectMembersAttribute” lub „ValidateEnumeratedItemsAttribute” w polach lub właściwościach z otwartymi typami ogólnymi. + Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. Can't apply validation attributes to constant or static member {0}. - Nie można zastosować atrybutów walidacji do stałych lub statycznych elementów członkowskich {0}. + Can't apply validation attributes to constant or static member {0}. Can't validate constants, static fields or properties. - Nie można zweryfikować stałych, pól statycznych lub właściwości. + Can't validate constants, static fields or properties. There is a circular type reference involving type {0} preventing it from being used for static validation. - Istnieje cykliczne odwołanie do typu dotyczące typu {0} uniemożliwiające użycie go do weryfikacji statycznej. + There is a circular type reference involving type {0} preventing it from being used for static validation. Unsupported circular references in model types. - Nieobsługiwane odwołania cykliczne w typach modeli. + Unsupported circular references in model types. Type {0} does not implement the required IValidateOptions<{1}> interface. - Typ {0} nie implementuje wymaganego interfejsu IValidateOptions<{1}>. + Type {0} does not implement the required IValidateOptions<{1}> interface. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - Typ z adnotacją „OptionsValidatorAttribute” nie implementuje wymaganego interfejsu. + A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Atrybut walidacji „{0}” elementu członkowskiego „{1}” jest niedostępny z typu modułu sprawdzania poprawności „{2}”. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. Validation attribute on the member is inaccessible from the validator type.. - Atrybut walidacji elementu członkowskiego jest niedostępny z typu modułu sprawdzania poprawności. + Validation attribute on the member is inaccessible from the validator type.. Can't apply validation attributes to private field or property {0}. - Nie można zastosować atrybutów weryfikacji do pola prywatnego lub właściwości {0}. + Can't apply validation attributes to private field or property {0}. Can't validate private fields or properties. - Nie można zweryfikować prywatnych pól lub właściwości. + Can't validate private fields or properties. Type {0} has no fields or properties to validate, referenced from member {1}. - Typ {0} nie ma pól ani właściwości do zweryfikowania, do których odwołuje się element członkowski {1}. + Type {0} has no fields or properties to validate, referenced from member {1}. A member type has no fields or properties to validate. - Typ elementu członkowskiego nie ma pól ani właściwości do zweryfikowania. + A member type has no fields or properties to validate. Type {0} has no fields or properties to validate, referenced by type {1}. - Typ {0} nie ma pól ani właściwości do zweryfikowania, do których odwołuje się typ {1}. + Type {0} has no fields or properties to validate, referenced by type {1}. A type has no fields or properties to validate. - Typ nie ma pól ani właściwości do zweryfikowania. + A type has no fields or properties to validate. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - Atrybutu [ValidateEnumeratedItems] nie można używać w przypadku elementów członkowskich typu {0}, ponieważ nie implementuje interfejsu IEnumerable<T>. + [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. Member type is not enumerable. - Nie można wyliczyć typu elementu członkowskiego. + Member type is not enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - W atrybutach [ValidateObjectMembers] lub [ValidateEnumeratedItems] określono typ modułu sprawdzania poprawności o wartości null. + Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Określono typ modułu sprawdzania poprawności o wartości null dla atrybutu „ValidateObjectMembersAttribute” lub „ValidateEnumeratedItemsAttribute”. + Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Typ {0} ma adnotacje walidacji, ale element członkowski {1} nie określa atrybutu [ValidateEnumeratedItems], co może być przeoczeniem. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. Member potentially missing enumerable validation. - W elemencie członkowskim może brakować walidacji możliwej do wyliczenia. + Member potentially missing enumerable validation. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Typ {0} ma adnotacje walidacji, ale element członkowski {1} nie określa atrybutu [ValidateObjectMembers], co może być przeoczeniem. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. Member potentially missing transitive validation. - W przypadku elementu członkowskiego może potencjalnie brakować weryfikacji przechodniej. + Member potentially missing transitive validation. Validator type {0} doesn't have a parameterless constructor. - Typ modułu sprawdzania poprawności {0} nie ma konstruktora bez parametrów. + Validator type {0} doesn't have a parameterless constructor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Moduły sprawdzania poprawności używane do weryfikacji przechodniej lub weryfikacji możliwej do wyliczenia muszą mieć konstruktora bez żadnych parametrów. + Validators used for transitive or enumerable validation must have a constructor with no parameters. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf index 4afa1d6763db8b..f62a1ef241e372 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf @@ -4,152 +4,162 @@ Type {0} already implements the Validate method. - O tipo {0} já implementa o método Validar. + Type {0} already implements the Validate method. A type already includes an implementation of the 'Validate' method. - Um tipo já inclui uma implementação do método "Validar". + A type already includes an implementation of the 'Validate' method. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] não pode ser aplicado à classe estática {0}. + [OptionsValidator] cannot be applied to static class {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - "OptionsValidatorAttribute" não pode ser aplicado a uma classe estática. + 'OptionsValidatorAttribute' can't be applied to a static class. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Não é possível usar [ValidateObjectMembers] ou [ValidateEnumeratedItems] em campos ou propriedades com o tipo genérico aberto {0}. + Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Não é possível usar "ValidateObjectMembersAttribute" ou "ValidateEnumeratedItemsAttribute" em campos ou propriedades com tipos genéricos abertos. + Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. Can't apply validation attributes to constant or static member {0}. - Não é possível aplicar atributos de validação a um membro constante ou estático {0}. + Can't apply validation attributes to constant or static member {0}. Can't validate constants, static fields or properties. - Não é possível validar constantes, campos estáticos ou propriedades. + Can't validate constants, static fields or properties. There is a circular type reference involving type {0} preventing it from being used for static validation. - Há uma referência de tipo circular que envolve o tipo {0} que a impede de ser usada para validação estática. + There is a circular type reference involving type {0} preventing it from being used for static validation. Unsupported circular references in model types. - Referências circulares sem suporte em tipos de modelo. + Unsupported circular references in model types. Type {0} does not implement the required IValidateOptions<{1}> interface. - O tipo {0} não implementa a interface IValidateOptions<{1}> necessária. + Type {0} does not implement the required IValidateOptions<{1}> interface. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - Um tipo anotado com "OptionsValidatorAttribute" não implementa a interface necessária. + A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - O atributo de validação '{0}' no membro '{1}' está inacessível do tipo de validador '{2}'. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. Validation attribute on the member is inaccessible from the validator type.. - O atributo de validação no membro está inacessível do tipo de validador. + Validation attribute on the member is inaccessible from the validator type.. Can't apply validation attributes to private field or property {0}. - Não é possível aplicar atributos de validação a um campo privado ou propriedade {0}. + Can't apply validation attributes to private field or property {0}. Can't validate private fields or properties. - Não é possível validar propriedades ou campos privados. + Can't validate private fields or properties. Type {0} has no fields or properties to validate, referenced from member {1}. - O tipo {0} não tem campos ou propriedades para validar, referenciados do membro {1}. + Type {0} has no fields or properties to validate, referenced from member {1}. A member type has no fields or properties to validate. - Um tipo de membro não tem campos ou propriedades a serem validados. + A member type has no fields or properties to validate. Type {0} has no fields or properties to validate, referenced by type {1}. - O tipo {0} não tem campos ou propriedades para validar, referenciados por tipo {1}. + Type {0} has no fields or properties to validate, referenced by type {1}. A type has no fields or properties to validate. - Um tipo não tem campos ou propriedades a serem validados. + A type has no fields or properties to validate. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] não pode ser usado em membros do tipo {0}, pois ele não implementa IEnumerable<T>. + [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. Member type is not enumerable. - O tipo de membro não é enumerável. + Member type is not enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Tipo de validador nulo especificado nos atributos [ValidateObjectMembers] ou [ValidateEnumeratedItems]. + Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Tipo de validador nulo especificado para os atributos "ValidateObjectMembersAttribute" ou "ValidateEnumeratedItemsAttribute". + Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - O tipo {0} tem anotações de validação, mas o membro {1} não especifica [ValidateEnumeratedItems], o que pode ser uma desatenção. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. Member potentially missing enumerable validation. - Membro potencialmente ausente na validação enumerável. + Member potentially missing enumerable validation. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - O tipo {0} tem anotações de validação, mas o membro {1} não especifica [ValidateObjectMembers], o que pode ser uma desatenção. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. Member potentially missing transitive validation. - Membro potencialmente ausente na validação transitiva. + Member potentially missing transitive validation. Validator type {0} doesn't have a parameterless constructor. - O tipo de validador {0} não tem um construtor sem parâmetros. + Validator type {0} doesn't have a parameterless constructor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Os validadores usados para validação transitiva ou enumerável devem ter um construtor sem parâmetros. + Validators used for transitive or enumerable validation must have a constructor with no parameters. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf index 02fb57d5497df9..b8069e4266ae37 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf @@ -4,152 +4,162 @@ Type {0} already implements the Validate method. - Тип {0} уже реализует метод Validate. + Type {0} already implements the Validate method. A type already includes an implementation of the 'Validate' method. - Тип уже содержит реализацию метода Validate. + A type already includes an implementation of the 'Validate' method. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] невозможно применить к статическому классу {0}. + [OptionsValidator] cannot be applied to static class {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - Параметр OptionsValidatorAttribute не может быть применен к статическому классу. + 'OptionsValidatorAttribute' can't be applied to a static class. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Нельзя использовать [ValidateObjectMembers] или [ValidateEnumeratedItems] для полей или свойств с открытыми универсальными типами {0}. + Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Нельзя использовать "ValidateObjectMembersAttribute" или "ValidateEnumeratedItemsAttribute" для полей или свойств с открытыми универсальными типами. + Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. Can't apply validation attributes to constant or static member {0}. - Не удалось применить атрибуты проверки к константе или статическому элементу {0}. + Can't apply validation attributes to constant or static member {0}. Can't validate constants, static fields or properties. - Не удалось проверить константы, статические поля или свойства. + Can't validate constants, static fields or properties. There is a circular type reference involving type {0} preventing it from being used for static validation. - Существует циклическая ссылка на тип, включающая тип {0}, предотвращающий его использование для статической проверки. + There is a circular type reference involving type {0} preventing it from being used for static validation. Unsupported circular references in model types. - Неподдерживаемые циклические ссылки в типах моделей. + Unsupported circular references in model types. Type {0} does not implement the required IValidateOptions<{1}> interface. - Тип {0} не реализует требуемый интерфейс IValidateOptions<{1}>. + Type {0} does not implement the required IValidateOptions<{1}> interface. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - Тип с аннотацией OptionsValidatorAttribute не реализует необходимый интерфейс. + A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Атрибут проверки "{0}" элемента "{1}" недоступен из типа средства проверки "{2}". + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. Validation attribute on the member is inaccessible from the validator type.. - Атрибут проверки элемента недоступен из типа средства проверки. + Validation attribute on the member is inaccessible from the validator type.. Can't apply validation attributes to private field or property {0}. - Не удается применить атрибуты проверки к закрытому полю или свойству {0}. + Can't apply validation attributes to private field or property {0}. Can't validate private fields or properties. - Не удается проверить частные поля или свойства. + Can't validate private fields or properties. Type {0} has no fields or properties to validate, referenced from member {1}. - Тип {0} не содержит полей или свойств для проверки, на которые ссылается из элемента {1}. + Type {0} has no fields or properties to validate, referenced from member {1}. A member type has no fields or properties to validate. - Тип элемента не имеет полей или свойств для проверки. + A member type has no fields or properties to validate. Type {0} has no fields or properties to validate, referenced by type {1}. - Тип {0} не содержит полей или свойств для проверки, на которые ссылается тип {1}. + Type {0} has no fields or properties to validate, referenced by type {1}. A type has no fields or properties to validate. - Тип не имеет полей или свойств для проверки. + A type has no fields or properties to validate. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] не может использоваться для элементов типа {0}, так как он не реализует IEnumerable<T>. + [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. Member type is not enumerable. - Тип элемента не является перечисляемым. + Member type is not enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Тип проверяющего элемента управления, указанный в [ValidateObjectMembers] или [ValidateEnumeratedItems] атрибутах, имеет значение NULL. + Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Для атрибутов ValidateObjectMembersAttribute или ValidateEnumeratedItemsAttribute указан тип проверяющего элемента управления NULL. + Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Тип {0} содержит примечания проверки, но элемент {1} не указывает [ValidateEnumeratedItems], который может быть задан. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. Member potentially missing enumerable validation. - Элемент потенциально пропускает перечисляемую проверку. + Member potentially missing enumerable validation. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Тип {0} содержит примечания проверки, но элемент {1} не указывает [ValidateObjectMembers], который может быть задан. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. Member potentially missing transitive validation. - Возможно, в элементе отсутствует транзитивная проверка. + Member potentially missing transitive validation. Validator type {0} doesn't have a parameterless constructor. - Тип проверяющего элемента управления {0} не имеет конструктора без параметров. + Validator type {0} doesn't have a parameterless constructor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - У проверяющих элементов управления, используемых для транзитивной или перечисляемой проверки, должен быть конструктор без параметров. + Validators used for transitive or enumerable validation must have a constructor with no parameters. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf index 6743baba13c804..8cb34b9b6f900a 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf @@ -4,152 +4,162 @@ Type {0} already implements the Validate method. - {0} türü Doğrulama yöntemini zaten uyguluyor. + Type {0} already implements the Validate method. A type already includes an implementation of the 'Validate' method. - Bir tür zaten 'Validate' yönteminin bir uygulamasını içeriyor. + A type already includes an implementation of the 'Validate' method. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator], {0} statik sınıfına uygulanamıyor. + [OptionsValidator] cannot be applied to static class {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' statik sınıfa uygulanamaz. + 'OptionsValidatorAttribute' can't be applied to a static class. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - {0} açık genel türündeki alanlarda veya özelliklerde [ValidateObjectMembers] veya [ValidateEnumeratedItems] kullanılamaz. + Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Açık genel türleri olan alanlarda veya özelliklerde 'ValidateObjectMembersAttribute' veya 'ValidateEnumeratedItemsAttribute' kullanılamaz. + Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. Can't apply validation attributes to constant or static member {0}. - Doğrulama öznitelikleri sabit veya statik üye {0} için geçerli değildir. + Can't apply validation attributes to constant or static member {0}. Can't validate constants, static fields or properties. - Sabitler, statik alanlar veya özellikler doğrulanamıyor. + Can't validate constants, static fields or properties. There is a circular type reference involving type {0} preventing it from being used for static validation. - Statik doğrulama için kullanılmasını engelleyen {0} türü içeren döngüsel bir tür başvurusu var. + There is a circular type reference involving type {0} preventing it from being used for static validation. Unsupported circular references in model types. - Model türlerde döngüsel başvurular desteklenmiyor. + Unsupported circular references in model types. Type {0} does not implement the required IValidateOptions<{1}> interface. - {0} türü gerekli IValidateOptions<{1}> arabirimini uygulamıyor. + Type {0} does not implement the required IValidateOptions<{1}> interface. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - 'OptionsValidatorAttribute' ile açıklama eklenmiş bir tür gerekli arabirimi uygulamıyor. + A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - '{1}' adlı üye üzerindeki '{0}' doğrulama özniteliğine '{2}' doğrulayıcı türünden erişilemiyor. + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. Validation attribute on the member is inaccessible from the validator type.. - Üye üzerindeki doğrulama özniteliğine doğrulayıcı türünden erişilemiyor. + Validation attribute on the member is inaccessible from the validator type.. Can't apply validation attributes to private field or property {0}. - Doğrulama öznitelikleri, {0} özel alanına veya özelliğine uygulanamıyor. + Can't apply validation attributes to private field or property {0}. Can't validate private fields or properties. - Özel alanlar veya özellikler doğrulanamıyor. + Can't validate private fields or properties. Type {0} has no fields or properties to validate, referenced from member {1}. - {0} türünde doğrulanacak alan veya özellik yok, {1} üyesinden başvurulur. + Type {0} has no fields or properties to validate, referenced from member {1}. A member type has no fields or properties to validate. - Üye türünde doğrulanacak alan veya özellik yok. + A member type has no fields or properties to validate. Type {0} has no fields or properties to validate, referenced by type {1}. - {0} türünde doğrulanacak alan veya özellik yok, {1} türü tarafından başvurulur. + Type {0} has no fields or properties to validate, referenced by type {1}. A type has no fields or properties to validate. - Türde doğrulanacak alan veya özellik yok. + A type has no fields or properties to validate. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems], IEnumerable<T> uygulamadığından {0} türündeki üyeler üzerinde kullanılamıyor. + [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. Member type is not enumerable. - Üye türü numaralandırılabilir değil. + Member type is not enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - [ValidateObjectMembers] veya [ValidateEnumeratedItems] özniteliklerinde null doğrulayıcı türü belirtildi. + Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - 'ValidateObjectMembersAttribute' veya 'ValidateEnumeratedItemsAttribute' öznitelikleri için null doğrulayıcı türü belirtildi. + Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - {0} türünde doğrulama ek açıklamaları var, ancak {1} üyesi gözden kaçmış olabilecek [ValidateEnumeratedItems] belirtmiyor. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. Member potentially missing enumerable validation. - Üyede numaralandırılabilir doğrulama eksik olabilir. + Member potentially missing enumerable validation. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - {0} türünde doğrulama ek açıklamaları var, ancak {1} üyesi gözden kaçmış olabilecek [ValidateObjectMembers] belirtmiyor. + Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. Member potentially missing transitive validation. - Üyede geçişli doğrulama eksik olabilir. + Member potentially missing transitive validation. Validator type {0} doesn't have a parameterless constructor. - {0} doğrulayıcı türü parametresiz bir oluşturucuya sahip değil. + Validator type {0} doesn't have a parameterless constructor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Geçişli veya numaralandırılabilir doğrulama için kullanılan doğrulayıcıların parametresi olmayan bir oluşturucusu olmalıdır. + Validators used for transitive or enumerable validation must have a constructor with no parameters. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf index cd68a3a773332b..707dcb36c697b0 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -4,152 +4,162 @@ Type {0} already implements the Validate method. - 类型 {0} 已实现 Validate 方法。 + Type {0} already implements the Validate method. A type already includes an implementation of the 'Validate' method. - 类型已包含“Validate”方法的实现。 + A type already includes an implementation of the 'Validate' method. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] 无法应用于静态类 {0}。 + [OptionsValidator] cannot be applied to static class {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - “OptionsValidatorAttribute”不能应用于静态类。 + 'OptionsValidatorAttribute' can't be applied to a static class. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - 不能对具有开放泛型类型 {0} 的字段或属性使用 [ValidateObjectMembers] 或 [ValidateEnumeratedItems]。 + Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - 不能对具有开放泛型类型的字段或属性使用 "ValidateObjectMembersAttribute" 或 "ValidateEnumeratedItemsAttribute"。 + Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. Can't apply validation attributes to constant or static member {0}. - 无法将验证属性应用于常量或静态成员 {0}。 + Can't apply validation attributes to constant or static member {0}. Can't validate constants, static fields or properties. - 无法验证常量、静态字段或属性。 + Can't validate constants, static fields or properties. There is a circular type reference involving type {0} preventing it from being used for static validation. - 存在一个循环类型引用,其中涉及的类型 {0} 阻止将其用于静态验证。 + There is a circular type reference involving type {0} preventing it from being used for static validation. Unsupported circular references in model types. - 模型类型中不支持的循环引用。 + Unsupported circular references in model types. Type {0} does not implement the required IValidateOptions<{1}> interface. - 类型 {0} 未实现所需的 IValidateOptions<{1}> 接口。 + Type {0} does not implement the required IValidateOptions<{1}> interface. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - 用 "OptionsValidatorAttribute" 批注的类型未实现必要的接口。 + A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - 无法从验证程序类型“{2}”访问成员“{1}”上的验证属性“{0}”。 + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. Validation attribute on the member is inaccessible from the validator type.. - 无法从验证程序类型访问成员上的验证属性。 + Validation attribute on the member is inaccessible from the validator type.. Can't apply validation attributes to private field or property {0}. - 无法将验证属性应用于专用字段或属性 {0}。 + Can't apply validation attributes to private field or property {0}. Can't validate private fields or properties. - 无法验证专用字段或属性。 + Can't validate private fields or properties. Type {0} has no fields or properties to validate, referenced from member {1}. - 类型 {0} 没有要验证的字段或属性,从成员 {1} 中引用。 + Type {0} has no fields or properties to validate, referenced from member {1}. A member type has no fields or properties to validate. - 成员类型没有要验证的字段或属性。 + A member type has no fields or properties to validate. Type {0} has no fields or properties to validate, referenced by type {1}. - 类型 {0} 没有要验证的字段或属性,由类型 {1} 引用。 + Type {0} has no fields or properties to validate, referenced by type {1}. A type has no fields or properties to validate. - 类型没有要验证的字段或属性。 + A type has no fields or properties to validate. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - 无法对类型 {0} 的成员使用 [ValidateEnumeratedItems],因为它未实现 IEnumerable<T>。 + [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. Member type is not enumerable. - 成员类型不可枚举。 + Member type is not enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - [ValidateObjectMembers] 或 [ValidateEnumeratedItems] 属性中指定的 Null 验证程序类型。 + Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - 为“ValidateObjectMembersAttribute”或“ValidateEnumeratedItemsAttribute”属性指定的验证程序类型为 Null。 + Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - 类型 {0} 具有验证注释,但成员 {1} 未指定 [ValidateEnumeratedItems],这可能是一种监督。 + Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. Member potentially missing enumerable validation. - 成员可能缺少可枚举验证。 + Member potentially missing enumerable validation. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - 类型 {0} 具有验证注释,但成员 {1} 未指定 [ValidateObjectMembers],这可能是一种监督。 + Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. Member potentially missing transitive validation. - 成员可能缺少可传递验证。 + Member potentially missing transitive validation. Validator type {0} doesn't have a parameterless constructor. - 验证程序类型 {0} 没有无参数构造函数。 + Validator type {0} doesn't have a parameterless constructor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - 用于可传递验证或可枚举验证的验证程序必须具有没有参数的构造函数。 + Validators used for transitive or enumerable validation must have a constructor with no parameters. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf index f21a748ed078e7..f8087186cb294b 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -4,152 +4,162 @@ Type {0} already implements the Validate method. - 類型 {0} 已實作 [驗證] 方法。 + Type {0} already implements the Validate method. A type already includes an implementation of the 'Validate' method. - 類型已經包含 [驗證] 方法的實作。 + A type already includes an implementation of the 'Validate' method. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] 無法套用至靜態類別 {0}。 + [OptionsValidator] cannot be applied to static class {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - 無法將 'OptionsValidatorAttribute' 套用至靜態類別。 + 'OptionsValidatorAttribute' can't be applied to a static class. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - 無法在有開放式泛型型別 {0} 的欄位或屬性上使用 [ValidateObjectMembers] 或 [ValidateEnumeratedItems]。 + Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - 無法在有開放式泛型型別的欄位或屬性上使用 'ValidateObjectMembersAttribute' 或 'ValidateEnumeratedItemsAttribute'。 + Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. Can't apply validation attributes to constant or static member {0}. - 無法將驗證屬性套用至常數或靜態成員 {0}。 + Can't apply validation attributes to constant or static member {0}. Can't validate constants, static fields or properties. - 無法驗證常數、靜態欄位或屬性。 + Can't validate constants, static fields or properties. There is a circular type reference involving type {0} preventing it from being used for static validation. - 有涉及類型 {0} 的循環類型參考讓它無法用於靜態驗證。 + There is a circular type reference involving type {0} preventing it from being used for static validation. Unsupported circular references in model types. - 模型類型中不支援的循環參考。 + Unsupported circular references in model types. Type {0} does not implement the required IValidateOptions<{1}> interface. - 類型 {0} 未實作必要的 IValidateOptions<{1}> 介面。 + Type {0} does not implement the required IValidateOptions<{1}> interface. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - 以 'OptionsValidatorAttribute' 附註的類型未實作必要的介面。 + A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - 無法從驗證程式類型 '{2}' 存取成員 '{1}' 上的驗證屬性 '{0}'。 + Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. Validation attribute on the member is inaccessible from the validator type.. - 無法從驗證程式類型存取成員上的驗證屬性。 + Validation attribute on the member is inaccessible from the validator type.. Can't apply validation attributes to private field or property {0}. - 無法將驗證屬性套用至私用欄位或屬性 {0}。 + Can't apply validation attributes to private field or property {0}. Can't validate private fields or properties. - 無法驗證私人欄位或屬性。 + Can't validate private fields or properties. Type {0} has no fields or properties to validate, referenced from member {1}. - 參照會員 {1},類型 {0} 沒有欄位或屬性可供驗證。 + Type {0} has no fields or properties to validate, referenced from member {1}. A member type has no fields or properties to validate. - 成員類型沒有欄位或屬性可供驗證。 + A member type has no fields or properties to validate. Type {0} has no fields or properties to validate, referenced by type {1}. - 參照類型 {1},類型 {0} 沒有欄位或屬性可供驗證。 + Type {0} has no fields or properties to validate, referenced by type {1}. A type has no fields or properties to validate. - 類型沒有欄位或屬性可供驗證。 + A type has no fields or properties to validate. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] 無法用於類型 {0} 的成員,因為其未實作 IEnumerable<T>。 + [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. Member type is not enumerable. - 成員類型無法列舉。 + Member type is not enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - [ValidateObjectMembers] 或 [ValidateEnumeratedItems] 屬性中指定的 Null 驗證程式類型。 + Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - 為 'ValidateObjectMembersAttribute' 或 'ValidateEnumeratedItemsAttribute' 屬性指定的 Null 驗證程式類型。 + Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + + + C# language version not supported by the source generator. + C# language version not supported by the source generator. Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - 成員 {0} 具備驗證註釋,但成員 {1} 未指定 [ValidateObjectMembers] (可能為監督)。 + Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. Member potentially missing enumerable validation. - 成員可能遺漏可列舉的驗證。 + Member potentially missing enumerable validation. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - 類型 {0} 具備驗證註釋,但成員 {1} 未指定 [ValidateObjectMembers] (可能為監督)。 + Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. Member potentially missing transitive validation. - 成員可能遺漏轉移的驗證。 + Member potentially missing transitive validation. Validator type {0} doesn't have a parameterless constructor. - 驗證程式類型 {0} 沒有無參數建構函式。 + Validator type {0} doesn't have a parameterless constructor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - 用於轉移或可列舉驗證的驗證程式必須具備沒有參數的建構函式。 + Validators used for transitive or enumerable validation must have a constructor with no parameters. diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs index b243ee50f361d9..f3e0513a885f22 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs @@ -1582,6 +1582,63 @@ public partial class FirstValidator : IValidateOptions Assert.Equal(DiagDescriptors.NotEnumerableType.Id, diagnostics[0].Id); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + public async Task LanguageVersionTest() + { + string source = """ + using System; + using System.ComponentModel.DataAnnotations; + using Microsoft.Extensions.Options; + + public class FirstModel + { + [Required] + public string? P1 { get; set; } + } + + [OptionsValidator] + public partial class FirstModelValidator : IValidateOptions + { + } + """; + + Assembly [] refAssemblies = new [] + { + Assembly.GetAssembly(typeof(RequiredAttribute)), + Assembly.GetAssembly(typeof(OptionsValidatorAttribute)), + Assembly.GetAssembly(typeof(IValidateOptions)), + }; + + // Run the generator with C# 7.0 and verify that it fails. + var (diagnostics, generatedSources) = await RoslynTestUtils.RunGenerator( + new Generator(), refAssemblies.ToArray(), new[] { source }, includeBaseReferences: true, LanguageVersion.CSharp7).ConfigureAwait(false); + + Assert.NotEmpty(diagnostics); + Assert.Equal("SYSLIB1216", diagnostics[0].Id); + Assert.Empty(generatedSources); + + // Run the generator with C# 8.0 and verify that it succeeds. + (diagnostics, generatedSources) = await RoslynTestUtils.RunGenerator( + new Generator(), refAssemblies.ToArray(), new[] { source }, includeBaseReferences: true, LanguageVersion.CSharp8).ConfigureAwait(false); + + Assert.Empty(diagnostics); + Assert.Single(generatedSources); + + // Compile the generated code with C# 7.0 and verify that it fails. + CSharpParseOptions parseOptions = new CSharpParseOptions(LanguageVersion.CSharp7); + SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(generatedSources[0].SourceText.ToString(), parseOptions); + var diags = syntaxTree.GetDiagnostics().ToArray(); + Assert.Equal(1, diags.Length); + // error CS8107: Feature 'nullable reference types' is not available in C# 7.0. Please use language version 8.0 or greater. + Assert.Equal("CS8107", diags[0].Id); + + // Compile the generated code with C# 8.0 and verify that it succeeds. + parseOptions = new CSharpParseOptions(LanguageVersion.CSharp8); + syntaxTree = SyntaxFactory.ParseSyntaxTree(generatedSources[0].SourceText.ToString(), parseOptions); + diags = syntaxTree.GetDiagnostics().ToArray(); + Assert.Equal(0, diags.Length); + } + private static CSharpCompilation CreateCompilationForOptionsSource(string assemblyName, string source, string? refAssemblyPath = null) { // Ensure the generated source compiles diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Resources/Strings.resx index c6d9021ea99672..6b8167e94b119a 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Resources/Strings.resx @@ -210,4 +210,10 @@ Validation attribute on the member is inaccessible from the validator type.. + + C# language version not supported by the source generator. + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Resources/Strings.resx index c6d9021ea99672..6b8167e94b119a 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Resources/Strings.resx @@ -210,4 +210,10 @@ Validation attribute on the member is inaccessible from the validator type.. + + C# language version not supported by the source generator. + + + The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + \ No newline at end of file diff --git a/src/libraries/System.Text.Json/gen/Resources/Strings.resx b/src/libraries/System.Text.Json/gen/Resources/Strings.resx index 85d64b685f023d..519cbffa3ec09a 100644 --- a/src/libraries/System.Text.Json/gen/Resources/Strings.resx +++ b/src/libraries/System.Text.Json/gen/Resources/Strings.resx @@ -1,17 +1,17 @@ - @@ -193,7 +193,7 @@ C# language version not supported by the source generator. - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. Constructor annotated with JsonConstructorAttribute is inaccessible. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.cs.xlf index cc88af350de1e5..41ce7674876442 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.cs.xlf @@ -113,8 +113,8 @@ - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. - Zdrojový generátor System.Text.Json není k dispozici v jazyce C#{0}. Použijte prosím jazykovou verzi {1} nebo vyšší. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + Zdrojový generátor System.Text.Json není k dispozici v jazyce C#{0}. Použijte prosím jazykovou verzi {1} nebo vyšší. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.de.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.de.xlf index d23d07843bb212..a0b49aa02c03f3 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.de.xlf @@ -113,8 +113,8 @@ - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. - Der System.Text.Json-Quellgenerator ist in C# „{0}“ nicht verfügbar. Verwenden Sie die Sprachversion {1} oder höher. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + Der System.Text.Json-Quellgenerator ist in C# „{0}“ nicht verfügbar. Verwenden Sie die Sprachversion {1} oder höher. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.es.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.es.xlf index 989c5a8a02f263..bdd7876fa38cd3 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.es.xlf @@ -113,8 +113,8 @@ - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. - El generador de origen System.Text.Json no está disponible en C# '{0}'. Use la versión de idioma {1} o superior. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + El generador de origen System.Text.Json no está disponible en C# '{0}'. Use la versión de idioma {1} o superior. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.fr.xlf index 4e1998a8f6e376..4b93e17edd6eb6 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.fr.xlf @@ -113,8 +113,8 @@ - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. - Le générateur de source System.Text.Json n'est pas disponible en C# '{0}'. Veuillez utiliser la version linguistique {1} ou supérieure. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + Le générateur de source System.Text.Json n'est pas disponible en C# '{0}'. Veuillez utiliser la version linguistique {1} ou supérieure. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.it.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.it.xlf index 5cb68b207cab19..cb163ff94ec4f9 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.it.xlf @@ -113,8 +113,8 @@ - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. - Il generatore di origine System.Text.Json non è disponibile in C# '{0}'. Usare la versione del linguaggio {1} o successiva. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + Il generatore di origine System.Text.Json non è disponibile in C# '{0}'. Usare la versione del linguaggio {1} o successiva. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ja.xlf index a25a901571f489..9e3366a8bf09a2 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ja.xlf @@ -113,8 +113,8 @@ - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. - System.Text.Json ソース ジェネレーターは C# '{0}' では使用できません。言語バージョン {1} 以上を使用してください。 + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + System.Text.Json ソース ジェネレーターは C# '{0}' では使用できません。言語バージョン {1} 以上を使用してください。 diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ko.xlf index dec5ff53a5aa12..735e6d772f7c26 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ko.xlf @@ -113,8 +113,8 @@ - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. - System.Text.Json 원본 생성기는 C# '{0}'에서 사용할 수 없습니다. {1} 이상의 언어 버전을 사용하세요. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + System.Text.Json 원본 생성기는 C# '{0}'에서 사용할 수 없습니다. {1} 이상의 언어 버전을 사용하세요. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pl.xlf index bb1a603dbaf458..8282fa16aa908b 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pl.xlf @@ -113,8 +113,8 @@ - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. - Generator źródła System.Text.Json nie jest dostępny w języku C# „{0}”. Użyj wersji językowej lub nowszej {1} . + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + Generator źródła System.Text.Json nie jest dostępny w języku C# „{0}”. Użyj wersji językowej lub nowszej {1} . diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pt-BR.xlf index a4cb21e691b5dd..030a3f3302e729 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pt-BR.xlf @@ -113,8 +113,8 @@ - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. - O gerador de fonte System.Text.Json não está disponível em C# '{0}'. Use a versão do idioma {1} ou superior. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + O gerador de fonte System.Text.Json não está disponível em C# '{0}'. Use a versão do idioma {1} ou superior. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ru.xlf index d1c3241bc43f22..556fa665267f30 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ru.xlf @@ -113,8 +113,8 @@ - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. - Генератор исходного кода System.Text.Json не доступен в C# "{0}". Используйте языковую версию {1} или выше. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + Генератор исходного кода System.Text.Json не доступен в C# "{0}". Используйте языковую версию {1} или выше. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.tr.xlf index 72b706fdc31a64..e74d8818167e3d 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.tr.xlf @@ -113,8 +113,8 @@ - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. - System.Text.Json kaynak oluşturucusu C# '{0}' içinde kullanılamıyor. Lütfen dil sürümü {1} veya üstü sürümü kullanın. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + System.Text.Json kaynak oluşturucusu C# '{0}' içinde kullanılamıyor. Lütfen dil sürümü {1} veya üstü sürümü kullanın. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hans.xlf index 3450d312816e01..3ac4929b2b76dd 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -113,8 +113,8 @@ - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. - System.Text.Json 源生成器在 C#“{0}”中不可用。请使用{1}或更高版本的语言版本。 + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + System.Text.Json 源生成器在 C#“{0}”中不可用。请使用{1}或更高版本的语言版本。 diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hant.xlf index 176989f5fc53a6..a194d8afc278d7 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -113,8 +113,8 @@ - The System.Text.Json source generator is not available in C# '{0}'. Please use language version {1} or greater. - C# '{0}' 中無法使用 System.Text.Json 來源產生器。請使用 {1} 或更新的語言版本。 + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + C# '{0}' 中無法使用 System.Text.Json 來源產生器。請使用 {1} 或更新的語言版本。 diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorDiagnosticsTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorDiagnosticsTests.cs index 98f2b71042332b..a554d2681d43d1 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorDiagnosticsTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorDiagnosticsTests.cs @@ -416,7 +416,7 @@ public void SupportedLanguageVersions_SucceedCompilation(LanguageVersion langVer using System.Text.Json.Serialization; namespace HelloWorld - { + { public class MyClass { public MyClass(int value) @@ -457,7 +457,7 @@ public void SupportedLanguageVersions_Memory_SucceedCompilation(LanguageVersion using System.Text.Json.Serialization; namespace HelloWorld - { + { public class MyClass { public MyClass( @@ -504,7 +504,7 @@ public void UnsupportedLanguageVersions_FailCompilation(LanguageVersion langVers using System.Text.Json.Serialization; namespace HelloWorld - { + { public class MyClass { public MyClass(int value) @@ -531,7 +531,7 @@ public partial class MyJsonContext : JsonSerializerContext var expectedDiagnostics = new DiagnosticData[] { - new(DiagnosticSeverity.Error, contextLocation, $"The System.Text.Json source generator is not available in C# '{langVersion.ToDisplayString()}'. Please use language version 9.0 or greater.") + new(DiagnosticSeverity.Error, contextLocation, $"The System.Text.Json source generator is not available in C# {langVersion.ToDisplayString()}. Please use language version 9.0 or greater.") }; CompilationHelper.AssertEqualDiagnosticMessages(expectedDiagnostics, result.Diagnostics); From 52f3d10d7938e8748a43b25f69a4e6795e72822c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 11:11:07 -0700 Subject: [PATCH 040/783] Make DacValidateMD and DacValidateMethodTable more resilient (#90797) Make both methods more resilient to the case of invalid MethodDesc and MethodTable with value -1. Close #90691 Co-authored-by: Jan Vorlicek --- src/coreclr/debug/daccess/request.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp index 868593fae4651e..114900ffaf0365 100644 --- a/src/coreclr/debug/daccess/request.cpp +++ b/src/coreclr/debug/daccess/request.cpp @@ -135,11 +135,17 @@ BOOL DacValidateEEClass(PTR_EEClass pEEClass) BOOL DacValidateMethodTable(PTR_MethodTable pMT, BOOL &bIsFree) { + bIsFree = FALSE; + + if ((pMT == NULL) || dac_cast(pMT) == (TADDR)-1) + { + return FALSE; + } + // Verify things are right. BOOL retval = FALSE; EX_TRY { - bIsFree = FALSE; if (HOST_CDADDR(pMT) == HOST_CDADDR(g_pFreeObjectMethodTable)) { bIsFree = TRUE; @@ -182,7 +188,7 @@ BadMethodTable: ; BOOL DacValidateMD(PTR_MethodDesc pMD) { - if (pMD == NULL) + if ((pMD == NULL) || dac_cast(pMD) == (TADDR)-1) { return FALSE; } From 20d508bf9597c73a063eec535bcb2fd5cabc7837 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 12:50:30 -0700 Subject: [PATCH 041/783] [release/8.0-rc1] [wasm] Do not build mono libs with `-msimd128` (#90750) * [wasm] Do not build mono libs with `-msimd128` Make it optional, build only minimal set of code witch required `-msimd128` to separate library. Also provide "stub" nosimd version of this library. Choose the appropriate library during linking. * Fix build * Fix build of non-wasm platforms * Add simd options for wasi * Fix wasi build --------- Co-authored-by: Radek Doulik Co-authored-by: Larry Ewing --- .../Directory.Build.props | 2 ++ src/mono/CMakeLists.txt | 8 ----- src/mono/mono.proj | 6 ++++ src/mono/mono/mini/CMakeLists.txt | 25 +++++++++++++-- src/mono/mono/mini/interp/interp-nosimd.c | 31 +++++++++++++++++++ src/mono/mono/mini/interp/interp-simd.c | 2 ++ src/mono/mono/mini/interp/interp-simd.h | 2 ++ src/mono/mono/mini/interp/transform-simd.c | 4 +++ src/mono/wasi/build/WasiApp.Native.targets | 6 ++++ src/mono/wasi/runtime/CMakeLists.txt | 1 + src/mono/wasi/wasi.proj | 2 ++ src/mono/wasm/build/WasmApp.Native.targets | 6 ++++ src/mono/wasm/runtime/CMakeLists.txt | 1 + src/mono/wasm/wasm.proj | 3 +- 14 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 src/mono/mono/mini/interp/interp-nosimd.c diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props index 13cf1fc895c8ac..5a96f57519aaf8 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -197,6 +197,8 @@ + + diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index 66e92d80564363..a57cc52b0b110b 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -242,14 +242,6 @@ elseif(CLR_CMAKE_HOST_OS STREQUAL "emscripten") add_compile_options(-Wno-strict-prototypes) add_compile_options(-Wno-unused-but-set-variable) add_compile_options(-Wno-single-bit-bitfield-constant-conversion) - # Allow using WASM simd intrinsics in the interpreter - add_compile_options(-msimd128) - # Disable autovectorization (it is automatically turned on by msimd128) - add_compile_options(-disable-loop-vectorization) - add_compile_options(-disable-vectorization) - add_compile_options(-fno-vectorize) - add_compile_options(-fno-tree-vectorize) - add_compile_options(-fno-slp-vectorize) set(DISABLE_EXECUTABLES 1) # FIXME: Is there a cmake option for this ? set(DISABLE_SHARED_LIBS 1) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index cf99f325ea5565..6be683f8e2eb2c 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -1061,6 +1061,12 @@ <_MonoRuntimeArtifacts Condition="'$(TargetsBrowser)' == 'true' and '$(BuildMonoAOTCrossCompilerOnly)' != 'true'" Include="$(MonoObjDir)out\lib\libmono-wasm-eh-wasm.a"> $(RuntimeBinDir)libmono-wasm-eh-wasm.a + <_MonoRuntimeArtifacts Condition="('$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true') and '$(BuildMonoAOTCrossCompilerOnly)' != 'true'" Include="$(MonoObjDir)out\lib\libmono-wasm-simd.a"> + $(RuntimeBinDir)libmono-wasm-simd.a + + <_MonoRuntimeArtifacts Condition="('$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true') and '$(BuildMonoAOTCrossCompilerOnly)' != 'true'" Include="$(MonoObjDir)out\lib\libmono-wasm-nosimd.a"> + $(RuntimeBinDir)libmono-wasm-nosimd.a + <_MonoICorDebugArtifacts Condition="'$(MonoMsCorDbi)' == 'true'" Include="$(MonoObjDir)out\lib\$(LibPrefix)mscordbi$(LibSuffix)"> $(RuntimeBinDir)$(LibPrefix)mscordbi$(LibSuffix) diff --git a/src/mono/mono/mini/CMakeLists.txt b/src/mono/mono/mini/CMakeLists.txt index 884b43c1b1eec4..5d6ef3dfa3c31e 100644 --- a/src/mono/mono/mini/CMakeLists.txt +++ b/src/mono/mono/mini/CMakeLists.txt @@ -288,7 +288,6 @@ set(interp_sources interp/interp.h interp/interp-internals.h interp/interp.c - interp/interp-simd.c interp/interp-intrins.h interp/interp-intrins.c interp/mintops.h @@ -297,11 +296,17 @@ set(interp_sources interp/tiering.h interp/tiering.c interp/jiterpreter.c) +set(interp_simd_sources + interp/interp-simd.c) set(interp_stub_sources interp-stubs.c) if(NOT DISABLE_INTERPRETER) -set(mini_interp_sources ${interp_sources}) + if(HOST_WASM) + set(mini_interp_sources ${interp_sources}) + else() + set(mini_interp_sources ${interp_sources} ${interp_simd_sources}) + endif() else() set(mini_interp_sources ${interp_stub_sources}) endif() @@ -504,6 +509,19 @@ if(HOST_BROWSER) install(TARGETS mono-wasm-eh-wasm LIBRARY) endif() +if(HOST_BROWSER OR HOST_WASI) + add_library(mono-wasm-simd STATIC interp/interp-simd.c) + target_link_libraries (mono-wasm-simd PRIVATE monoapi eglib_api) + set_target_properties(mono-wasm-simd PROPERTIES COMPILE_FLAGS "-msimd128") + install(TARGETS mono-wasm-simd LIBRARY) +endif() + +if(HOST_BROWSER OR HOST_WASI OR TARGET_WASM) + add_library(mono-wasm-nosimd STATIC interp/interp-nosimd.c) + target_link_libraries (mono-wasm-nosimd PRIVATE monoapi eglib_api) + install(TARGETS mono-wasm-nosimd LIBRARY) +endif() + find_package(Python3 COMPONENTS Interpreter) add_custom_command( @@ -576,6 +594,9 @@ if(NOT DISABLE_EXECUTABLES) endif() endif() target_link_libraries(mono-sgen PRIVATE monoapi eglib_api monosgen-static) + if (HOST_WASM) + target_link_libraries(mono-sgen PRIVATE mono-wasm-nosimd) + endif() if(HAVE_ICU_SHIM) target_link_libraries(mono-sgen PRIVATE icu_shim_objects) endif() diff --git a/src/mono/mono/mini/interp/interp-nosimd.c b/src/mono/mono/mini/interp/interp-nosimd.c new file mode 100644 index 00000000000000..63bcf2783ec087 --- /dev/null +++ b/src/mono/mono/mini/interp/interp-nosimd.c @@ -0,0 +1,31 @@ + +#include "interp-internals.h" +#include "interp-simd.h" + +#ifdef INTERP_ENABLE_SIMD + +gboolean interp_simd_enabled = FALSE; + +#ifdef HOST_BROWSER + +int interp_simd_p_p_wasm_opcode_table [] = { +}; + +int interp_simd_p_pp_wasm_opcode_table [] = { +}; + +int interp_simd_p_ppp_wasm_opcode_table [] = { +}; + +#endif // HOST_BROWSER + +PP_SIMD_Method interp_simd_p_p_table [] = { +}; + +PPP_SIMD_Method interp_simd_p_pp_table [] = { +}; + +PPPP_SIMD_Method interp_simd_p_ppp_table [] = { +}; + +#endif // INTERP_ENABLE_SIMD diff --git a/src/mono/mono/mini/interp/interp-simd.c b/src/mono/mono/mini/interp/interp-simd.c index 65e60b4c6e7017..5031c87aaf206b 100644 --- a/src/mono/mono/mini/interp/interp-simd.c +++ b/src/mono/mono/mini/interp/interp-simd.c @@ -8,6 +8,8 @@ #ifdef INTERP_ENABLE_SIMD +gboolean interp_simd_enabled = TRUE; + typedef gint64 v128_i8 __attribute__ ((vector_size (SIZEOF_V128))); typedef guint64 v128_u8 __attribute__ ((vector_size (SIZEOF_V128))); typedef gint32 v128_i4 __attribute__ ((vector_size (SIZEOF_V128))); diff --git a/src/mono/mono/mini/interp/interp-simd.h b/src/mono/mono/mini/interp/interp-simd.h index e3306a251fc9f6..8e0222613e44a2 100644 --- a/src/mono/mono/mini/interp/interp-simd.h +++ b/src/mono/mono/mini/interp/interp-simd.h @@ -3,6 +3,8 @@ #include +extern gboolean interp_simd_enabled; + typedef void (*PP_SIMD_Method) (gpointer, gpointer); typedef void (*PPP_SIMD_Method) (gpointer, gpointer, gpointer); typedef void (*PPPP_SIMD_Method) (gpointer, gpointer, gpointer, gpointer); diff --git a/src/mono/mono/mini/interp/transform-simd.c b/src/mono/mono/mini/interp/transform-simd.c index 255a2aba595634..7df7f92ab6d7c0 100644 --- a/src/mono/mono/mini/interp/transform-simd.c +++ b/src/mono/mono/mini/interp/transform-simd.c @@ -3,6 +3,7 @@ */ #include "config.h" +#include "interp-simd.h" #include #include #include @@ -900,6 +901,9 @@ interp_emit_simd_intrinsics (TransformData *td, MonoMethod *cmethod, MonoMethodS if (image != mono_get_corlib ()) return FALSE; + if (!interp_simd_enabled) + return FALSE; + class_ns = m_class_get_name_space (cmethod->klass); class_name = m_class_get_name (cmethod->klass); diff --git a/src/mono/wasi/build/WasiApp.Native.targets b/src/mono/wasi/build/WasiApp.Native.targets index 36c66585870a2c..ba9c085924d46a 100644 --- a/src/mono/wasi/build/WasiApp.Native.targets +++ b/src/mono/wasi/build/WasiApp.Native.targets @@ -273,6 +273,10 @@ <_WasmEHLibToExclude Condition="'$(WasmEnableExceptionHandling)' != 'true'">libmono-wasm-eh-wasm.a + <_WasmSIMDLib Condition="'$(WasmEnableSIMD)' == 'true'">libmono-wasm-simd.a + <_WasmSIMDLib Condition="'$(WasmEnableSIMD)' != 'true'">libmono-wasm-nosimd.a + <_WasmSIMDLibToExclude Condition="'$(WasmEnableSIMD)' != 'true'">libmono-wasm-simd.a + <_WasmSIMDLibToExclude Condition="'$(WasmEnableSIMD)' == 'true'">libmono-wasm-nosimd.a @@ -286,7 +290,9 @@ Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)*.a" Exclude="@(_MonoRuntimeComponentDontLink->'$(MicrosoftNetCoreAppRuntimePackRidNativeDir)%(Identity)')" /> <_WasmNativeFileForLinking Condition="'$(_WasmEHLib)' != ''" Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(_WasmEHLib)" /> + <_WasmNativeFileForLinking Condition="'$(_WasmSIMDLib)' != ''" Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(_WasmSIMDLib)" /> <_WasmNativeFileForLinking Remove="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(_WasmEHLibToExclude)" /> + <_WasmNativeFileForLinking Remove="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(_WasmSIMDLibToExclude)" /> <_WasmNativeFileForLinking Include="$(WasiSysRoot)\lib\wasm32-wasi\libc++.a" /> <_WasmNativeFileForLinking Include="$(WasiSysRoot)\lib\wasm32-wasi\libc++abi.a" /> diff --git a/src/mono/wasi/runtime/CMakeLists.txt b/src/mono/wasi/runtime/CMakeLists.txt index ede21d72193f6c..912132b06ccfb0 100644 --- a/src/mono/wasi/runtime/CMakeLists.txt +++ b/src/mono/wasi/runtime/CMakeLists.txt @@ -26,6 +26,7 @@ target_link_libraries(dotnet ${MONO_ARTIFACTS_DIR}/libmono-ee-interp.a ${MONO_ARTIFACTS_DIR}/libmonosgen-2.0.a ${MONO_ARTIFACTS_DIR}/libmono-icall-table.a + ${MONO_ARTIFACTS_DIR}/libmono-wasm-${CONFIGURATION_INTERPSIMDTABLES_LIB}.a ${NATIVE_BIN_DIR}/wasm-bundled-timezones.a ${NATIVE_BIN_DIR}/libSystem.Native.a ${NATIVE_BIN_DIR}/libSystem.Globalization.Native.a diff --git a/src/mono/wasi/wasi.proj b/src/mono/wasi/wasi.proj index 611d7969f034b8..b942b6f4925035 100644 --- a/src/mono/wasi/wasi.proj +++ b/src/mono/wasi/wasi.proj @@ -218,6 +218,8 @@ $(CMakeBuildRuntimeConfigureCmd) -DICU_LIB_DIR="$(ICULibDir.TrimEnd('\/'))" $(CMakeBuildRuntimeConfigureCmd) -DMONO_ARTIFACTS_DIR="$(MonoArtifactsPath.TrimEnd('\/'))" $(CMakeBuildRuntimeConfigureCmd) -DNATIVE_BIN_DIR="$(NativeBinDir.TrimEnd('\/'))" + $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_COMPILE_OPTIONS="-msimd128" -DCONFIGURATION_INTERPSIMDTABLES_LIB="simd" + $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_INTERPSIMDTABLES_LIB="nosimd" $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_THREADS=0 call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" wasm && $(CMakeBuildRuntimeConfigureCmd) diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index 52125a8bd00b00..7060397f0cb85c 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -440,6 +440,10 @@ <_WasmEHLib Condition="'$(WasmEnableExceptionHandling)' != 'true'">libmono-wasm-eh-js.a <_WasmEHLibToExclude Condition="'$(WasmEnableExceptionHandling)' == 'true'">libmono-wasm-eh-js.a <_WasmEHLibToExclude Condition="'$(WasmEnableExceptionHandling)' != 'true'">libmono-wasm-eh-wasm.a + <_WasmSIMDLib Condition="'$(WasmEnableSIMD)' == 'true'">libmono-wasm-simd.a + <_WasmSIMDLib Condition="'$(WasmEnableSIMD)' != 'true'">libmono-wasm-nosimd.a + <_WasmSIMDLibToExclude Condition="'$(WasmEnableSIMD)' != 'true'">libmono-wasm-simd.a + <_WasmSIMDLibToExclude Condition="'$(WasmEnableSIMD)' == 'true'">libmono-wasm-nosimd.a <_EmccExportedLibraryFunction>"[@(EmccExportedLibraryFunction -> '%27%(Identity)%27', ',')]" <_EmccExportedRuntimeMethods>"[@(EmccExportedRuntimeMethod -> '%27%(Identity)%27', ',')]" <_EmccExportedFunctions>@(EmccExportedFunction -> '%(Identity)',',') @@ -460,7 +464,9 @@ Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)*.a" Exclude="@(_MonoRuntimeComponentDontLink->'$(MicrosoftNetCoreAppRuntimePackRidNativeDir)%(Identity)')" /> <_WasmNativeFileForLinking Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(_WasmEHLib)" /> + <_WasmNativeFileForLinking Condition="'$(_WasmSIMDLib)' != ''" Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(_WasmSIMDLib)" /> <_WasmNativeFileForLinking Remove="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(_WasmEHLibToExclude)" /> + <_WasmNativeFileForLinking Remove="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(_WasmSIMDLibToExclude)" /> <_WasmExtraJSFile Include="@(Content)" Condition="'%(Content.Extension)' == '.js'" /> diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt index 6b8ef873ec27da..6d939088d74314 100644 --- a/src/mono/wasm/runtime/CMakeLists.txt +++ b/src/mono/wasm/runtime/CMakeLists.txt @@ -25,6 +25,7 @@ target_link_libraries(dotnet.native ${MONO_ARTIFACTS_DIR}/libmonosgen-2.0.a ${MONO_ARTIFACTS_DIR}/libmono-icall-table.a ${MONO_ARTIFACTS_DIR}/libmono-wasm-eh-js.a + ${MONO_ARTIFACTS_DIR}/libmono-wasm-${CONFIGURATION_INTERPSIMDTABLES_LIB}.a ${MONO_ARTIFACTS_DIR}/libmono-profiler-aot.a ${MONO_ARTIFACTS_DIR}/libmono-profiler-browser.a ${NATIVE_BIN_DIR}/wasm-bundled-timezones.a diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index c46c92ab70db70..66bc509910571a 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -388,7 +388,8 @@ $(CMakeBuildRuntimeConfigureCmd) -DICU_LIB_DIR="$(ICULibDir.TrimEnd('\/').Replace('\','/'))" $(CMakeBuildRuntimeConfigureCmd) -DMONO_ARTIFACTS_DIR="$(MonoArtifactsPath.TrimEnd('\/').Replace('\','/'))" $(CMakeBuildRuntimeConfigureCmd) -DNATIVE_BIN_DIR="$(NativeBinDir.TrimEnd('\/').Replace('\','/'))" - $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_COMPILE_OPTIONS="-msimd128" + $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_COMPILE_OPTIONS="-msimd128" -DCONFIGURATION_INTERPSIMDTABLES_LIB="simd" + $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_INTERPSIMDTABLES_LIB="nosimd" $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_THREADS=0 $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_LEGACY_JS_INTEROP=1 $(CMakeBuildRuntimeConfigureCmd) $(CMakeConfigurationEmsdkPath) From 92d1962d546e60172d69ecfda9e8c34123896732 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 13:04:51 -0700 Subject: [PATCH 042/783] Disable BinderTracingTest.ResolutionFlow test (#90818) Tracking: #90580 Co-authored-by: Bruce Forstall --- src/tests/issues.targets | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 87f8bbf2673dd3..22178e4b3b506d 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -63,6 +63,9 @@ https://github.com/dotnet/runtime/issues/57786 + + https://github.com/dotnet/runtime/issues/90580 + CoreCLR does not implement the mono embedding API From 90b92bb265a412592c4c152983d7b30c92236dbe Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 17:06:10 -0700 Subject: [PATCH 043/783] run nightlies against release/8.0 (#90809) Co-authored-by: antonfirsov --- eng/pipelines/libraries/stress/http.yml | 1 + eng/pipelines/libraries/stress/ssl.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/eng/pipelines/libraries/stress/http.yml b/eng/pipelines/libraries/stress/http.yml index 6c740e49d04d47..f4f9c45de36e48 100644 --- a/eng/pipelines/libraries/stress/http.yml +++ b/eng/pipelines/libraries/stress/http.yml @@ -13,6 +13,7 @@ schedules: - main - release/6.0 - release/7.0 + - release/8.0 variables: - template: ../variables.yml diff --git a/eng/pipelines/libraries/stress/ssl.yml b/eng/pipelines/libraries/stress/ssl.yml index 791251030f5753..ab93994400d346 100644 --- a/eng/pipelines/libraries/stress/ssl.yml +++ b/eng/pipelines/libraries/stress/ssl.yml @@ -13,6 +13,7 @@ schedules: - main - release/6.0 - release/7.0 + - release/8.0 variables: - template: ../variables.yml From f8e2a9b9beccddae9f0838dd7a1bdcc3f994777e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 18:17:18 -0700 Subject: [PATCH 044/783] Enable telemetry for WasmStripILAfterAOT (#90827) Co-authored-by: Fan Yang --- .../WorkloadTelemetry.targets | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets index 8f78ce16b62587..cf97ec1f14c2af 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadTelemetry.targets @@ -19,6 +19,7 @@ + @@ -35,6 +36,7 @@ <_WorkloadUsesInterpreter Condition="'$(_WorkloadUsesInterpreter)' == '' and '$(UseInterpreter)' == 'true'">true <_WorkloadUsesInterpreter Condition="'$(_WorkloadUsesInterpreter)' == '' and '$(RunAOTCompilation)' != 'true' and ('$(_WorkloadUsesBlazorWasm)' == 'true' or '$(_WorkloadUsesWasmSDK)' == 'true')">true <_WorkloadUsesLibraryMode Condition="'$(NativeLib)' != '' and ('$(_WorkloadUsesMonoAOT)' == 'true' or '$(_WorkloadUsesNativeAOT)' == 'true')">true + <_WorkloadUsesWasmStripILAfterAOT Condition="'$(WasmStripILAfterAOT)' == 'true'">true From 6aef01d5aae9dc0cd88c876a642cb06e4fcaafc4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 19:33:12 -0700 Subject: [PATCH 045/783] [release/8.0-rc1] [mini] Fix typo in mono_decompose_vtype_opts (#90832) * Fix typo in mono_decompose_vtype_opts Without this, if some previous instruction already created a vreg for ins->dest (for example if we are doing multiple passes over the basic block because `restart == TRUE`) we will use an incorrect vreg when decomposing the current VMOVE Fixes https://github.com/dotnet/runtime/issues/90800 * Only emit an OP_LDTOKEN_FIELD if we loaded a field token This is used by a CreateSpan optimization that needs access to the MonoClassField* For other cases of a bare LDTOKEN (such as hand-written IL that calls LDTOKEN on a type but doesn't follow it up with a call to `GetTypeFromHandle` leave the opcode as a VMOVE (from the `EMIT_NEW_TEMPLOAD` above)) --------- Co-authored-by: Aleksey Kliger --- src/mono/mono/mini/decompose.c | 2 +- src/mono/mono/mini/method-to-ir.c | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/mini/decompose.c b/src/mono/mono/mini/decompose.c index b4570cc0c7429d..2be1ff52e416d0 100644 --- a/src/mono/mono/mini/decompose.c +++ b/src/mono/mono/mini/decompose.c @@ -1226,7 +1226,7 @@ mono_decompose_vtype_opts (MonoCompile *cfg) dest_var = get_vreg_to_inst (cfg, ins->dreg); if (!src_var) - src_var = mono_compile_create_var_for_vreg (cfg, m_class_get_byval_arg (ins->klass), OP_LOCAL, ins->dreg); + src_var = mono_compile_create_var_for_vreg (cfg, m_class_get_byval_arg (ins->klass), OP_LOCAL, ins->sreg1); if (!dest_var) dest_var = mono_compile_create_var_for_vreg (cfg, m_class_get_byval_arg (ins->klass), OP_LOCAL, ins->dreg); diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index b5f75ea1c3133d..e3605981bafcdf 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -10840,12 +10840,15 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b EMIT_NEW_TEMPLOADA (cfg, addr, vtvar->inst_c0); MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, addr->dreg, 0, ins->dreg); EMIT_NEW_TEMPLOAD (cfg, ins, vtvar->inst_c0); - ins->opcode = OP_LDTOKEN_FIELD; - ins->inst_c0 = n; - ins->inst_p1 = handle; + if (handle_class == mono_defaults.fieldhandle_class) { + ins->opcode = OP_LDTOKEN_FIELD; + ins->inst_c0 = n; + ins->inst_p1 = handle; + + cfg->flags |= MONO_CFG_NEEDS_DECOMPOSE; + cfg->cbb->needs_decompose = TRUE; + } - cfg->flags |= MONO_CFG_NEEDS_DECOMPOSE; - cfg->cbb->needs_decompose = TRUE; } } From 034d27f4a9420e10601447d0385c88de9b4a2925 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 19 Aug 2023 09:13:47 -0700 Subject: [PATCH 046/783] [release/8.0-rc1] Use Roslyn interceptors feature in binder gen (#90835) * Use Roslyn interceptors feature in binder gen * Fix polymorphic issue and address feedback * Fix source build issue * Revert changes to options gen * Fix * Work around source build issue Co-authored-by: Eric StJohn --------- Co-authored-by: Layomi Akinrinade Co-authored-by: Eric StJohn --- docs/project/list-of-diagnostics.md | 2 + eng/SourceBuildPrebuiltBaseline.xml | 1 + .../ConfigurationBindingGenerator.Emitter.cs | 87 +++---- .../ConfigurationBindingGenerator.Parser.cs | 69 ++++-- ...onfigurationBindingGenerator.Suppressor.cs | 70 ++++++ .../gen/ConfigurationBindingGenerator.cs | 12 +- .../Helpers/Emitter/ConfigurationBinder.cs | 146 ++++++------ ...BindingHelper.cs => CoreBindingHelpers.cs} | 215 ++++++++---------- .../gen/Helpers/Emitter/Helpers.cs | 159 ++++++------- .../OptionsBuilderConfigurationExtensions.cs | 44 ++-- ...onfigurationServiceCollectionExtensions.cs | 49 ++-- .../gen/Helpers/InterceptorLocationInfo.cs | 90 ++++++++ .../gen/Helpers/MethodsToGen.cs | 9 +- .../gen/Helpers/Parser/BinderInvocation.cs | 2 +- .../gen/Helpers/Parser/ConfigurationBinder.cs | 33 ++- .../OptionsBuilderConfigurationExtensions.cs | 44 ++-- ...onfigurationServiceCollectionExtensions.cs | 4 +- ...nfiguration.Binder.SourceGeneration.csproj | 6 +- .../gen/Model/ObjectSpec.cs | 4 - .../gen/Model/ParsableFromStringSpec.cs | 2 +- .../gen/Model/SourceGenerationSpec.cs | 8 +- .../gen/Model/TypeSpec.cs | 9 +- .../gen/Resources/Strings.resx | 4 +- .../gen/Resources/xlf/Strings.cs.xlf | 8 +- .../gen/Resources/xlf/Strings.de.xlf | 8 +- .../gen/Resources/xlf/Strings.es.xlf | 8 +- .../gen/Resources/xlf/Strings.fr.xlf | 8 +- .../gen/Resources/xlf/Strings.it.xlf | 8 +- .../gen/Resources/xlf/Strings.ja.xlf | 8 +- .../gen/Resources/xlf/Strings.ko.xlf | 8 +- .../gen/Resources/xlf/Strings.pl.xlf | 8 +- .../gen/Resources/xlf/Strings.pt-BR.xlf | 8 +- .../gen/Resources/xlf/Strings.ru.xlf | 8 +- .../gen/Resources/xlf/Strings.tr.xlf | 8 +- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 8 +- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 8 +- .../tests/Common/ConfigurationBinderTests.cs | 3 +- .../Baselines/Collections.generated.txt | 79 ++----- .../ConfigurationBinder/Bind.generated.txt | 100 +++++--- .../Bind_Instance.generated.txt | 60 +++-- .../Bind_Instance_BinderOptions.generated.txt | 62 ++--- .../Bind_Key_Instance.generated.txt | 60 +++-- .../ConfigurationBinder/Get.generated.txt | 81 +++---- .../GetValue.generated.txt | 57 +++-- .../GetValue_T_Key.generated.txt | 29 ++- .../GetValue_T_Key_DefaultValue.generated.txt | 29 ++- .../GetValue_TypeOf_Key.generated.txt | 29 ++- ...alue_TypeOf_Key_DefaultValue.generated.txt | 29 ++- .../ConfigurationBinder/Get_T.generated.txt | 54 ++--- .../Get_T_BinderOptions.generated.txt | 54 ++--- .../Get_TypeOf.generated.txt | 39 ++-- .../Get_TypeOf_BinderOptions.generated.txt | 39 ++-- .../BindConfiguration.generated.txt | 96 +++++--- .../OptionsBuilder/Bind_T.generated.txt | 117 +++++----- .../Bind_T_BinderOptions.generated.txt | 105 +++++---- .../Baselines/Primitives.generated.txt | 45 +++- .../Configure_T.generated.txt | 101 ++++---- .../Configure_T_BinderOptions.generated.txt | 101 ++++---- .../Configure_T_name.generated.txt | 101 ++++---- ...nfigure_T_name_BinderOptions.generated.txt | 91 ++++---- ...BindingGeneratorTests.Baselines.Options.cs | 4 + ...gurationBindingGeneratorTests.Baselines.cs | 4 +- .../ConfigurationBindingGeneratorTests.cs | 18 +- ...ation.Binder.SourceGeneration.Tests.csproj | 2 +- ...ft.Extensions.Logging.Configuration.csproj | 1 + ...icrosoft.Extensions.Logging.Console.csproj | 2 + ...onExtensions.SourceGeneration.Tests.csproj | 4 +- 67 files changed, 1581 insertions(+), 1188 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Suppressor.cs rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/{CoreBindingHelper.cs => CoreBindingHelpers.cs} (83%) create mode 100644 src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/InterceptorLocationInfo.cs diff --git a/docs/project/list-of-diagnostics.md b/docs/project/list-of-diagnostics.md index 4f78e9e711653d..579b8d160d59b0 100644 --- a/docs/project/list-of-diagnostics.md +++ b/docs/project/list-of-diagnostics.md @@ -270,3 +270,5 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL | Suppression ID | Suppressed Diagnostic ID | Description | | :----------------------- | :----------------------- | :---------- | | __`SYSLIBSUPPRESS0001`__ | CA1822 | Do not offer to make methods static when the methods need to be instance methods for a custom marshaller shape. | +| __`SYSLIBSUPPRESS0002`__ | IL2026 | ConfigurationBindingGenerator: suppress RequiresUnreferencedCode diagnostic for binding call that has been intercepted by a generated static variant. | +| __`SYSLIBSUPPRESS0003`__ | IL3050 | ConfigurationBindingGenerator: suppress RequiresDynamicCode diagnostic for binding call that has been intercepted by a generated static variant. | diff --git a/eng/SourceBuildPrebuiltBaseline.xml b/eng/SourceBuildPrebuiltBaseline.xml index 74f6be96543a5e..46dd7457d764aa 100644 --- a/eng/SourceBuildPrebuiltBaseline.xml +++ b/eng/SourceBuildPrebuiltBaseline.xml @@ -10,6 +10,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs index a40cf2976b31fc..756e10bc26b8d5 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Immutable; using System.Diagnostics; using System.Text.RegularExpressions; using Microsoft.CodeAnalysis; @@ -17,7 +18,6 @@ private sealed partial class Emitter private readonly SourceGenerationSpec _sourceGenSpec; private bool _emitBlankLineBeforeNextStatement; - private bool _useFullyQualifiedNames; private int _valueSuffixIndex; private static readonly Regex s_arrayBracketsRegex = new(Regex.Escape("[]")); @@ -32,7 +32,7 @@ public Emitter(SourceProductionContext context, SourceGenerationSpec sourceGenSp public void Emit() { - if (!ShouldEmitBinders()) + if (!ShouldEmitBindingExtensions()) { return; } @@ -42,17 +42,26 @@ public void Emit() #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. """); - _writer.WriteLine(); - _useFullyQualifiedNames = true; - EmitBinder_Extensions_IConfiguration(); - EmitBinder_Extensions_OptionsBuilder(); - EmitBinder_Extensions_IServiceCollection(); + EmitInterceptsLocationAttrDecl(); + + EmitStartBlock($"namespace {ProjectName}"); + EmitUsingStatements(); + + _writer.WriteLine(); + EmitStartBlock($$""" + {{Expression.GeneratedCodeAnnotation}} + file static class {{Identifier.BindingExtensions}} + """); + EmitBindingExtensions_IConfiguration(); + EmitBindingExtensions_OptionsBuilder(); + EmitBindingExtensions_IServiceCollection(); + EmitCoreBindingHelpers(); + EmitEndBlock(); // BindingExtensions class - _useFullyQualifiedNames = false; - Emit_CoreBindingHelper(); + EmitEndBlock(); // Binding namespace. - _context.AddSource($"{Identifier.GeneratedConfigurationBinder}.g.cs", _writer.ToSourceText()); + _context.AddSource($"{Identifier.BindingExtensions}.g.cs", _writer.ToSourceText()); } private void EmitBindCoreCall( @@ -74,7 +83,7 @@ private void EmitBindCoreCall( if (initKind is InitializationKind.AssignmentWithNullCheck) { Debug.Assert(!type.IsValueType); - _writer.WriteLine($"{type.MinimalDisplayString}? {tempIdentifier} = {memberAccessExpr};"); + _writer.WriteLine($"{type.DisplayString}? {tempIdentifier} = {memberAccessExpr};"); EmitBindCoreCall(tempIdentifier, InitializationKind.AssignmentWithNullCheck); } else if (initKind is InitializationKind.None && type.IsValueType) @@ -89,9 +98,7 @@ private void EmitBindCoreCall( void EmitBindCoreCall(string objExpression, InitializationKind initKind) { - string methodDisplayString = GetHelperMethodDisplayString(nameof(MethodsToGen_CoreBindingHelper.BindCore)); - string bindCoreCall = $@"{methodDisplayString}({configArgExpr}, ref {objExpression}, {Identifier.binderOptions});"; - + string bindCoreCall = $@"{nameof(MethodsToGen_CoreBindingHelper.BindCore)}({configArgExpr}, ref {objExpression}, {Identifier.binderOptions});"; EmitObjectInit(objExpression, initKind); _writer.WriteLine(bindCoreCall); writeOnSuccess?.Invoke(objExpression); @@ -127,12 +134,11 @@ private void EmitBindLogicFromString( } else if (typeKind is StringParsableTypeKind.Enum) { - parsedValueExpr = $"ParseEnum<{type.MinimalDisplayString}>({stringValueToParse_Expr}, () => {sectionPathExpr})"; + parsedValueExpr = $"ParseEnum<{type.DisplayString}>({stringValueToParse_Expr}, () => {sectionPathExpr})"; } else { - string helperMethodDisplayString = GetHelperMethodDisplayString(type.ParseMethodName); - parsedValueExpr = $"{helperMethodDisplayString}({stringValueToParse_Expr}, () => {sectionPathExpr})"; + parsedValueExpr = $"{type.ParseMethodName}({stringValueToParse_Expr}, () => {sectionPathExpr})"; } if (!checkForNullSectionValue) @@ -156,7 +162,7 @@ private bool EmitObjectInit(TypeSpec type, string memberAccessExpr, Initializati string initExpr; CollectionSpec? collectionType = type as CollectionSpec; - string effectiveDisplayString = GetTypeDisplayString(type); + string effectiveDisplayString = type.DisplayString; if (collectionType is not null) { if (collectionType is EnumerableSpec { InitializationStrategy: InitializationStrategy.Array }) @@ -165,7 +171,7 @@ private bool EmitObjectInit(TypeSpec type, string memberAccessExpr, Initializati } else { - effectiveDisplayString = GetTypeDisplayString(collectionType.ConcreteType ?? collectionType); + effectiveDisplayString = (collectionType.ConcreteType ?? collectionType).DisplayString; initExpr = $"new {effectiveDisplayString}()"; } } @@ -215,36 +221,41 @@ private bool EmitObjectInit(TypeSpec type, string memberAccessExpr, Initializati return true; } - private void EmitCastToIConfigurationSection() + private void EmitInterceptsLocationAttrDecl() { - string sectionTypeDisplayString; - string exceptionTypeDisplayString; - if (_useFullyQualifiedNames) - { - sectionTypeDisplayString = "global::Microsoft.Extensions.Configuration.IConfigurationSection"; - exceptionTypeDisplayString = FullyQualifiedDisplayString.InvalidOperationException; - } - else - { - sectionTypeDisplayString = Identifier.IConfigurationSection; - exceptionTypeDisplayString = nameof(InvalidOperationException); - } - + _writer.WriteLine(); _writer.WriteLine($$""" - if ({{Identifier.configuration}} is not {{sectionTypeDisplayString}} {{Identifier.section}}) + namespace System.Runtime.CompilerServices { - throw new {{exceptionTypeDisplayString}}(); + using System; + using System.CodeDom.Compiler; + + {{Expression.GeneratedCodeAnnotation}} + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } """); + _writer.WriteLine(); + } + + private void EmitUsingStatements() + { + foreach (string @namespace in _sourceGenSpec.Namespaces.ToImmutableSortedSet()) + { + _writer.WriteLine($"using {@namespace};"); + } } private void EmitIConfigurationHasValueOrChildrenCheck(bool voidReturn) { string returnPostfix = voidReturn ? string.Empty : " null"; - string methodDisplayString = GetHelperMethodDisplayString(Identifier.HasValueOrChildren); - _writer.WriteLine($$""" - if (!{{methodDisplayString}}({{Identifier.configuration}})) + if (!{{Identifier.HasValueOrChildren}}({{Identifier.configuration}})) { return{{returnPostfix}}; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs index b0f53ef074078f..64db4eb58b1f77 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs @@ -1,12 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Operations; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { @@ -147,7 +149,7 @@ type.TypeKind is TypeKind.TypeParameter or TypeKind.Pointer or TypeKind.Error || { // List is used in generated code as a temp holder for formatting // an error for config properties that don't map to object properties. - _sourceGenSpec.TypeNamespaces.Add("System.Collections.Generic"); + _sourceGenSpec.Namespaces.Add("System.Collections.Generic"); spec = CreateObjectSpec(namedType); } @@ -169,32 +171,54 @@ type.TypeKind is TypeKind.TypeParameter or TypeKind.Pointer or TypeKind.Error || string @namespace = spec.Namespace; if (@namespace is not null and not "") { - _sourceGenSpec.TypeNamespaces.Add(@namespace); + _sourceGenSpec.Namespaces.Add(@namespace); } return _createdSpecs[type] = spec; } - private void RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper method, TypeSpec type) + private void RegisterTypeForBindCoreMainGen(TypeSpec typeSpec) { - if (!_sourceGenSpec.TypesForGen_CoreBindingHelper_Methods.TryGetValue(method, out HashSet? types)) + if (typeSpec.NeedsMemberBinding) { - _sourceGenSpec.TypesForGen_CoreBindingHelper_Methods[method] = types = new HashSet(); + RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.BindCoreMain, typeSpec); + RegisterTypeForBindCoreGen(typeSpec); + _sourceGenSpec.MethodsToGen_CoreBindingHelper |= MethodsToGen_CoreBindingHelper.AsConfigWithChildren; } - - types.Add(type); - _sourceGenSpec.MethodsToGen_CoreBindingHelper |= method; } - private void RegisterTypeForBindCoreUntypedGen(TypeSpec typeSpec) + private void RegisterTypeForBindCoreGen(TypeSpec typeSpec) { if (typeSpec.NeedsMemberBinding) { RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.BindCore, typeSpec); - RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.BindCoreUntyped, typeSpec); } } + private void RegisterTypeForGetCoreGen(TypeSpec typeSpec) + { + RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.GetCore, typeSpec); + _sourceGenSpec.MethodsToGen_CoreBindingHelper |= MethodsToGen_CoreBindingHelper.AsConfigWithChildren; + } + + private void RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper method, TypeSpec type) + { + if (!_sourceGenSpec.TypesForGen_CoreBindingHelper_Methods.TryGetValue(method, out HashSet? types)) + { + _sourceGenSpec.TypesForGen_CoreBindingHelper_Methods[method] = types = new HashSet(); + } + + types.Add(type); + _sourceGenSpec.MethodsToGen_CoreBindingHelper |= method; + } + + /// + /// Registers interceptors for root binding methods, except for ConfigurationBinder.Bind, + /// which is handled by + /// + private void RegisterAsInterceptor(Enum method, IInvocationOperation operation) => + _sourceGenSpec.InterceptionInfo.RegisterCacheEntry(method, new InterceptorLocationInfo(operation)); + private static bool IsNullable(ITypeSymbol type, [NotNullWhen(true)] out ITypeSymbol? underlyingType) { if (type is INamedTypeSymbol { IsGenericType: true } genericType && @@ -335,7 +359,7 @@ private bool TryGetTypeSpec(ITypeSymbol type, DiagnosticDescriptor descriptor, o // We want a BindCore method for List as a temp holder for the array values. We know the element type is supported. EnumerableSpec listSpec = (GetOrCreateTypeSpec(_typeSymbols.List.Construct(arrayType.ElementType)) as EnumerableSpec)!; - RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.BindCore, listSpec); + RegisterTypeForBindCoreGen(listSpec); EnumerableSpec spec = new EnumerableSpec(arrayType) { @@ -347,7 +371,7 @@ private bool TryGetTypeSpec(ITypeSymbol type, DiagnosticDescriptor descriptor, o }; Debug.Assert(spec.CanInitialize); - RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.BindCore, spec); + RegisterTypeForBindCoreGen(spec); return spec; } @@ -383,7 +407,7 @@ private bool IsSupportedArrayType(ITypeSymbol type) if (spec is not null) { - RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.BindCore, spec); + RegisterTypeForBindCoreGen(spec); spec.InitExceptionMessage ??= spec.ElementType.InitExceptionMessage; } @@ -442,7 +466,7 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol k constructionStrategy = InitializationStrategy.ToEnumerableMethod; populationStrategy = CollectionPopulationStrategy.Cast_Then_Add; toEnumerableMethodCall = "ToDictionary(pair => pair.Key, pair => pair.Value)"; - _sourceGenSpec.TypeNamespaces.Add("System.Linq"); + _sourceGenSpec.Namespaces.Add("System.Linq"); } else { @@ -711,7 +735,7 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol k if (objectSpec.NeedsMemberBinding) { - RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.BindCore, objectSpec); + RegisterTypeForBindCoreGen(objectSpec); } return objectSpec; @@ -890,4 +914,19 @@ private void RegisterTypeDiagnostic(ITypeSymbol causingType, InvocationDiagnosti } } } + + public static class ParserExtensions + { + public static void RegisterCacheEntry(this Dictionary cache, TKey key, TEntry entry) + where TKey : notnull + where TValue : ICollection, new() + { + if (!cache.TryGetValue(key, out TValue? entryCollection)) + { + cache[key] = entryCollection = new TValue(); + } + + entryCollection.Add(entry); + } + } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Suppressor.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Suppressor.cs new file mode 100644 index 00000000000000..13158753c3f075 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Suppressor.cs @@ -0,0 +1,70 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; + +namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration +{ + public sealed partial class ConfigurationBindingGenerator + { + /// + /// Supresses false-positive diagnostics emitted by the linker + /// when analyzing binding invocations that we have intercepted. + /// Workaround for https://github.com/dotnet/roslyn/issues/68669. + /// + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public sealed class Suppressor : DiagnosticSuppressor + { + private const string Justification = "The target method has been intercepted by a generated static variant."; + + /// + /// Suppression descriptor for IL2026: Members attributed with RequiresUnreferencedCode may break when trimming. + /// + private static readonly SuppressionDescriptor RUCDiagnostic = new(id: "SYSLIBSUPPRESS0002", suppressedDiagnosticId: "IL2026", Justification); + + /// + /// Suppression descriptor for IL3050: Avoid calling members annotated with 'RequiresDynamicCodeAttribute' when publishing as native AOT. + /// + private static readonly SuppressionDescriptor RDCDiagnostic = new(id: "SYSLIBSUPPRESS0003", suppressedDiagnosticId: "IL3050", Justification); + + public override ImmutableArray SupportedSuppressions => ImmutableArray.Create(RUCDiagnostic, RDCDiagnostic); + + public override void ReportSuppressions(SuppressionAnalysisContext context) + { + foreach (Diagnostic diagnostic in context.ReportedDiagnostics) + { + string diagnosticId = diagnostic.Id; + + if (diagnosticId != RDCDiagnostic.SuppressedDiagnosticId && diagnosticId != RUCDiagnostic.SuppressedDiagnosticId) + { + continue; + } + + Location location = diagnostic.AdditionalLocations.Count > 0 + ? diagnostic.AdditionalLocations[0] + : diagnostic.Location; + + bool shouldSuppressDiagnostic = + location.SourceTree is SyntaxTree sourceTree && + sourceTree.GetRoot().FindNode(location.SourceSpan) is SyntaxNode syntaxNode && + BinderInvocation.IsCandidateSyntaxNode(syntaxNode) && + context.GetSemanticModel(sourceTree) + .GetOperation((InvocationExpressionSyntax)syntaxNode, context.CancellationToken) is IInvocationOperation operation && + BinderInvocation.IsBindingOperation(operation); + + if (shouldSuppressDiagnostic) + { + SuppressionDescriptor targetSuppression = diagnosticId == RUCDiagnostic.SuppressedDiagnosticId + ? RUCDiagnostic + : RDCDiagnostic; + context.ReportSuppression(Suppression.Create(targetSuppression, diagnostic)); + } + } + } + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.cs index 70da582dddf0cd..fbca2dd3cfc507 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.cs @@ -5,7 +5,6 @@ using System.Collections.Immutable; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { @@ -15,7 +14,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration [Generator] public sealed partial class ConfigurationBindingGenerator : IIncrementalGenerator { - internal const string ProjectName = "Microsoft.Extensions.Configuration.Binder.SourceGeneration"; + private static readonly string ProjectName = Emitter.s_assemblyName.Name; public void Initialize(IncrementalGeneratorInitializationContext context) { @@ -42,9 +41,6 @@ public void Initialize(IncrementalGeneratorInitializationContext context) context.RegisterSourceOutput(inputData, (spc, source) => Execute(source.Item1, source.Item2, spc)); } - /// - /// Generates source code to optimize binding with ConfigurationBinder. - /// private static void Execute(CompilationData compilationData, ImmutableArray inputCalls, SourceProductionContext context) { if (inputCalls.IsDefaultOrEmpty) @@ -73,7 +69,11 @@ private sealed record CompilationData public CompilationData(CSharpCompilation compilation) { - LanguageVersionIsSupported = compilation.LanguageVersion >= LanguageVersion.CSharp11; + // We don't have a CSharp21 value available yet. Polyfill the value here for forward compat, rather than use the LangugeVersion.Preview enum value. + // https://github.com/dotnet/roslyn/blob/168689931cb4e3150641ec2fb188a64ce4b3b790/src/Compilers/CSharp/Portable/LanguageVersion.cs#L218-L232 + const int LangVersion_CSharp12 = 1200; + LanguageVersionIsSupported = (int)compilation.LanguageVersion >= LangVersion_CSharp12; + if (LanguageVersionIsSupported) { TypeSymbols = new KnownTypeSymbols(compilation); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs index c10e607df75d0a..64064887c7c70b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs @@ -2,9 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Microsoft.CodeAnalysis; +using SourceGenerators; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { @@ -14,91 +12,84 @@ private sealed partial class Emitter { private bool ShouldEmitMethods(MethodsToGen_ConfigurationBinder methods) => (_sourceGenSpec.MethodsToGen_ConfigurationBinder & methods) != 0; - private void EmitBinder_Extensions_IConfiguration() + private void EmitBindingExtensions_IConfiguration() { - Debug.Assert(_sourceGenSpec.TypesForGen_ConfigurationBinder_BindMethods.Count <= 3 && - !_sourceGenSpec.TypesForGen_ConfigurationBinder_BindMethods.Keys.Any(overload => (overload & MethodsToGen_ConfigurationBinder.Bind) is 0)); - if (!ShouldEmitMethods(MethodsToGen_ConfigurationBinder.Any)) { return; } - _emitBlankLineBeforeNextStatement = false; - EmitRootBindingClassStartBlock(Identifier.GeneratedConfigurationBinder); - + EmitBindingExtStartRegion(Identifier.IConfiguration); EmitGetMethods(); EmitGetValueMethods(); EmitBindMethods_ConfigurationBinder(); - - EmitEndBlock(); - _emitBlankLineBeforeNextStatement = true; + EmitBindingExtEndRegion(); } private void EmitGetMethods() { - const string expressionForGetCore = $"{FullyQualifiedDisplayString.CoreBindingHelper}.{nameof(MethodsToGen_CoreBindingHelper.GetCore)}"; + const string expressionForGetCore = nameof(MethodsToGen_CoreBindingHelper.GetCore); const string documentation = "Attempts to bind the configuration instance to a new instance of type T."; if (ShouldEmitMethods(MethodsToGen_ConfigurationBinder.Get_T)) { - StartMethodDefinition(documentation); - _writer.WriteLine($"public static T? {Identifier.Get}(this {FullyQualifiedDisplayString.IConfiguration} {Identifier.configuration}) => " + + StartMethodDefinition(MethodsToGen_ConfigurationBinder.Get_T, documentation); + _writer.WriteLine($"public static T? {Identifier.Get}(this {Identifier.IConfiguration} {Identifier.configuration}) => " + $"(T?)({expressionForGetCore}({Identifier.configuration}, typeof(T), {Identifier.configureOptions}: null) ?? default(T));"); } if (ShouldEmitMethods(MethodsToGen_ConfigurationBinder.Get_T_BinderOptions)) { - StartMethodDefinition(documentation); - _writer.WriteLine($"public static T? {Identifier.Get}(this {FullyQualifiedDisplayString.IConfiguration} {Identifier.configuration}, {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions}) => " + + StartMethodDefinition(MethodsToGen_ConfigurationBinder.Get_T_BinderOptions, documentation); + _writer.WriteLine($"public static T? {Identifier.Get}(this {Identifier.IConfiguration} {Identifier.configuration}, {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions}) => " + $"(T?)({expressionForGetCore}({Identifier.configuration}, typeof(T), {Identifier.configureOptions}) ?? default(T));"); } if (ShouldEmitMethods(MethodsToGen_ConfigurationBinder.Get_TypeOf)) { - StartMethodDefinition(documentation); - _writer.WriteLine($"public static object? {Identifier.Get}(this {FullyQualifiedDisplayString.IConfiguration} {Identifier.configuration}, {FullyQualifiedDisplayString.Type} {Identifier.type}) => " + + StartMethodDefinition(MethodsToGen_ConfigurationBinder.Get_TypeOf, documentation); + _writer.WriteLine($"public static object? {Identifier.Get}(this {Identifier.IConfiguration} {Identifier.configuration}, Type {Identifier.type}) => " + $"{expressionForGetCore}({Identifier.configuration}, {Identifier.type}, {Identifier.configureOptions}: null);"); } if (ShouldEmitMethods(MethodsToGen_ConfigurationBinder.Get_TypeOf_BinderOptions)) { - StartMethodDefinition(documentation); - _writer.WriteLine($"public static object? {Identifier.Get}(this {FullyQualifiedDisplayString.IConfiguration} {Identifier.configuration}, {FullyQualifiedDisplayString.Type} {Identifier.type}, {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions}) => " + + StartMethodDefinition(MethodsToGen_ConfigurationBinder.Get_TypeOf_BinderOptions, documentation); + _writer.WriteLine($"public static object? {Identifier.Get}(this {Identifier.IConfiguration} {Identifier.configuration}, Type {Identifier.type}, {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions}) => " + $"{expressionForGetCore}({Identifier.configuration}, {Identifier.type}, {Identifier.configureOptions});"); } } private void EmitGetValueMethods() { - const string expressionForGetValueCore = $"{FullyQualifiedDisplayString.CoreBindingHelper}.{nameof(MethodsToGen_CoreBindingHelper.GetValueCore)}"; + const string expressionForGetValueCore = $"{Identifier.BindingExtensions}.{nameof(MethodsToGen_CoreBindingHelper.GetValueCore)}"; const string documentation = "Extracts the value with the specified key and converts it to the specified type."; if (ShouldEmitMethods(MethodsToGen_ConfigurationBinder.GetValue_T_key)) { - StartMethodDefinition(documentation); - _writer.WriteLine($"public static T? {Identifier.GetValue}(this {FullyQualifiedDisplayString.IConfiguration} {Identifier.configuration}, string {Identifier.key}) => " + + StartMethodDefinition(MethodsToGen_ConfigurationBinder.GetValue_T_key, documentation); + _writer.WriteLine($"public static T? {Identifier.GetValue}(this {Identifier.IConfiguration} {Identifier.configuration}, string {Identifier.key}) => " + $"(T?)({expressionForGetValueCore}({Identifier.configuration}, typeof(T), {Identifier.key}) ?? default(T));"); } if (ShouldEmitMethods(MethodsToGen_ConfigurationBinder.GetValue_T_key_defaultValue)) { - StartMethodDefinition(documentation); - _writer.WriteLine($"public static T? {Identifier.GetValue}(this {FullyQualifiedDisplayString.IConfiguration} {Identifier.configuration}, string {Identifier.key}, T {Identifier.defaultValue}) => " + + StartMethodDefinition(MethodsToGen_ConfigurationBinder.GetValue_T_key_defaultValue, documentation); + _writer.WriteLine($"public static T? {Identifier.GetValue}(this {Identifier.IConfiguration} {Identifier.configuration}, string {Identifier.key}, T {Identifier.defaultValue}) => " + $"(T?)({expressionForGetValueCore}({Identifier.configuration}, typeof(T), {Identifier.key}) ?? {Identifier.defaultValue});"); } if (ShouldEmitMethods(MethodsToGen_ConfigurationBinder.GetValue_TypeOf_key)) { - StartMethodDefinition(documentation); - _writer.WriteLine($"public static object? {Identifier.GetValue}(this {FullyQualifiedDisplayString.IConfiguration} {Identifier.configuration}, {FullyQualifiedDisplayString.Type} {Identifier.type}, string {Identifier.key}) => " + + StartMethodDefinition(MethodsToGen_ConfigurationBinder.GetValue_TypeOf_key, documentation); + _writer.WriteLine($"public static object? {Identifier.GetValue}(this {Identifier.IConfiguration} {Identifier.configuration}, Type {Identifier.type}, string {Identifier.key}) => " + $"{expressionForGetValueCore}({Identifier.configuration}, {Identifier.type}, {Identifier.key});"); } if (ShouldEmitMethods(MethodsToGen_ConfigurationBinder.GetValue_TypeOf_key_defaultValue)) { - StartMethodDefinition(documentation); - _writer.WriteLine($"public static object? {Identifier.GetValue}(this {FullyQualifiedDisplayString.IConfiguration} {Identifier.configuration}, {FullyQualifiedDisplayString.Type} {Identifier.type}, string {Identifier.key}, object? {Identifier.defaultValue}) => " + + StartMethodDefinition(MethodsToGen_ConfigurationBinder.GetValue_TypeOf_key_defaultValue, documentation); + _writer.WriteLine($"public static object? {Identifier.GetValue}(this {Identifier.IConfiguration} {Identifier.configuration}, Type {Identifier.type}, string {Identifier.key}, object? {Identifier.defaultValue}) => " + $"{expressionForGetValueCore}({Identifier.configuration}, {Identifier.type}, {Identifier.key}) ?? {Identifier.defaultValue};"); } } @@ -110,72 +101,71 @@ private void EmitBindMethods_ConfigurationBinder() return; } - Dictionary> types = _sourceGenSpec.TypesForGen_ConfigurationBinder_BindMethods; + string objParamExpr = $"object? {Identifier.obj}"; - if (types.TryGetValue(MethodsToGen_ConfigurationBinder.Bind_instance, out HashSet? typeSpecs)) + if (ShouldEmitMethods(MethodsToGen_ConfigurationBinder.Bind_instance)) { - foreach (TypeSpec type in typeSpecs) - { - EmitMethodImplementation( - type, - additionalParams: GetObjParameter(type), - configExpression: Identifier.configuration, - configureOptions: false); - } + EmitMethods( + MethodsToGen_ConfigurationBinder.Bind_instance, + additionalParams: objParamExpr, + configExpression: Identifier.configuration, + configureOptions: false); } - if (types.TryGetValue(MethodsToGen_ConfigurationBinder.Bind_instance_BinderOptions, out typeSpecs)) + if (ShouldEmitMethods(MethodsToGen_ConfigurationBinder.Bind_instance_BinderOptions)) { - foreach (TypeSpec type in typeSpecs) - { - EmitMethodImplementation( - type, - additionalParams: $"{GetObjParameter(type)}, {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions}", - configExpression: Identifier.configuration, - configureOptions: true); - } + EmitMethods( + MethodsToGen_ConfigurationBinder.Bind_instance_BinderOptions, + additionalParams: $"{objParamExpr}, {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions}", + configExpression: Identifier.configuration, + configureOptions: true); } - if (types.TryGetValue(MethodsToGen_ConfigurationBinder.Bind_key_instance, out typeSpecs)) + if (ShouldEmitMethods(MethodsToGen_ConfigurationBinder.Bind_key_instance)) { - foreach (TypeSpec type in typeSpecs) - { - EmitMethodImplementation( - type, - additionalParams: $"string {Identifier.key}, {GetObjParameter(type)}", - configExpression: $"{Expression.configurationGetSection}({Identifier.key})", - configureOptions: false); - } + EmitMethods( + MethodsToGen_ConfigurationBinder.Bind_key_instance, + additionalParams: $"string {Identifier.key}, {objParamExpr}", + configExpression: $"{Expression.configurationGetSection}({Identifier.key})", + configureOptions: false); } - void EmitMethodImplementation(TypeSpec type, string additionalParams, string configExpression, bool configureOptions) + void EmitMethods(MethodsToGen_ConfigurationBinder method, string additionalParams, string configExpression, bool configureOptions) { - string binderOptionsArg = configureOptions ? $"{Expression.GetBinderOptions}({Identifier.configureOptions})" : $"{Identifier.binderOptions}: null"; - - string returnExpression; - if (type.CanInitialize) + foreach (KeyValuePair> pair in _sourceGenSpec.InterceptionInfo_ConfigBinder.GetOverloadInfo(method)) { - returnExpression = type.NeedsMemberBinding - ? $"{FullyQualifiedDisplayString.CoreBindingHelper}.{nameof(MethodsToGen_CoreBindingHelper.BindCore)}({configExpression}, ref {Identifier.obj}, {binderOptionsArg})" - : "{ }"; + (TypeSpec type, List interceptorInfoList) = (pair.Key, pair.Value); + + EmitBlankLineIfRequired(); + _writer.WriteLine($"/// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively."); + EmitInterceptsLocationAnnotations(interceptorInfoList); + EmitStartBlock($"public static void {Identifier.Bind}_{type.DisplayString.ToIdentifierSubstring()}(this {Identifier.IConfiguration} {Identifier.configuration}, {additionalParams})"); + + if (!EmitInitException(type) && type.NeedsMemberBinding) + { + string binderOptionsArg = configureOptions ? $"{Identifier.GetBinderOptions}({Identifier.configureOptions})" : $"{Identifier.binderOptions}: null"; + + EmitCheckForNullArgument_WithBlankLine(Identifier.configuration); + if (!type.IsValueType) + { + EmitCheckForNullArgument_WithBlankLine(Identifier.obj); + } + _writer.WriteLine($$""" + var {{Identifier.typedObj}} = ({{type.EffectiveType.DisplayString}}){{Identifier.obj}}; + {{nameof(MethodsToGen_CoreBindingHelper.BindCore)}}({{configExpression}}, ref {{Identifier.typedObj}}, {{binderOptionsArg}}); + """); + } + + EmitEndBlock(); } - else - { - returnExpression = GetInitException(type.InitExceptionMessage); - } - - StartMethodDefinition("Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively."); - _writer.WriteLine($"public static void {Identifier.Bind}(this {FullyQualifiedDisplayString.IConfiguration} {Identifier.configuration}, {additionalParams}) => " - + $"{returnExpression};"); } - - string GetObjParameter(TypeSpec type) => $"{type.FullyQualifiedDisplayString} {Identifier.obj}"; } - private void StartMethodDefinition(string documentation) + private void StartMethodDefinition(MethodsToGen_ConfigurationBinder method, string documentation) { EmitBlankLineIfRequired(); _writer.WriteLine($"/// {documentation}"); + EmitInterceptsLocationAnnotations(method); } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelper.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs similarity index 83% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelper.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs index a7b42b1329804e..f30408fad596dd 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelper.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs @@ -3,10 +3,10 @@ using System; using System.Collections.Generic; -using System.Collections.Immutable; using System.Diagnostics; using System.Linq; using Microsoft.CodeAnalysis; +using SourceGenerators; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { @@ -16,41 +16,18 @@ private sealed partial class Emitter { private bool ShouldEmitMethods(MethodsToGen_CoreBindingHelper methods) => (_sourceGenSpec.MethodsToGen_CoreBindingHelper & methods) != 0; - private void Emit_CoreBindingHelper() + private void EmitCoreBindingHelpers() { Debug.Assert(_emitBlankLineBeforeNextStatement); - _writer.WriteLine(); - _emitBlankLineBeforeNextStatement = false; - - EmitStartBlock($"namespace {ProjectName}"); - EmitHelperUsingStatements(); - - _writer.WriteLine(); - - EmitStartBlock($$""" - /// Provide core binding logic. - {{GetGeneratedCodeAttributeSrc()}} - file static class {{Identifier.CoreBindingHelper}} - """); - + EmitBindingExtStartRegion("Core binding"); EmitConfigurationKeyCaches(); EmitGetCoreMethod(); EmitGetValueCoreMethod(); - EmitBindCoreUntypedMethod(); + EmitBindCoreMainMethod(); EmitBindCoreMethods(); EmitInitializeMethods(); EmitHelperMethods(); - - EmitEndBlock(); // End helper class. - EmitEndBlock(); // End namespace. - } - - private void EmitHelperUsingStatements() - { - foreach (string @namespace in _sourceGenSpec.TypeNamespaces.ToImmutableSortedSet()) - { - _writer.WriteLine($"using {@namespace};"); - } + EmitBindingExtEndRegion(); } private void EmitConfigurationKeyCaches() @@ -60,6 +37,8 @@ private void EmitConfigurationKeyCaches() return; } + EmitBlankLineIfRequired(); + foreach (TypeSpec type in targetTypes) { if (type is not ObjectSpec objectType) @@ -73,10 +52,8 @@ private void EmitConfigurationKeyCaches() string configKeysSource = string.Join(", ", keys); string fieldName = GetConfigKeyCacheFieldName(objectType); - _writer.WriteLine($@"private readonly static Lazy<{MinimalDisplayString.HashSetOfString}> {fieldName} = new(() => new {MinimalDisplayString.HashSetOfString}(StringComparer.OrdinalIgnoreCase) {{ {configKeysSource} }});"); + _writer.WriteLine($@"private readonly static Lazy<{TypeDisplayString.HashSetOfString}> {fieldName} = new(() => new {TypeDisplayString.HashSetOfString}(StringComparer.OrdinalIgnoreCase) {{ {configKeysSource} }});"); } - - _emitBlankLineBeforeNextStatement = true; } private void EmitGetCoreMethod() @@ -96,16 +73,24 @@ private void EmitGetCoreMethod() EmitIConfigurationHasValueOrChildrenCheck(voidReturn: false); + bool isFirstType = true; foreach (TypeSpec type in types) { TypeSpec effectiveType = type.EffectiveType; TypeSpecKind kind = effectiveType.SpecKind; + string conditionKindExpr = GetConditionKindExpr(ref isFirstType); - EmitStartBlock($"if (type == typeof({type.MinimalDisplayString}))"); + EmitStartBlock($"{conditionKindExpr} ({Identifier.type} == typeof({type.DisplayString}))"); if (effectiveType is ParsableFromStringSpec stringParsableType) { - EmitCastToIConfigurationSection(); + _writer.WriteLine($$""" + if ({{Identifier.configuration}} is not {{Identifier.IConfigurationSection}} {{Identifier.section}}) + { + throw new {{Identifier.InvalidOperationException}}(); + } + """); + EmitBindLogicFromString( stringParsableType, Expression.sectionValue, @@ -121,9 +106,9 @@ private void EmitGetCoreMethod() } EmitEndBlock(); - _writer.WriteLine(); } + _writer.WriteLine(); Emit_NotSupportedException_TypeNotDetectedAsInput(); EmitEndBlock(); _emitBlankLineBeforeNextStatement = true; @@ -152,9 +137,11 @@ private void EmitGetValueCoreMethod() _writer.WriteLine(); + bool isFirstType = true; foreach (TypeSpec type in targetTypes) { - EmitStartBlock($"if ({Identifier.type} == typeof({type.MinimalDisplayString}))"); + string conditionKindExpr = GetConditionKindExpr(ref isFirstType); + EmitStartBlock($"{conditionKindExpr} ({Identifier.type} == typeof({type.DisplayString}))"); EmitBindLogicFromString( (ParsableFromStringSpec)type.EffectiveType, @@ -165,51 +152,48 @@ private void EmitGetValueCoreMethod() useIncrementalStringValueIdentifier: false); EmitEndBlock(); - _writer.WriteLine(); } + _writer.WriteLine(); _writer.WriteLine("return null;"); EmitEndBlock(); _emitBlankLineBeforeNextStatement = true; } - private void EmitBindCoreUntypedMethod() + private void EmitBindCoreMainMethod() { - if (!_sourceGenSpec.TypesForGen_CoreBindingHelper_Methods.TryGetValue(MethodsToGen_CoreBindingHelper.BindCoreUntyped, out HashSet? targetTypes)) + if (!_sourceGenSpec.TypesForGen_CoreBindingHelper_Methods.TryGetValue(MethodsToGen_CoreBindingHelper.BindCoreMain, out HashSet? targetTypes)) { return; } EmitBlankLineIfRequired(); - - EmitStartBlock($"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCoreUntyped)}(this {Identifier.IConfiguration} {Identifier.configuration}, object {Identifier.obj}, Type {Identifier.type}, {MinimalDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions})"); - + EmitStartBlock($"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCoreMain)}({Identifier.IConfiguration} {Identifier.configuration}, object {Identifier.obj}, Type {Identifier.type}, {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions})"); EmitCheckForNullArgument_WithBlankLine(Identifier.configuration); - + EmitCheckForNullArgument_WithBlankLine(Identifier.obj); + EmitIConfigurationHasValueOrChildrenCheck(voidReturn: true); _writer.WriteLine($"{Identifier.BinderOptions}? {Identifier.binderOptions} = {Identifier.GetBinderOptions}({Identifier.configureOptions});"); _writer.WriteLine(); - EmitIConfigurationHasValueOrChildrenCheck(voidReturn: true); - + bool isFirstType = true; foreach (TypeSpec type in targetTypes) { - EmitStartBlock($"if (type == typeof({type.MinimalDisplayString}))"); - TypeSpec effectiveType = type.EffectiveType; + string conditionKindExpr = GetConditionKindExpr(ref isFirstType); + + EmitStartBlock($"{conditionKindExpr} ({Identifier.type} == typeof({type.DisplayString}))"); if (!EmitInitException(effectiveType)) { - _writer.WriteLine($"var {Identifier.temp} = ({effectiveType.MinimalDisplayString}){Identifier.obj};"); + _writer.WriteLine($"var {Identifier.temp} = ({effectiveType.DisplayString}){Identifier.obj};"); EmitBindCoreCall(type, Identifier.temp, Identifier.configuration, InitializationKind.None); _writer.WriteLine($"return;"); } - EmitEndBlock(); - _writer.WriteLine(); } + _writer.WriteLine(); Emit_NotSupportedException_TypeNotDetectedAsInput(); EmitEndBlock(); - _emitBlankLineBeforeNextStatement = true; } private void EmitBindCoreMethods() @@ -231,11 +215,9 @@ private void EmitBindCoreMethod(TypeSpec type) { Debug.Assert(type.CanInitialize); - string objParameterExpression = $"ref {type.MinimalDisplayString} {Identifier.obj}"; + string objParameterExpression = $"ref {type.DisplayString} {Identifier.obj}"; EmitStartBlock(@$"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCore)}({Identifier.IConfiguration} {Identifier.configuration}, {objParameterExpression}, {Identifier.BinderOptions}? {Identifier.binderOptions})"); - EmitCheckForNullArgument_WithBlankLine_IfRequired(type.IsValueType); - TypeSpec effectiveType = type.EffectiveType; if (effectiveType is EnumerableSpec enumerable) { @@ -281,9 +263,9 @@ private void EmitInitializeMethod(ObjectSpec type) List ctorParams = type.ConstructorParameters; IEnumerable initOnlyProps = type.Properties.Values.Where(prop => prop is { SetOnInit: true }); List ctorArgList = new(); - string displayString = type.MinimalDisplayString; + string displayString = type.DisplayString; - EmitStartBlock($"public static {type.MinimalDisplayString} {GetInitalizeMethodDisplayString(type)}({Identifier.IConfiguration} {Identifier.configuration}, {Identifier.BinderOptions}? {Identifier.binderOptions})"); + EmitStartBlock($"public static {type.DisplayString} {GetInitalizeMethodDisplayString(type)}({Identifier.IConfiguration} {Identifier.configuration}, {Identifier.BinderOptions}? {Identifier.binderOptions})"); _emitBlankLineBeforeNextStatement = false; foreach (ParameterSpec parameter in ctorParams) @@ -335,7 +317,7 @@ void EmitBindImplForMember(MemberSpec member) TypeSpec memberType = member.Type; bool errorOnFailedBinding = member.ErrorOnFailedBinding; - string parsedMemberIdentifierDeclarationPrefix = $"{memberType.MinimalDisplayString} {member.Name}"; + string parsedMemberIdentifierDeclarationPrefix = $"{memberType.DisplayString} {member.Name}"; string parsedMemberIdentifier; if (memberType is ParsableFromStringSpec { StringParsableTypeKind: StringParsableTypeKind.AssignFromSectionValue }) @@ -344,7 +326,7 @@ void EmitBindImplForMember(MemberSpec member) if (errorOnFailedBinding) { - string condition = $@" if ({Identifier.configuration}[""{member.ConfigurationKeyName}""] is not {memberType.MinimalDisplayString} {member.Name})"; + string condition = $@" if ({Identifier.configuration}[""{member.ConfigurationKeyName}""] is not {memberType.DisplayString} {member.Name})"; EmitThrowBlock(condition); _writer.WriteLine(); return; @@ -393,40 +375,42 @@ void EmitThrowBlock(string condition) => _writer.WriteLine($$""" {{condition}} { - throw new {{GetInvalidOperationDisplayName()}}("{{string.Format(ExceptionMessages.ParameterHasNoMatchingConfig, type.Name, member.Name)}}"); + throw new {{Identifier.InvalidOperationException}}("{{string.Format(ExceptionMessages.ParameterHasNoMatchingConfig, type.Name, member.Name)}}"); } """); } } + private void EmitHelperMethods() { + // Emitted if we are to bind objects with complex members, or if we're emitting BindCoreMain or GetCore methods. + bool emitAsConfigWithChildren = ShouldEmitMethods(MethodsToGen_CoreBindingHelper.AsConfigWithChildren); + if (ShouldEmitMethods(MethodsToGen_CoreBindingHelper.BindCore)) { + EmitBlankLineIfRequired(); EmitValidateConfigurationKeysMethod(); } - if (ShouldEmitMethods(MethodsToGen_CoreBindingHelper.BindCoreUntyped | MethodsToGen_CoreBindingHelper.GetCore)) + if (ShouldEmitMethods(MethodsToGen_CoreBindingHelper.BindCoreMain | MethodsToGen_CoreBindingHelper.GetCore)) { - _writer.WriteLine(); + // HasValueOrChildren references this method. + Debug.Assert(emitAsConfigWithChildren); + EmitBlankLineIfRequired(); EmitHasValueOrChildrenMethod(); - _writer.WriteLine(); - EmitAsConfigWithChildrenMethod(); - _emitBlankLineBeforeNextStatement = true; } - else if (ShouldEmitMethods(MethodsToGen_CoreBindingHelper.AsConfigWithChildren)) + + if (emitAsConfigWithChildren) { - _writer.WriteLine(); + EmitBlankLineIfRequired(); EmitAsConfigWithChildrenMethod(); - _emitBlankLineBeforeNextStatement = true; } - if (ShouldEmitMethods( - MethodsToGen_CoreBindingHelper.BindCoreUntyped | MethodsToGen_CoreBindingHelper.GetCore) || + if (ShouldEmitMethods(MethodsToGen_CoreBindingHelper.BindCoreMain | MethodsToGen_CoreBindingHelper.GetCore) || ShouldEmitMethods(MethodsToGen_ConfigurationBinder.Bind_instance_BinderOptions)) { - _writer.WriteLine(); + EmitBlankLineIfRequired(); EmitGetBinderOptionsHelper(); - _emitBlankLineBeforeNextStatement = true; } bool enumTypeExists = false; @@ -458,17 +442,17 @@ private void EmitValidateConfigurationKeysMethod() EmitBlankLineIfRequired(); _writer.WriteLine($$""" /// If required by the binder options, validates that there are no unknown keys in the input configuration object. - public static void {{Identifier.ValidateConfigurationKeys}}(Type {{Identifier.type}}, {{MinimalDisplayString.LazyHashSetOfString}} {{keysIdentifier}}, {{Identifier.IConfiguration}} {{Identifier.configuration}}, {{Identifier.BinderOptions}}? {{Identifier.binderOptions}}) + public static void {{Identifier.ValidateConfigurationKeys}}(Type {{Identifier.type}}, {{TypeDisplayString.LazyHashSetOfString}} {{keysIdentifier}}, {{Identifier.IConfiguration}} {{Identifier.configuration}}, {{Identifier.BinderOptions}}? {{Identifier.binderOptions}}) { if ({{Identifier.binderOptions}}?.{{Identifier.ErrorOnUnknownConfiguration}} is true) { - {{MinimalDisplayString.ListOfString}}? {{Identifier.temp}} = null; + {{TypeDisplayString.ListOfString}}? {{Identifier.temp}} = null; foreach ({{Identifier.IConfigurationSection}} {{Identifier.section}} in {{Identifier.configuration}}.{{Identifier.GetChildren}}()) { if (!{{keysIdentifier}}.Value.Contains({{Expression.sectionKey}})) { - ({{Identifier.temp}} ??= new {{MinimalDisplayString.ListOfString}}()).Add($"'{{{Expression.sectionKey}}}'"); + ({{Identifier.temp}} ??= new {{TypeDisplayString.ListOfString}}()).Add($"'{{{Expression.sectionKey}}}'"); } } @@ -490,7 +474,7 @@ private void EmitHasValueOrChildrenMethod() { return true; } - return {{Identifier.AsConfigWithChildren}}({{Identifier.configuration}}) is not null; + return {{MethodsToGen_CoreBindingHelper.AsConfigWithChildren}}({{Identifier.configuration}}) is not null; } """); } @@ -498,7 +482,7 @@ private void EmitHasValueOrChildrenMethod() private void EmitAsConfigWithChildrenMethod() { _writer.WriteLine($$""" - public static {{Identifier.IConfiguration}}? {{Identifier.AsConfigWithChildren}}({{Identifier.IConfiguration}} {{Identifier.configuration}}) + public static {{Identifier.IConfiguration}}? {{MethodsToGen_CoreBindingHelper.AsConfigWithChildren}}({{Identifier.IConfiguration}} {{Identifier.configuration}}) { foreach ({{Identifier.IConfigurationSection}} _ in {{Identifier.configuration}}.{{Identifier.GetChildren}}()) { @@ -512,7 +496,7 @@ private void EmitAsConfigWithChildrenMethod() private void EmitGetBinderOptionsHelper() { _writer.WriteLine($$""" - public static {{Identifier.BinderOptions}}? {{Identifier.GetBinderOptions}}({{MinimalDisplayString.NullableActionOfBinderOptions}} {{Identifier.configureOptions}}) + public static {{Identifier.BinderOptions}}? {{Identifier.GetBinderOptions}}({{TypeDisplayString.NullableActionOfBinderOptions}} {{Identifier.configureOptions}}) { if ({{Identifier.configureOptions}} is null) { @@ -524,7 +508,7 @@ private void EmitGetBinderOptionsHelper() if ({{Identifier.binderOptions}}.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"{{string.Format(ExceptionMessages.CannotSpecifyBindNonPublicProperties)}}"); + throw new NotSupportedException($"{{string.Format(ExceptionMessages.CannotSpecifyBindNonPublicProperties)}}"); } return {{Identifier.binderOptions}}; @@ -534,7 +518,6 @@ private void EmitGetBinderOptionsHelper() private void EmitEnumParseMethod() { - string innerExceptionTypeDisplayString = _useFullyQualifiedNames ? "global::System.Exception" : "Exception"; string exceptionArg1 = string.Format(ExceptionMessages.FailedBinding, $"{{{Identifier.getPath}()}}", $"{{typeof(T)}}"); _writer.WriteLine($$""" @@ -548,9 +531,9 @@ public static T ParseEnum(string value, Func getPath) where T : stru return Enum.Parse(value, ignoreCase: true); #endif } - catch ({{innerExceptionTypeDisplayString}} {{Identifier.exception}}) + catch ({{Identifier.Exception}} {{Identifier.exception}}) { - throw new {{GetInvalidOperationDisplayName()}}($"{{exceptionArg1}}", {{Identifier.exception}}); + throw new {{Identifier.InvalidOperationException}}($"{{exceptionArg1}}", {{Identifier.exception}}); } } """); @@ -558,29 +541,12 @@ public static T ParseEnum(string value, Func getPath) where T : stru private void EmitPrimitiveParseMethod(ParsableFromStringSpec type) { - string innerExceptionTypeDisplayString; - string cultureInfoTypeDisplayString; - string numberStylesTypeDisplayString; - - if (_useFullyQualifiedNames) - { - innerExceptionTypeDisplayString = "global::System.Exception"; - cultureInfoTypeDisplayString = "global::System.Globalization.CultureInfo"; - numberStylesTypeDisplayString = "global::System.Globalization.NumberStyles"; - } - else - { - innerExceptionTypeDisplayString = "Exception"; - cultureInfoTypeDisplayString = "CultureInfo"; - numberStylesTypeDisplayString = "NumberStyles"; - } - StringParsableTypeKind typeKind = type.StringParsableTypeKind; - string typeDisplayString = type.MinimalDisplayString; - - string invariantCultureExpression = $"{cultureInfoTypeDisplayString}.InvariantCulture"; + string typeDisplayString = type.DisplayString; + string invariantCultureExpression = $"{Identifier.CultureInfo}.InvariantCulture"; string parsedValueExpr; + switch (typeKind) { case StringParsableTypeKind.Enum: @@ -592,12 +558,12 @@ private void EmitPrimitiveParseMethod(ParsableFromStringSpec type) break; case StringParsableTypeKind.Integer: { - parsedValueExpr = $"{typeDisplayString}.{Identifier.Parse}({Identifier.value}, {numberStylesTypeDisplayString}.Integer, {invariantCultureExpression})"; + parsedValueExpr = $"{typeDisplayString}.{Identifier.Parse}({Identifier.value}, {Identifier.NumberStyles}.Integer, {invariantCultureExpression})"; } break; case StringParsableTypeKind.Float: { - parsedValueExpr = $"{typeDisplayString}.{Identifier.Parse}({Identifier.value}, {numberStylesTypeDisplayString}.Float, {invariantCultureExpression})"; + parsedValueExpr = $"{typeDisplayString}.{Identifier.Parse}({Identifier.value}, {Identifier.NumberStyles}.Float, {invariantCultureExpression})"; } break; case StringParsableTypeKind.Parse: @@ -612,7 +578,7 @@ private void EmitPrimitiveParseMethod(ParsableFromStringSpec type) break; case StringParsableTypeKind.CultureInfo: { - parsedValueExpr = $"{cultureInfoTypeDisplayString}.GetCultureInfo({Identifier.value})"; + parsedValueExpr = $"{Identifier.CultureInfo}.GetCultureInfo({Identifier.value})"; } break; case StringParsableTypeKind.Uri: @@ -635,9 +601,9 @@ private void EmitPrimitiveParseMethod(ParsableFromStringSpec type) { return {{parsedValueExpr}}; } - catch ({{innerExceptionTypeDisplayString}} {{Identifier.exception}}) + catch ({{Identifier.Exception}} {{Identifier.exception}}) { - throw new {{GetInvalidOperationDisplayName()}}($"{{exceptionArg1}}", {{Identifier.exception}}); + throw new {{Identifier.InvalidOperationException}}($"{{exceptionArg1}}", {{Identifier.exception}}); } """); } @@ -722,13 +688,13 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr) if (keyType.StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue) { // Save value to local to avoid parsing twice - during look-up and during add. - _writer.WriteLine($"{keyType.MinimalDisplayString} {Identifier.key} = {parsedKeyExpr};"); + _writer.WriteLine($"{keyType.DisplayString} {Identifier.key} = {parsedKeyExpr};"); parsedKeyExpr = Identifier.key; } bool isValueType = elementType.IsValueType; string expressionForElementIsNotNull = $"{Identifier.element} is not null"; - string elementTypeDisplayString = elementType.MinimalDisplayString + (elementType.IsValueType ? string.Empty : "?"); + string elementTypeDisplayString = elementType.DisplayString + (elementType.IsValueType ? string.Empty : "?"); string expressionForElementExists = $"{objIdentifier}.{Identifier.TryGetValue}({parsedKeyExpr}, out {elementTypeDisplayString} {Identifier.element})"; string conditionToUseExistingElement = expressionForElementExists; @@ -749,7 +715,7 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr) // we need to copy its contents into a new instance & then append/bind to that. string initExpression = collectionSpec.InitializationStrategy is InitializationStrategy.ParameterizedConstructor - ? $"new {collectionSpec.ConcreteType.MinimalDisplayString}({Identifier.element})" + ? $"new {collectionSpec.ConcreteType.DisplayString}({Identifier.element})" : $"{Identifier.element}.{collectionSpec.ToEnumerableMethodCall!}"; _writer.WriteLine($$""" @@ -773,7 +739,7 @@ private void EmitBindCoreImplForObject(ObjectSpec type) Debug.Assert(type.NeedsMemberBinding); string keyCacheFieldName = GetConfigKeyCacheFieldName(type); - string validateMethodCallExpr = $"{Identifier.ValidateConfigurationKeys}(typeof({type.MinimalDisplayString}), {keyCacheFieldName}, {Identifier.configuration}, {Identifier.binderOptions});"; + string validateMethodCallExpr = $"{Identifier.ValidateConfigurationKeys}(typeof({type.DisplayString}), {keyCacheFieldName}, {Identifier.configuration}, {Identifier.binderOptions});"; _writer.WriteLine(validateMethodCallExpr); foreach (PropertySpec property in type.Properties.Values) @@ -781,7 +747,7 @@ private void EmitBindCoreImplForObject(ObjectSpec type) bool noSetter_And_IsReadonly = !property.CanSet && property.Type is CollectionSpec { InitializationStrategy: InitializationStrategy.ParameterizedConstructor }; if (property.ShouldBind() && !noSetter_And_IsReadonly) { - string containingTypeRef = property.IsStatic ? type.MinimalDisplayString : Identifier.obj; + string containingTypeRef = property.IsStatic ? type.DisplayString : Identifier.obj; EmitBindImplForMember( property, memberAccessExpr: $"{containingTypeRef}.{property.Name}", @@ -832,7 +798,7 @@ private bool EmitBindImplForMember( return true; } - string sectionValidationCall = $"{Identifier.AsConfigWithChildren}({sectionParseExpr})"; + string sectionValidationCall = $"{MethodsToGen_CoreBindingHelper.AsConfigWithChildren}({sectionParseExpr})"; string sectionIdentifier = GetIncrementalIdentifier(Identifier.section); EmitStartBlock($"if ({sectionValidationCall} is {Identifier.IConfigurationSection} {sectionIdentifier})"); @@ -869,14 +835,14 @@ private void EmitBindCoreCallForMember( } Debug.Assert(canSet); - string effectiveMemberTypeDisplayString = effectiveMemberType.MinimalDisplayString; + string effectiveMemberTypeDisplayString = effectiveMemberType.DisplayString; initKind = InitializationKind.None; if (memberType.SpecKind is TypeSpecKind.Nullable) { string nullableTempIdentifier = GetIncrementalIdentifier(Identifier.temp); - _writer.WriteLine($"{memberType.MinimalDisplayString} {nullableTempIdentifier} = {memberAccessExpr};"); + _writer.WriteLine($"{memberType.DisplayString} {nullableTempIdentifier} = {memberAccessExpr};"); _writer.WriteLine( $"{effectiveMemberTypeDisplayString} {tempIdentifier} = {nullableTempIdentifier}.{Identifier.HasValue} ? {nullableTempIdentifier}.{Identifier.Value} : new {effectiveMemberTypeDisplayString}();"); @@ -924,7 +890,7 @@ private void EmitCollectionCastIfRequired(CollectionSpec type, out string objIde { objIdentifier = Identifier.temp; _writer.WriteLine($$""" - if ({{Identifier.obj}} is not {{type.PopulationCastType!.MinimalDisplayString}} {{objIdentifier}}) + if ({{Identifier.obj}} is not {{type.PopulationCastType!.DisplayString}} {{objIdentifier}}) { return; } @@ -936,20 +902,31 @@ private void EmitCollectionCastIfRequired(CollectionSpec type, out string objIde private void Emit_Foreach_Section_In_ConfigChildren_StartBlock() => EmitStartBlock($"foreach ({Identifier.IConfigurationSection} {Identifier.section} in {Identifier.configuration}.{Identifier.GetChildren}())"); + private void Emit_NotSupportedException_TypeNotDetectedAsInput() => + _writer.WriteLine(@$"throw new NotSupportedException($""{string.Format(ExceptionMessages.TypeNotDetectedAsInput, "{type}")}"");"); + private static string GetSectionPathFromConfigurationExpression(string configurationKeyName) => $@"{GetSectionFromConfigurationExpression(configurationKeyName)}.{Identifier.Path}"; private static string GetSectionFromConfigurationExpression(string configurationKeyName, bool addQuotes = true) { string argExpr = addQuotes ? $@"""{configurationKeyName}""" : configurationKeyName; - return $@"{Expression.configurationGetSection}({argExpr})"; + return $@"{Identifier.configuration}.{Identifier.GetSection}({argExpr})"; } - private static string GetConfigKeyCacheFieldName(ObjectSpec type) => - $"s_configKeys_{type.DisplayStringWithoutSpecialCharacters}"; + private static string GetConditionKindExpr(ref bool isFirstType) + { + if (isFirstType) + { + isFirstType = false; + return "if"; + } - private void Emit_NotSupportedException_TypeNotDetectedAsInput() => - _writer.WriteLine(@$"throw new global::System.NotSupportedException($""{string.Format(ExceptionMessages.TypeNotDetectedAsInput, "{type}")}"");"); + return "else if"; + } + + private static string GetConfigKeyCacheFieldName(ObjectSpec type) => + $"s_configKeys_{type.DisplayString.ToIdentifierSubstring()}"; } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs index e0e6a36aabaa7c..bad56b7ce3275a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Collections.Generic; using System.Diagnostics; using System.Reflection; @@ -10,7 +12,9 @@ public sealed partial class ConfigurationBindingGenerator { private sealed partial class Emitter { - private static readonly AssemblyName s_assemblyName = typeof(Emitter).Assembly.GetName(); + private string? _emittedExtsTargetType; + + internal static readonly AssemblyName s_assemblyName = typeof(ConfigurationBindingGenerator).Assembly.GetName(); private enum InitializationKind { @@ -26,29 +30,13 @@ private static class Expression public const string sectionPath = "section.Path"; public const string sectionValue = "section.Value"; - public const string GetBinderOptions = $"{FullyQualifiedDisplayString.CoreBindingHelper}.{Identifier.GetBinderOptions}"; - } - - private static class FullyQualifiedDisplayString - { - public const string ActionOfBinderOptions = $"global::System.Action"; - public const string AddSingleton = $"{ServiceCollectionServiceExtensions}.AddSingleton"; - public const string ConfigurationChangeTokenSource = "global::Microsoft.Extensions.Options.ConfigurationChangeTokenSource"; - public const string CoreBindingHelper = $"global::{ProjectName}.{Identifier.CoreBindingHelper}"; - public const string IConfiguration = "global::Microsoft.Extensions.Configuration.IConfiguration"; - public const string IConfigurationSection = IConfiguration + "Section"; - public const string IOptionsChangeTokenSource = "global::Microsoft.Extensions.Options.IOptionsChangeTokenSource"; - public const string InvalidOperationException = "global::System.InvalidOperationException"; - public const string IServiceCollection = "global::Microsoft.Extensions.DependencyInjection.IServiceCollection"; - public const string NotSupportedException = "global::System.NotSupportedException"; - public const string OptionsBuilderOfTOptions = $"global::Microsoft.Extensions.Options.OptionsBuilder<{Identifier.TOptions}>"; - public const string ServiceCollectionServiceExtensions = "global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions"; - public const string Type = $"global::System.Type"; + public static string GeneratedCodeAnnotation = $@"[GeneratedCode(""{s_assemblyName.Name}"", ""{s_assemblyName.Version}"")]"; } - private static class MinimalDisplayString + private static class TypeDisplayString { public const string NullableActionOfBinderOptions = "Action?"; + public const string OptionsBuilderOfTOptions = $"OptionsBuilder<{Identifier.TOptions}>"; public const string HashSetOfString = "HashSet"; public const string LazyHashSetOfString = "Lazy>"; public const string ListOfString = "List"; @@ -75,6 +63,7 @@ private static class Identifier public const string services = nameof(services); public const string temp = nameof(temp); public const string type = nameof(type); + public const string typedObj = nameof(typedObj); public const string validateKeys = nameof(validateKeys); public const string value = nameof(value); @@ -82,21 +71,19 @@ private static class Identifier public const string AddSingleton = nameof(AddSingleton); public const string Any = nameof(Any); public const string Array = nameof(Array); - public const string AsConfigWithChildren = nameof(AsConfigWithChildren); public const string Bind = nameof(Bind); public const string BinderOptions = nameof(BinderOptions); + public const string BindingExtensions = nameof(BindingExtensions); + public const string ConfigurationChangeTokenSource = nameof(ConfigurationChangeTokenSource); public const string Configure = nameof(Configure); public const string CopyTo = nameof(CopyTo); public const string ContainsKey = nameof(ContainsKey); - public const string CoreBindingHelper = nameof(CoreBindingHelper); public const string Count = nameof(Count); public const string CultureInfo = nameof(CultureInfo); public const string CultureNotFoundException = nameof(CultureNotFoundException); public const string Enum = nameof(Enum); public const string ErrorOnUnknownConfiguration = nameof(ErrorOnUnknownConfiguration); - public const string GeneratedConfigurationBinder = nameof(GeneratedConfigurationBinder); - public const string GeneratedOptionsBuilderBinder = nameof(GeneratedOptionsBuilderBinder); - public const string GeneratedServiceCollectionBinder = nameof(GeneratedServiceCollectionBinder); + public const string Exception = nameof(Exception); public const string Get = nameof(Get); public const string GetBinderOptions = nameof(GetBinderOptions); public const string GetChildren = nameof(GetChildren); @@ -108,9 +95,13 @@ private static class Identifier public const string IConfiguration = nameof(IConfiguration); public const string IConfigurationSection = nameof(IConfigurationSection); public const string Int32 = "int"; + public const string InterceptsLocation = nameof(InterceptsLocation); public const string InvalidOperationException = nameof(InvalidOperationException); public const string InvariantCulture = nameof(InvariantCulture); + public const string IOptionsChangeTokenSource = nameof(IOptionsChangeTokenSource); + public const string IServiceCollection = nameof(IServiceCollection); public const string Length = nameof(Length); + public const string NumberStyles = nameof(NumberStyles); public const string Parse = nameof(Parse); public const string Path = nameof(Path); public const string Resize = nameof(Resize); @@ -118,17 +109,66 @@ private static class Identifier public const string TOptions = nameof(TOptions); public const string TryCreate = nameof(TryCreate); public const string TryGetValue = nameof(TryGetValue); - public const string TryParse = nameof(TryParse); + public const string Type = nameof(Type); public const string Uri = nameof(Uri); public const string ValidateConfigurationKeys = nameof(ValidateConfigurationKeys); public const string Value = nameof(Value); } - private bool ShouldEmitBinders() => + private bool ShouldEmitBindingExtensions() => ShouldEmitMethods(MethodsToGen_ConfigurationBinder.Any) || ShouldEmitMethods(MethodsToGen_Extensions_OptionsBuilder.Any) || ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Any); + private void EmitInterceptsLocationAnnotations(Enum generatedBindingOverload) + { + // The only time a generated binding method won't have any locations to + // intercept is when either of these methods are used as helpers for + // other generated OptionsBuilder or ServiceCollection binding extensions. + bool interceptsCalls = _sourceGenSpec.InterceptionInfo.TryGetValue(generatedBindingOverload, out List? infoList); + Debug.Assert(interceptsCalls || + generatedBindingOverload is MethodsToGen_Extensions_ServiceCollection.Configure_T_name_BinderOptions || + generatedBindingOverload is MethodsToGen_Extensions_OptionsBuilder.Bind_T_BinderOptions); + + if (interceptsCalls) + { + EmitInterceptsLocationAnnotations(infoList); + } + } + + private void EmitInterceptsLocationAnnotations(List infoList) + { + foreach (InterceptorLocationInfo info in infoList) + { + _writer.WriteLine($@"[{Identifier.InterceptsLocation}Attribute(@""{info.FilePath}"", {info.LineNumber}, {info.CharacterNumber})]"); + } + } + + private void EmitBindingExtStartRegion(string targetType) + { + Debug.Assert(_emittedExtsTargetType is null); + + EmitBlankLineIfRequired(); + _emittedExtsTargetType = targetType; + EmitBindingExtRegionText(isStart: true); + _emitBlankLineBeforeNextStatement = false; + } + + private void EmitBindingExtEndRegion() + { + Debug.Assert(_emittedExtsTargetType is not null); + + EmitBindingExtRegionText(isStart: false); + _emittedExtsTargetType = null; + _emitBlankLineBeforeNextStatement = true; + } + + private void EmitBindingExtRegionText(bool isStart) + { + string endSource = isStart ? string.Empty : "end"; + _writer.WriteLine($"#{endSource}region {_emittedExtsTargetType} extensions."); + } + /// /// Starts a block of source code. /// @@ -171,24 +211,12 @@ private void EmitBlankLineIfRequired() _emitBlankLineBeforeNextStatement = true; } - private void EmitCheckForNullArgument_WithBlankLine_IfRequired(bool isValueType) - { - if (!isValueType) - { - EmitCheckForNullArgument_WithBlankLine(Identifier.obj); - } - } - private void EmitCheckForNullArgument_WithBlankLine(string paramName) { - string exceptionTypeDisplayString = _useFullyQualifiedNames - ? "global::System.ArgumentNullException" - : "ArgumentNullException"; - _writer.WriteLine($$""" if ({{paramName}} is null) { - throw new {{exceptionTypeDisplayString}}(nameof({{paramName}})); + throw new ArgumentNullException(nameof({{paramName}})); } """); @@ -201,51 +229,28 @@ private bool EmitInitException(TypeSpec type) if (!type.CanInitialize) { - _writer.WriteLine(GetInitException(type.InitExceptionMessage) + ";"); + _writer.WriteLine($@"throw new {Identifier.InvalidOperationException}(""{type.InitExceptionMessage}"");"); return true; } return false; } - private void EmitRootBindingClassStartBlock(string className) - { - EmitBlankLineIfRequired(); - EmitStartBlock($$""" - /// Generated helper providing an AOT and linking compatible implementation for configuration binding. - {{GetGeneratedCodeAttributeSrc()}} - internal static class {{className}} - """); - - _emitBlankLineBeforeNextStatement = false; - } - - private string GetGeneratedCodeAttributeSrc() - { - string attributeRefExpr = _useFullyQualifiedNames ? $"global::System.CodeDom.Compiler.GeneratedCodeAttribute" : "GeneratedCode"; - return $@"[{attributeRefExpr}(""{s_assemblyName.Name}"", ""{s_assemblyName.Version}"")]"; - } - - private string GetInitException(string message) => $@"throw new {GetInvalidOperationDisplayName()}(""{message}"")"; - private string GetIncrementalIdentifier(string prefix) => $"{prefix}{_valueSuffixIndex++}"; - private string GetInitalizeMethodDisplayString(ObjectSpec type) => - GetHelperMethodDisplayString($"{nameof(MethodsToGen_CoreBindingHelper.Initialize)}{type.DisplayStringWithoutSpecialCharacters}"); - - private string GetTypeDisplayString(TypeSpec type) => _useFullyQualifiedNames ? type.FullyQualifiedDisplayString : type.MinimalDisplayString; - - private string GetHelperMethodDisplayString(string methodName) - { - if (_useFullyQualifiedNames) - { - methodName = FullyQualifiedDisplayString.CoreBindingHelper + "." + methodName; - } - - return methodName; - } - - private string GetInvalidOperationDisplayName() => _useFullyQualifiedNames ? FullyQualifiedDisplayString.InvalidOperationException : Identifier.InvalidOperationException; + private static string GetInitalizeMethodDisplayString(ObjectSpec type) => + $"{nameof(MethodsToGen_CoreBindingHelper.Initialize)}{type.DisplayString.ToIdentifierSubstring()}"; } } + + internal static class EmitterExtensions + { + public static string ToIdentifierSubstring(this string typeDisplayName) => + typeDisplayName + .Replace("[]", nameof(Array)) + .Replace(", ", string.Empty) + .Replace(".", string.Empty) + .Replace("<", string.Empty) + .Replace(">", string.Empty); + } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs index 71d0b6989dd970..d49198196fd491 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs @@ -9,19 +9,17 @@ private sealed partial class Emitter { private bool ShouldEmitMethods(MethodsToGen_Extensions_OptionsBuilder methods) => (_sourceGenSpec.MethodsToGen_OptionsBuilderExt & methods) != 0; - private void EmitBinder_Extensions_OptionsBuilder() + private void EmitBindingExtensions_OptionsBuilder() { if (!ShouldEmitMethods(MethodsToGen_Extensions_OptionsBuilder.Any)) { return; } - EmitRootBindingClassStartBlock(Identifier.GeneratedOptionsBuilderBinder); - + EmitBindingExtStartRegion(TypeDisplayString.OptionsBuilderOfTOptions); EmitBindMethods_Extensions_OptionsBuilder(); EmitBindConfigurationMethod(); - - EmitEndBlock(); + EmitBindingExtEndRegion(); } private void EmitBindMethods_Extensions_OptionsBuilder() @@ -32,24 +30,25 @@ private void EmitBindMethods_Extensions_OptionsBuilder() } const string documentation = @"/// Registers a configuration instance which will bind against."; - const string paramList = $"{FullyQualifiedDisplayString.IConfiguration} {Identifier.configuration}"; + const string paramList = $"{Identifier.IConfiguration} {Identifier.configuration}"; if (ShouldEmitMethods(MethodsToGen_Extensions_OptionsBuilder.Bind_T)) { - EmitMethodStartBlock("Bind", paramList, documentation); - _writer.WriteLine($"return global::{Identifier.GeneratedOptionsBuilderBinder}.Bind({Identifier.optionsBuilder}, {Identifier.configuration}, {Identifier.configureOptions}: null);"); + EmitMethodStartBlock(MethodsToGen_Extensions_OptionsBuilder.Bind_T, "Bind", paramList, documentation); + _writer.WriteLine($"return Bind({Identifier.optionsBuilder}, {Identifier.configuration}, {Identifier.configureOptions}: null);"); EmitEndBlock(); } EmitMethodStartBlock( + MethodsToGen_Extensions_OptionsBuilder.Bind_T_BinderOptions, "Bind", - paramList + $", {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions}", + paramList + $", {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions}", documentation); EmitCheckForNullArgument_WithBlankLine(Identifier.optionsBuilder); _writer.WriteLine($$""" - global::{{Identifier.GeneratedServiceCollectionBinder}}.{{Identifier.Configure}}<{{Identifier.TOptions}}>({{Identifier.optionsBuilder}}.{{Identifier.Services}}, {{Identifier.optionsBuilder}}.Name, {{Identifier.configuration}}, {{Identifier.configureOptions}}); + {{Identifier.Configure}}<{{Identifier.TOptions}}>({{Identifier.optionsBuilder}}.{{Identifier.Services}}, {{Identifier.optionsBuilder}}.Name, {{Identifier.configuration}}, {{Identifier.configureOptions}}); return {{Identifier.optionsBuilder}}; """); @@ -63,19 +62,20 @@ private void EmitBindConfigurationMethod() return; } - const string documentation = $@"/// Registers the dependency injection container to bind against the obtained from the DI service provider."; - string paramList = $"string {Identifier.configSectionPath}, {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions} = null"; + const string documentation = $@"/// Registers the dependency injection container to bind against the obtained from the DI service provider."; + string paramList = $"string {Identifier.configSectionPath}, {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions} = null"; - EmitMethodStartBlock("BindConfiguration", paramList, documentation); + EmitMethodStartBlock(MethodsToGen_Extensions_OptionsBuilder.BindConfiguration, "BindConfiguration", paramList, documentation); EmitCheckForNullArgument_WithBlankLine(Identifier.optionsBuilder); EmitCheckForNullArgument_WithBlankLine(Identifier.configSectionPath); - EmitStartBlock($"{Identifier.optionsBuilder}.{Identifier.Configure}<{FullyQualifiedDisplayString.IConfiguration}>(({Identifier.obj}, {Identifier.configuration}) =>"); - + EmitStartBlock($"{Identifier.optionsBuilder}.{Identifier.Configure}<{Identifier.IConfiguration}>(({Identifier.obj}, {Identifier.configuration}) =>"); + EmitCheckForNullArgument_WithBlankLine(Identifier.obj); + EmitCheckForNullArgument_WithBlankLine(Identifier.configuration); _writer.WriteLine($$""" - {{FullyQualifiedDisplayString.IConfiguration}} {{Identifier.section}} = string.Equals(string.Empty, {{Identifier.configSectionPath}}, global::System.StringComparison.OrdinalIgnoreCase) ? {{Identifier.configuration}} : {{Identifier.configuration}}.{{Identifier.GetSection}}({{Identifier.configSectionPath}}); - {{FullyQualifiedDisplayString.CoreBindingHelper}}.{{nameof(MethodsToGen_CoreBindingHelper.BindCoreUntyped)}}({{Identifier.section}}, {{Identifier.obj}}, typeof({{Identifier.TOptions}}), {{Identifier.configureOptions}}); + {{Identifier.IConfiguration}} {{Identifier.section}} = string.Equals(string.Empty, {{Identifier.configSectionPath}}, StringComparison.OrdinalIgnoreCase) ? {{Identifier.configuration}} : {{Identifier.configuration}}.{{Identifier.GetSection}}({{Identifier.configSectionPath}}); + {{nameof(MethodsToGen_CoreBindingHelper.BindCoreMain)}}({{Identifier.section}}, {{Identifier.obj}}, typeof({{Identifier.TOptions}}), {{Identifier.configureOptions}}); """); EmitEndBlock(endBraceTrailingSource: ");"); @@ -83,20 +83,20 @@ private void EmitBindConfigurationMethod() _writer.WriteLine(); _writer.WriteLine($$""" - {{FullyQualifiedDisplayString.AddSingleton}}<{{FullyQualifiedDisplayString.IOptionsChangeTokenSource}}<{{Identifier.TOptions}}>, {{FullyQualifiedDisplayString.ConfigurationChangeTokenSource}}<{{Identifier.TOptions}}>>({{Identifier.optionsBuilder}}.{{Identifier.Services}}); + {{Identifier.optionsBuilder}}.{{Identifier.Services}}.{{Identifier.AddSingleton}}<{{Identifier.IOptionsChangeTokenSource}}<{{Identifier.TOptions}}>, {{Identifier.ConfigurationChangeTokenSource}}<{{Identifier.TOptions}}>>(); return {{Identifier.optionsBuilder}}; """); EmitEndBlock(); } - private void EmitMethodStartBlock(string methodName, string paramList, string documentation) + private void EmitMethodStartBlock(MethodsToGen_Extensions_OptionsBuilder method, string methodName, string paramList, string documentation) { - paramList = $"this {FullyQualifiedDisplayString.OptionsBuilderOfTOptions} {Identifier.optionsBuilder}, {paramList}"; - + paramList = $"this {TypeDisplayString.OptionsBuilderOfTOptions} {Identifier.optionsBuilder}, {paramList}"; EmitBlankLineIfRequired(); _writer.WriteLine(documentation); - EmitStartBlock($"public static {FullyQualifiedDisplayString.OptionsBuilderOfTOptions} {methodName}<{Identifier.TOptions}>({paramList}) where {Identifier.TOptions} : class"); + EmitInterceptsLocationAnnotations(method); + EmitStartBlock($"public static {TypeDisplayString.OptionsBuilderOfTOptions} {methodName}<{Identifier.TOptions}>({paramList}) where {Identifier.TOptions} : class"); } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs index f4cd4800df1230..0348eb5047e970 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs @@ -9,71 +9,72 @@ private sealed partial class Emitter { private bool ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection methods) => (_sourceGenSpec.MethodsToGen_ServiceCollectionExt & methods) != 0; - private void EmitBinder_Extensions_IServiceCollection() + private void EmitBindingExtensions_IServiceCollection() { if (!ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Any)) { return; } - EmitRootBindingClassStartBlock(Identifier.GeneratedServiceCollectionBinder); + EmitBindingExtStartRegion(Identifier.IServiceCollection); + EmitConfigureMethods(); + EmitBindingExtEndRegion(); + } + private void EmitConfigureMethods() + { const string defaultNameExpr = "string.Empty"; - const string configureMethodString = $"global::{Identifier.GeneratedServiceCollectionBinder}.{Identifier.Configure}"; - string configParam = $"{FullyQualifiedDisplayString.IConfiguration} {Identifier.configuration}"; + string configParam = $"{Identifier.IConfiguration} {Identifier.configuration}"; if (ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Configure_T)) { - EmitStartMethod(configParam); - _writer.WriteLine($"return {configureMethodString}<{Identifier.TOptions}>({Identifier.services}, {defaultNameExpr}, {Identifier.configuration}, {Identifier.configureOptions}: null);"); + EmitStartMethod(MethodsToGen_Extensions_ServiceCollection.Configure_T, configParam); + _writer.WriteLine($"return {Identifier.Configure}<{Identifier.TOptions}>({Identifier.services}, {defaultNameExpr}, {Identifier.configuration}, {Identifier.configureOptions}: null);"); EmitEndBlock(); } if (ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Configure_T_name)) { EmitStartMethod( + MethodsToGen_Extensions_ServiceCollection.Configure_T_name, paramList: $"string? {Identifier.name}, " + configParam); - _writer.WriteLine($"return {configureMethodString}<{Identifier.TOptions}>({Identifier.services}, {Identifier.name}, {Identifier.configuration}, {Identifier.configureOptions}: null);"); + _writer.WriteLine($"return {Identifier.Configure}<{Identifier.TOptions}>({Identifier.services}, {Identifier.name}, {Identifier.configuration}, {Identifier.configureOptions}: null);"); EmitEndBlock(); } if (ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Configure_T_BinderOptions)) { EmitStartMethod( - paramList: configParam + $", {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions}"); - _writer.WriteLine($"return {configureMethodString}<{Identifier.TOptions}>({Identifier.services}, {defaultNameExpr}, {Identifier.configuration}, {Identifier.configureOptions});"); + MethodsToGen_Extensions_ServiceCollection.Configure_T_BinderOptions, + paramList: configParam + $", {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions}"); + _writer.WriteLine($"return {Identifier.Configure}<{Identifier.TOptions}>({Identifier.services}, {defaultNameExpr}, {Identifier.configuration}, {Identifier.configureOptions});"); EmitEndBlock(); } // Core Configure method that the other overloads call. // Like the others, it is public API that could be called directly by users. // So, it is always generated whenever a Configure overload is called. - string optionsNamespaceName = "global::Microsoft.Extensions.Options"; - string bindCoreUntypedDisplayString = GetHelperMethodDisplayString(nameof(MethodsToGen_CoreBindingHelper.BindCoreUntyped)); + string optionsNamespaceName = "Microsoft.Extensions.Options"; - EmitStartMethod(paramList: $"string? {Identifier.name}, " + configParam + $", {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions}"); + EmitStartMethod(MethodsToGen_Extensions_ServiceCollection.Configure_T_name_BinderOptions, paramList: $"string? {Identifier.name}, " + configParam + $", {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions}"); EmitCheckForNullArgument_WithBlankLine(Identifier.services); EmitCheckForNullArgument_WithBlankLine(Identifier.configuration); _writer.WriteLine($$""" - global::Microsoft.Extensions.DependencyInjection.OptionsServiceCollectionExtensions.AddOptions({{Identifier.services}}); - {{FullyQualifiedDisplayString.AddSingleton}}<{{FullyQualifiedDisplayString.IOptionsChangeTokenSource}}<{{Identifier.TOptions}}>>({{Identifier.services}}, new {{FullyQualifiedDisplayString.ConfigurationChangeTokenSource}}<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.configuration}})); - return {{FullyQualifiedDisplayString.AddSingleton}}<{{optionsNamespaceName}}.IConfigureOptions<{{Identifier.TOptions}}>>({{Identifier.services}}, new {{optionsNamespaceName}}.ConfigureNamedOptions<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.obj}} => {{bindCoreUntypedDisplayString}}({{Identifier.configuration}}, {{Identifier.obj}}, typeof({{Identifier.TOptions}}), {{Identifier.configureOptions}}))); + OptionsServiceCollectionExtensions.AddOptions({{Identifier.services}}); + {{Identifier.services}}.{{Identifier.AddSingleton}}<{{Identifier.IOptionsChangeTokenSource}}<{{Identifier.TOptions}}>>(new {{Identifier.ConfigurationChangeTokenSource}}<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.configuration}})); + return {{Identifier.services}}.{{Identifier.AddSingleton}}<{{optionsNamespaceName}}.IConfigureOptions<{{Identifier.TOptions}}>>(new {{optionsNamespaceName}}.ConfigureNamedOptions<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.obj}} => {{nameof(MethodsToGen_CoreBindingHelper.BindCoreMain)}}({{Identifier.configuration}}, {{Identifier.obj}}, typeof({{Identifier.TOptions}}){{Identifier.configureOptions}}))); """); EmitEndBlock(); - - EmitEndBlock(); - _emitBlankLineBeforeNextStatement = true; } - private void EmitStartMethod(string paramList) + private void EmitStartMethod(MethodsToGen_Extensions_ServiceCollection overload, string paramList) { - paramList = $"this {FullyQualifiedDisplayString.IServiceCollection} {Identifier.services}, {paramList}"; + paramList = $"this {Identifier.IServiceCollection} {Identifier.services}, {paramList}"; EmitBlankLineIfRequired(); - EmitStartBlock($$""" - /// Registers a configuration instance which TOptions will bind against. - public static {{FullyQualifiedDisplayString.IServiceCollection}} {{Identifier.Configure}}<{{Identifier.TOptions}}>({{paramList}}) where {{Identifier.TOptions}} : class - """); + _writer.WriteLine("/// Registers a configuration instance which TOptions will bind against."); + EmitInterceptsLocationAnnotations(overload); + EmitStartBlock($"public static {Identifier.IServiceCollection} {Identifier.Configure}<{Identifier.TOptions}>({paramList}) where {Identifier.TOptions} : class"); } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/InterceptorLocationInfo.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/InterceptorLocationInfo.cs new file mode 100644 index 00000000000000..d1dc4f4afa7e7e --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/InterceptorLocationInfo.cs @@ -0,0 +1,90 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections; +using System.Collections.Generic; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Operations; +using Microsoft.CodeAnalysis.Text; + +namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration +{ + internal sealed record InterceptorLocationInfo + { + public InterceptorLocationInfo(IInvocationOperation operation) + { + SyntaxNode operationSyntax = operation.Syntax; + TextSpan operationSpan = operationSyntax.Span; + SyntaxTree operationSyntaxTree = operationSyntax.SyntaxTree; + + FilePath = GetInterceptorFilePath(operationSyntaxTree, operation.SemanticModel?.Compilation.Options.SourceReferenceResolver); + + FileLinePositionSpan span = operationSyntaxTree.GetLineSpan(operationSpan); + LineNumber = span.StartLinePosition.Line + 1; + + // Calculate the character offset to the end of the binding invocation detected. + int invocationLength = ((MemberAccessExpressionSyntax)((InvocationExpressionSyntax)operationSyntax).Expression).Expression.Span.Length; + CharacterNumber = span.StartLinePosition.Character + invocationLength + 2; + } + + public string FilePath { get; } + public int LineNumber { get; } + public int CharacterNumber { get; } + + // Utilize the same logic used by the interceptors API for resolving the source mapped value of a path. + // https://github.com/dotnet/roslyn/blob/f290437fcc75dad50a38c09e0977cce13a64f5ba/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs#L1063-L1064 + private static string GetInterceptorFilePath(SyntaxTree tree, SourceReferenceResolver? resolver) => + resolver?.NormalizePath(tree.FilePath, baseFilePath: null) ?? tree.FilePath; + } + + internal sealed record ConfigurationBinderInterceptorInfo + { + private OverloadInterceptorInfo? _bind_Instance; + private OverloadInterceptorInfo? _bind_instance_BinderOptions; + private OverloadInterceptorInfo? _bind_key_instance; + + public void RegisterOverloadInfo(MethodsToGen_ConfigurationBinder overload, TypeSpec type, IInvocationOperation operation) + { + OverloadInterceptorInfo overloadInfo = DetermineOverload(overload, initIfNull: true); + overloadInfo.RegisterLocationInfo(type, operation); + } + + public OverloadInterceptorInfo GetOverloadInfo(MethodsToGen_ConfigurationBinder overload) => + DetermineOverload(overload, initIfNull: false) ?? throw new ArgumentNullException(nameof(overload)); + + private OverloadInterceptorInfo? DetermineOverload(MethodsToGen_ConfigurationBinder overload, bool initIfNull) + { + return overload switch + { + MethodsToGen_ConfigurationBinder.Bind_instance => InitIfNull(ref _bind_Instance), + MethodsToGen_ConfigurationBinder.Bind_instance_BinderOptions => InitIfNull(ref _bind_instance_BinderOptions), + MethodsToGen_ConfigurationBinder.Bind_key_instance => InitIfNull(ref _bind_key_instance), + _ => throw new InvalidOperationException(nameof(overload)), + }; + + OverloadInterceptorInfo InitIfNull(ref OverloadInterceptorInfo? info) + { + if (initIfNull) + { + info ??= new OverloadInterceptorInfo(); + } + + return info; + } + } + } + + internal sealed record OverloadInterceptorInfo : IEnumerable>> + { + private readonly Dictionary> _typeInterceptionInfo = new(); + + public void RegisterLocationInfo(TypeSpec type, IInvocationOperation operation) => + _typeInterceptionInfo.RegisterCacheEntry(type, new InterceptorLocationInfo(operation)); + + public IEnumerator>> GetEnumerator() => _typeInterceptionInfo.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/MethodsToGen.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/MethodsToGen.cs index 7b40f198e08f23..2c582b20e8ebd6 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/MethodsToGen.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/MethodsToGen.cs @@ -10,11 +10,12 @@ public enum MethodsToGen_CoreBindingHelper { None = 0x0, BindCore = 0x1, - BindCoreUntyped = 0x2, - GetCore = 0x4, - GetValueCore = 0x8, + GetCore = 0x2, + GetValueCore = 0x4, + BindCoreMain = 0x8, Initialize = 0x10, - AsConfigWithChildren = 0x20, + HasValueOrChildren = 0x20, + AsConfigWithChildren = 0x40, } /// diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/BinderInvocation.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/BinderInvocation.cs index 554786589c8c81..ad7c4c09204d4b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/BinderInvocation.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/BinderInvocation.cs @@ -40,7 +40,7 @@ static bool IsCandidateBindingMethodName(string name) => IsValidMethodName_OptionsConfigurationServiceCollectionExtensions(name); } - private static bool IsBindingOperation(IInvocationOperation operation) + public static bool IsBindingOperation(IInvocationOperation operation) { if (operation.TargetMethod is not IMethodSymbol { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/ConfigurationBinder.cs index a663c441c55ce3..e24ce11fe4374c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/ConfigurationBinder.cs @@ -102,15 +102,7 @@ private void RegisterBindInvocation(BinderInvocation invocation) if (GetTargetTypeForRootInvocationCore(type, invocation.Location) is TypeSpec typeSpec) { - Dictionary> types = _sourceGenSpec.TypesForGen_ConfigurationBinder_BindMethods; - - if (!types.TryGetValue(overload, out HashSet? typeSpecs)) - { - types[overload] = typeSpecs = new HashSet(); - } - - _sourceGenSpec.MethodsToGen_ConfigurationBinder |= overload; - typeSpecs.Add(typeSpec); + RegisterAsInterceptor_ConfigBinder_BindMethod(overload, typeSpec, invocation.Operation); } static ITypeSymbol? ResolveType(IOperation conversionOperation) => @@ -184,8 +176,8 @@ private void RegisterGetInvocation(BinderInvocation invocation) if (GetTargetTypeForRootInvocation(type, invocation.Location) is TypeSpec typeSpec) { - _sourceGenSpec.MethodsToGen_ConfigurationBinder |= overload; - RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.GetCore, typeSpec); + RegisterAsInterceptor_ConfigBinder(overload, invocation.Operation); + RegisterTypeForGetCoreGen(typeSpec); } } @@ -253,10 +245,27 @@ private void RegisterGetValueInvocation(BinderInvocation invocation) if (IsParsableFromString(effectiveType, out _) && GetTargetTypeForRootInvocationCore(type, invocation.Location) is TypeSpec typeSpec) { - _sourceGenSpec.MethodsToGen_ConfigurationBinder |= overload; + RegisterAsInterceptor_ConfigBinder(overload, invocation.Operation); RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.GetValueCore, typeSpec); } } + + private void RegisterAsInterceptor_ConfigBinder(MethodsToGen_ConfigurationBinder overload, IInvocationOperation operation) + { + _sourceGenSpec.MethodsToGen_ConfigurationBinder |= overload; + RegisterAsInterceptor(overload, operation); + } + + /// + /// Registers generated Bind methods as interceptors. This is done differently from other root + /// methods because we need to + /// explicitly account for the type to bind, to avoid type-check issues for polymorphic objects. + /// + private void RegisterAsInterceptor_ConfigBinder_BindMethod(MethodsToGen_ConfigurationBinder overload, TypeSpec typeSpec, IInvocationOperation operation) + { + _sourceGenSpec.MethodsToGen_ConfigurationBinder |= overload; + _sourceGenSpec.InterceptionInfo_ConfigBinder.RegisterOverloadInfo(overload, typeSpec, operation); + } } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsBuilderConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsBuilderConfigurationExtensions.cs index d01e80d708ca11..a62e63c0d90d5e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsBuilderConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsBuilderConfigurationExtensions.cs @@ -34,9 +34,6 @@ private void RegisterMethodInvocation_OptionsBuilderExt(BinderInvocation invocat return; } - // We are going to emit calls to APIs on IServiceCollection. - _sourceGenSpec.TypeNamespaces.Add("Microsoft.Extensions.DependencyInjection"); - if (targetMethod.Name is "Bind") { RegisterBindInvocation(invocation, typeSpec); @@ -61,20 +58,19 @@ private void RegisterBindInvocation(BinderInvocation invocation, TypeSpec typeSp return; } - if (paramCount is 2) - { - _sourceGenSpec.MethodsToGen_OptionsBuilderExt |= MethodsToGen_Extensions_OptionsBuilder.Bind_T; - } - else if (paramCount is 3 && SymbolEqualityComparer.Default.Equals(_typeSymbols.ActionOfBinderOptions, @params[2].Type)) + MethodsToGen_Extensions_OptionsBuilder overload = paramCount switch { - _sourceGenSpec.MethodsToGen_OptionsBuilderExt |= MethodsToGen_Extensions_OptionsBuilder.Bind_T_BinderOptions; - } - else + 2 => MethodsToGen_Extensions_OptionsBuilder.Bind_T, + 3 when SymbolEqualityComparer.Default.Equals(_typeSymbols.ActionOfBinderOptions, @params[2].Type) => + MethodsToGen_Extensions_OptionsBuilder.Bind_T_BinderOptions, + _ => MethodsToGen_Extensions_OptionsBuilder.None + }; + + if (overload is not MethodsToGen_Extensions_OptionsBuilder.None) { - return; + RegisterAsInterceptor_OptionsBuilder(overload, operation); + RegisterTypeForMethodGen(MethodsToGen_Extensions_ServiceCollection.Configure_T_name_BinderOptions, typeSpec); } - - RegisterTypeForMethodGen(MethodsToGen_Extensions_ServiceCollection.Configure_T_name_BinderOptions, typeSpec); } private void ParseBindConfigurationInvocation(BinderInvocation invocation, TypeSpec typeSpec) @@ -85,12 +81,26 @@ private void ParseBindConfigurationInvocation(BinderInvocation invocation, TypeS int paramCount = @params.Length; Debug.Assert(paramCount >= 2); - if (paramCount is 3 && @params[1].Type.SpecialType is SpecialType.System_String && SymbolEqualityComparer.Default.Equals(_typeSymbols.ActionOfBinderOptions, @params[2].Type)) + if (paramCount is 3 && + @params[1].Type.SpecialType is SpecialType.System_String && + SymbolEqualityComparer.Default.Equals(_typeSymbols.ActionOfBinderOptions, @params[2].Type)) { - _sourceGenSpec.MethodsToGen_OptionsBuilderExt |= MethodsToGen_Extensions_OptionsBuilder.BindConfiguration_T_path_BinderOptions; - RegisterTypeForBindCoreUntypedGen(typeSpec); + RegisterAsInterceptor_OptionsBuilder(MethodsToGen_Extensions_OptionsBuilder.BindConfiguration_T_path_BinderOptions, invocation.Operation); + RegisterTypeForBindCoreMainGen(typeSpec); } } + + private void RegisterAsInterceptor_OptionsBuilder(MethodsToGen_Extensions_OptionsBuilder overload, IInvocationOperation operation) + { + _sourceGenSpec.MethodsToGen_OptionsBuilderExt |= overload; + RegisterAsInterceptor(overload, operation); + + // Emitting refs to IOptionsChangeTokenSource, ConfigurationChangeTokenSource. + _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.Options"); + + // Emitting refs to OptionsBuilder. + _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.DependencyInjection"); + } } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs index 02c75b4ab653b3..c356b29a69efff 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs @@ -79,12 +79,14 @@ @params[1].Type.SpecialType is SpecialType.System_String && } RegisterTypeForMethodGen(overload, typeSpec); + RegisterAsInterceptor(overload, operation); } private void RegisterTypeForMethodGen(MethodsToGen_Extensions_ServiceCollection overload, TypeSpec typeSpec) { _sourceGenSpec.MethodsToGen_ServiceCollectionExt |= overload; - RegisterTypeForBindCoreUntypedGen(typeSpec); + _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.DependencyInjection"); + RegisterTypeForBindCoreMainGen(typeSpec); } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj index 785a18c5c0978e..5b10a6f8e06c6b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj @@ -11,6 +11,8 @@ + + @@ -26,12 +28,14 @@ + - + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ObjectSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ObjectSpec.cs index 1696ee099fe469..8cc0ba68b49381 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ObjectSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ObjectSpec.cs @@ -22,10 +22,6 @@ public ObjectSpec(INamedTypeSymbol type) : base(type) { } public List ConstructorParameters { get; } = new(); - private string _displayStringWithoutSpecialCharacters; - public string DisplayStringWithoutSpecialCharacters => - _displayStringWithoutSpecialCharacters ??= $"{MinimalDisplayString.Replace(".", string.Empty).Replace("<", string.Empty).Replace(">", string.Empty)}"; - public override bool NeedsMemberBinding => CanInitialize && Properties.Values.Count > 0 && Properties.Values.Any(p => p.ShouldBind()); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ParsableFromStringSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ParsableFromStringSpec.cs index 6b5bb5b61ea371..e19e3e61d210f3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ParsableFromStringSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ParsableFromStringSpec.cs @@ -24,7 +24,7 @@ public string ParseMethodName _parseMethodName ??= StringParsableTypeKind is StringParsableTypeKind.ByteArray ? "ParseByteArray" // MinimalDisplayString.Length is certainly > 2. - : $"Parse{(char.ToUpper(MinimalDisplayString[0]) + MinimalDisplayString.Substring(1)).Replace(".", "")}"; + : $"Parse{(char.ToUpper(DisplayString[0]) + DisplayString.Substring(1)).Replace(".", "")}"; return _parseMethodName; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/SourceGenerationSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/SourceGenerationSpec.cs index 88c4b24f57a5ea..760d57b1dcc888 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/SourceGenerationSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/SourceGenerationSpec.cs @@ -1,21 +1,25 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Collections.Generic; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { internal sealed record SourceGenerationSpec { + public Dictionary> InterceptionInfo { get; } = new(); + public ConfigurationBinderInterceptorInfo InterceptionInfo_ConfigBinder { get; } = new(); + public Dictionary> TypesForGen_CoreBindingHelper_Methods { get; } = new(); - public Dictionary> TypesForGen_ConfigurationBinder_BindMethods { get; } = new(); public HashSet PrimitivesForHelperGen { get; } = new(); - public HashSet TypeNamespaces { get; } = new() + public HashSet Namespaces { get; } = new() { "System", "System.CodeDom.Compiler", "System.Globalization", + "System.Runtime.CompilerServices", "Microsoft.Extensions.Configuration", }; diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/TypeSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/TypeSpec.cs index 6a6292b7ebd0b4..6f5e26bf3f6d38 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/TypeSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/TypeSpec.cs @@ -17,17 +17,14 @@ public TypeSpec(ITypeSymbol type) { IsValueType = type.IsValueType; Namespace = type.ContainingNamespace?.ToDisplayString(); - FullyQualifiedDisplayString = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); - MinimalDisplayString = type.ToDisplayString(s_minimalDisplayFormat); - Name = Namespace + "." + MinimalDisplayString.Replace(".", "+"); + DisplayString = type.ToDisplayString(s_minimalDisplayFormat); + Name = Namespace + "." + DisplayString.Replace(".", "+"); IsInterface = type.TypeKind is TypeKind.Interface; } public string Name { get; } - public string FullyQualifiedDisplayString { get; } - - public string MinimalDisplayString { get; } + public string DisplayString { get; } public string? Namespace { get; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/Strings.resx index 301913987d7c7e..3978cbaac6ce48 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/Strings.resx @@ -133,10 +133,10 @@ The collection element type is not supported: '{0}'. - The project's language version has to be at least 'C# 11'. + The project's language version has to be at least 'C# 12'. - Language version is required to be at least C# 11 + Language version is required to be at least C# 12 Cannot create instance of type '{0}' because it is missing a public instance constructor. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf index e248c54626865f..c6672eaff0bcd8 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf @@ -28,13 +28,13 @@ - The project's language version has to be at least 'C# 11'. - Jazyková verze projektu musí být alespoň C# 11 + The project's language version has to be at least 'C# 12'. + Jazyková verze projektu musí být alespoň C# 11 - Language version is required to be at least C# 11 - Verze jazyka musí být alespoň C# 11 + Language version is required to be at least C# 12 + Verze jazyka musí být alespoň C# 11 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf index 1fa847592bd02e..5f353065a5f511 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf @@ -28,13 +28,13 @@ - The project's language version has to be at least 'C# 11'. - Die Sprachversion des Projekts muss mindestens „C# 11“ sein + The project's language version has to be at least 'C# 12'. + Die Sprachversion des Projekts muss mindestens „C# 11“ sein - Language version is required to be at least C# 11 - Die Sprachversion muss mindestens C# 11 sein + Language version is required to be at least C# 12 + Die Sprachversion muss mindestens C# 11 sein diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf index c52b2317ceaded..cd54149e66c2fa 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf @@ -28,13 +28,13 @@ - The project's language version has to be at least 'C# 11'. - La versión del lenguaje del proyecto debe ser al menos "C# 11". + The project's language version has to be at least 'C# 12'. + La versión del lenguaje del proyecto debe ser al menos "C# 11". - Language version is required to be at least C# 11 - La versión del lenguaje debe ser al menos C# 11 + Language version is required to be at least C# 12 + La versión del lenguaje debe ser al menos C# 11 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf index 19362d7336208f..b1c0753a49e8a5 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf @@ -28,13 +28,13 @@ - The project's language version has to be at least 'C# 11'. - La version de langage du projet doit être au moins « C# 11 ». + The project's language version has to be at least 'C# 12'. + La version de langage du projet doit être au moins « C# 11 ». - Language version is required to be at least C# 11 - La version du langage doit être au moins C# 11 + Language version is required to be at least C# 12 + La version du langage doit être au moins C# 11 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf index f418a83d0d422e..27d10a7ee5f9f2 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf @@ -28,13 +28,13 @@ - The project's language version has to be at least 'C# 11'. - La versione del linguaggio del progetto deve essere almeno 'C# 11'. + The project's language version has to be at least 'C# 12'. + La versione del linguaggio del progetto deve essere almeno 'C# 11'. - Language version is required to be at least C# 11 - La versione del linguaggio deve essere almeno C# 11 + Language version is required to be at least C# 12 + La versione del linguaggio deve essere almeno C# 11 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf index ba59cfba40a89b..24621bcc8b3d22 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf @@ -28,13 +28,13 @@ - The project's language version has to be at least 'C# 11'. - プロジェクトの言語バージョンは少なくとも 'C# 11' である必要があります。 + The project's language version has to be at least 'C# 12'. + プロジェクトの言語バージョンは少なくとも 'C# 11' である必要があります。 - Language version is required to be at least C# 11 - 言語バージョンは少なくとも C# 11 である必要があります + Language version is required to be at least C# 12 + 言語バージョンは少なくとも C# 11 である必要があります diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf index 10b9b107c4aade..217a0cd9f8e54c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf @@ -28,13 +28,13 @@ - The project's language version has to be at least 'C# 11'. - 프로젝트의 언어 버전은 'C# 11' 이상이어야 합니다. + The project's language version has to be at least 'C# 12'. + 프로젝트의 언어 버전은 'C# 11' 이상이어야 합니다. - Language version is required to be at least C# 11 - 언어 버전은 C# 11 이상이어야 합니다. + Language version is required to be at least C# 12 + 언어 버전은 C# 11 이상이어야 합니다. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf index 2b558c588ebfb9..0b24813a77a805 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf @@ -28,13 +28,13 @@ - The project's language version has to be at least 'C# 11'. - Wersja językowa projektu musi mieć wartość co najmniej „C# 11”. + The project's language version has to be at least 'C# 12'. + Wersja językowa projektu musi mieć wartość co najmniej „C# 11”. - Language version is required to be at least C# 11 - Wymagana jest wersja językowa co najmniej C# 11 + Language version is required to be at least C# 12 + Wymagana jest wersja językowa co najmniej C# 11 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf index 9d2a51c6aa9c96..0ad700e64e9ebd 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf @@ -28,13 +28,13 @@ - The project's language version has to be at least 'C# 11'. - A versão do idioma do projeto deve ser no mínimo 'C# 11'. + The project's language version has to be at least 'C# 12'. + A versão do idioma do projeto deve ser no mínimo 'C# 11'. - Language version is required to be at least C# 11 - A versão do idioma deve ser pelo menos C# 11 + Language version is required to be at least C# 12 + A versão do idioma deve ser pelo menos C# 11 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf index 1ed03c55891a9e..5e53330060c30b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf @@ -28,13 +28,13 @@ - The project's language version has to be at least 'C# 11'. - Версия языка проекта должна быть не ниже "C# 11". + The project's language version has to be at least 'C# 12'. + Версия языка проекта должна быть не ниже "C# 11". - Language version is required to be at least C# 11 - Версия языка должна быть не ниже C# 11 + Language version is required to be at least C# 12 + Версия языка должна быть не ниже C# 11 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf index 8a6dbf76bab7f7..cfaea488fd195d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf @@ -28,13 +28,13 @@ - The project's language version has to be at least 'C# 11'. - Projenin dil sürümü en az 'C# 11' olmalıdır. + The project's language version has to be at least 'C# 12'. + Projenin dil sürümü en az 'C# 11' olmalıdır. - Language version is required to be at least C# 11 - Dil sürümünün en az C# 11 olması gerekir + Language version is required to be at least C# 12 + Dil sürümünün en az C# 11 olması gerekir diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf index 9d0c0eb3a5d6dd..3dfb711b39b4eb 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -28,13 +28,13 @@ - The project's language version has to be at least 'C# 11'. - 项目的语言版本必须至少为 "C# 11"。 + The project's language version has to be at least 'C# 12'. + 项目的语言版本必须至少为 "C# 11"。 - Language version is required to be at least C# 11 - 语言版本必须至少为 C# 11 + Language version is required to be at least C# 12 + 语言版本必须至少为 C# 11 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf index dc6ded618c8e94..9917b18949880e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -28,13 +28,13 @@ - The project's language version has to be at least 'C# 11'. - 專案的語言版本必須至少為 'C# 11'。 + The project's language version has to be at least 'C# 12'. + 專案的語言版本必須至少為 'C# 11'。 - Language version is required to be at least C# 11 - 語言版本要求至少為 C#11 + Language version is required to be at least C# 12 + 語言版本要求至少為 C#11 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs index 56dddc6f8bc83b..eea01092667e8d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs @@ -8,7 +8,6 @@ using System.Globalization; using System.Linq; using System.Reflection; -using System.Text; #if BUILDING_SOURCE_GENERATOR_TESTS using Microsoft.Extensions.Configuration; #endif @@ -2037,6 +2036,7 @@ public void ComplexObj_As_Enumerable_Element() ValidateGeolocation(obj); } +#if !BUILDING_SOURCE_GENERATOR_TESTS [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] public void TraceSwitchTest() { @@ -2056,6 +2056,7 @@ public void TraceSwitchTest() Assert.Equal("Info", ts.Value); #endif // NETCOREAPP } +#endif private void ValidateGeolocation(IGeolocation location) { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt index 2149dcaaa07141..528847cfeb3a37 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt @@ -2,12 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Attempts to bind the configuration instance to a new instance of type T. - public static T? Get(this global::Microsoft.Extensions.Configuration.IConfiguration configuration) => (T?)(global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetCore(configuration, typeof(T), configureOptions: null) ?? default(T)); + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -18,11 +25,18 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System.Collections.Generic; using System.Globalization; using System.Linq; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IConfiguration extensions. + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocationAttribute(@"src-0.cs", 12, 17)] + public static T? Get(this IConfiguration configuration) => (T?)(GetCore(configuration, typeof(T), configureOptions: null) ?? default(T)); + #endregion IConfiguration extensions. + + #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClassWithCustomCollections = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "CustomDictionary", "CustomList", "IReadOnlyList", "IReadOnlyDictionary" }); public static object? GetCore(this IConfiguration configuration, Type type, Action? configureOptions) @@ -46,16 +60,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration return obj; } - throw new global::System.NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } public static void BindCore(IConfiguration configuration, ref Program.CustomDictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -67,11 +76,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.CustomList obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -83,11 +87,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -99,11 +98,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref ICollection obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -115,11 +109,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref IReadOnlyList obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - if (obj is not ICollection temp) { return; @@ -136,11 +125,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -152,11 +136,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref IDictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -168,11 +147,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref IReadOnlyDictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - if (obj is not IDictionary temp) { return; @@ -189,11 +163,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClassWithCustomCollections obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClassWithCustomCollections), s_configKeys_ProgramMyClassWithCustomCollections, configuration, binderOptions); if (AsConfigWithChildren(configuration.GetSection("CustomDictionary")) is IConfigurationSection section1) @@ -229,6 +198,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -281,7 +251,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -298,5 +268,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt index 406e8db6716777..36ac12fd31f83d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt @@ -2,18 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - public static void Bind(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::Program.MyClass obj) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCore(configuration, ref obj, binderOptions: null); - - /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - public static void Bind(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::Program.MyClass obj, global::System.Action? configureOptions) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCore(configuration, ref obj, global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetBinderOptions(configureOptions)); + using System; + using System.CodeDom.Compiler; - /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - public static void Bind(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, string key, global::Program.MyClass obj) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCore(configuration.GetSection(key), ref obj, binderOptions: null); + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -23,20 +24,72 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { - private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); + #region IConfiguration extensions. + /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. + [InterceptsLocationAttribute(@"src-0.cs", 13, 18)] + public static void Bind_ProgramMyClass(this IConfiguration configuration, object? obj) + { + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + if (obj is null) + { + throw new ArgumentNullException(nameof(obj)); + } + + var typedObj = (Program.MyClass)obj; + BindCore(configuration, ref typedObj, binderOptions: null); + } + + /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. + [InterceptsLocationAttribute(@"src-0.cs", 14, 24)] + public static void Bind_ProgramMyClass(this IConfiguration configuration, object? obj, Action? configureOptions) + { + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + if (obj is null) + { + throw new ArgumentNullException(nameof(obj)); + } + + var typedObj = (Program.MyClass)obj; + BindCore(configuration, ref typedObj, GetBinderOptions(configureOptions)); + } + + /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. + [InterceptsLocationAttribute(@"src-0.cs", 15, 24)] + public static void Bind_ProgramMyClass(this IConfiguration configuration, string key, object? obj) { + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + if (obj is null) { throw new ArgumentNullException(nameof(obj)); } + var typedObj = (Program.MyClass)obj; + BindCore(configuration.GetSection(key), ref typedObj, binderOptions: null); + } + #endregion IConfiguration extensions. + + #region Core binding extensions. + private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); + + public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -48,11 +101,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -64,11 +112,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (!(obj.TryGetValue(section.Key, out Program.MyClass2? element) && element is not null)) @@ -81,11 +124,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -120,6 +158,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -163,7 +202,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -180,5 +219,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt index 106e01795369e2..02fb06957bb3d5 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt @@ -2,12 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - public static void Bind(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::Program.MyClass obj) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCore(configuration, ref obj, binderOptions: null); + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -17,20 +24,36 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { - private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); - - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + #region IConfiguration extensions. + /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. + [InterceptsLocationAttribute(@"src-0.cs", 12, 20)] + public static void Bind_ProgramMyClass(this IConfiguration configuration, object? obj) { + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + if (obj is null) { throw new ArgumentNullException(nameof(obj)); } + var typedObj = (Program.MyClass)obj; + BindCore(configuration, ref typedObj, binderOptions: null); + } + #endregion IConfiguration extensions. + + #region Core binding extensions. + private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); + + public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -42,11 +65,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -58,11 +76,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (!(obj.TryGetValue(section.Key, out Program.MyClass2? element) && element is not null)) @@ -75,11 +88,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -114,6 +122,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -156,5 +165,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt index a1cb7d6b93b5d0..4703980996b889 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt @@ -2,12 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - public static void Bind(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::Program.MyClass obj, global::System.Action? configureOptions) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCore(configuration, ref obj, global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetBinderOptions(configureOptions)); + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -17,20 +24,36 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { - private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); - - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + #region IConfiguration extensions. + /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. + [InterceptsLocationAttribute(@"src-0.cs", 12, 20)] + public static void Bind_ProgramMyClass(this IConfiguration configuration, object? obj, Action? configureOptions) { + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + if (obj is null) { throw new ArgumentNullException(nameof(obj)); } + var typedObj = (Program.MyClass)obj; + BindCore(configuration, ref typedObj, GetBinderOptions(configureOptions)); + } + #endregion IConfiguration extensions. + + #region Core binding extensions. + private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); + + public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -42,11 +65,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -58,11 +76,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (!(obj.TryGetValue(section.Key, out Program.MyClass2? element) && element is not null)) @@ -75,11 +88,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -114,6 +122,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -157,7 +166,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -174,5 +183,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt index f3ee8a9ff43840..99371296997168 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt @@ -2,12 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - public static void Bind(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, string key, global::Program.MyClass obj) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCore(configuration.GetSection(key), ref obj, binderOptions: null); + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -17,20 +24,36 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { - private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); - - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + #region IConfiguration extensions. + /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. + [InterceptsLocationAttribute(@"src-0.cs", 12, 20)] + public static void Bind_ProgramMyClass(this IConfiguration configuration, string key, object? obj) { + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + if (obj is null) { throw new ArgumentNullException(nameof(obj)); } + var typedObj = (Program.MyClass)obj; + BindCore(configuration.GetSection(key), ref typedObj, binderOptions: null); + } + #endregion IConfiguration extensions. + + #region Core binding extensions. + private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); + + public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -42,11 +65,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -58,11 +76,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (!(obj.TryGetValue(section.Key, out Program.MyClass2? element) && element is not null)) @@ -75,11 +88,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -114,6 +122,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -156,5 +165,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt index fb71c70b4dd3bd..3e6ce1459b289a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt @@ -2,21 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Attempts to bind the configuration instance to a new instance of type T. - public static T? Get(this global::Microsoft.Extensions.Configuration.IConfiguration configuration) => (T?)(global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetCore(configuration, typeof(T), configureOptions: null) ?? default(T)); - - /// Attempts to bind the configuration instance to a new instance of type T. - public static T? Get(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Action? configureOptions) => (T?)(global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetCore(configuration, typeof(T), configureOptions) ?? default(T)); - - /// Attempts to bind the configuration instance to a new instance of type T. - public static object? Get(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Type type) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetCore(configuration, type, configureOptions: null); + using System; + using System.CodeDom.Compiler; - /// Attempts to bind the configuration instance to a new instance of type T. - public static object? Get(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Type type, global::System.Action? configureOptions) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetCore(configuration, type, configureOptions); + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -26,11 +24,30 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IConfiguration extensions. + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocationAttribute(@"src-0.cs", 12, 38)] + public static T? Get(this IConfiguration configuration) => (T?)(GetCore(configuration, typeof(T), configureOptions: null) ?? default(T)); + + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocationAttribute(@"src-0.cs", 14, 36)] + public static T? Get(this IConfiguration configuration, Action? configureOptions) => (T?)(GetCore(configuration, typeof(T), configureOptions) ?? default(T)); + + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocationAttribute(@"src-0.cs", 13, 36)] + public static object? Get(this IConfiguration configuration, Type type) => GetCore(configuration, type, configureOptions: null); + + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocationAttribute(@"src-0.cs", 15, 36)] + public static object? Get(this IConfiguration configuration, Type type, Action? configureOptions) => GetCore(configuration, type, configureOptions); + #endregion IConfiguration extensions. + + #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyArray", "MyDictionary" }); private readonly static Lazy> s_configKeys_ProgramMyClass2 = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyInt" }); @@ -54,24 +71,18 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration BindCore(configuration, ref obj, binderOptions); return obj; } - - if (type == typeof(Program.MyClass2)) + else if (type == typeof(Program.MyClass2)) { var obj = new Program.MyClass2(); BindCore(configuration, ref obj, binderOptions); return obj; } - throw new global::System.NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -83,11 +94,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref int[] obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - var temp2 = new List(); BindCore(configuration, ref temp2, binderOptions); int originalCount = obj.Length; @@ -97,11 +103,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -113,11 +114,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -154,11 +150,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value15) @@ -167,6 +158,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -219,7 +211,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -236,5 +228,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue.generated.txt index c9d49faa937244..e4bcaf6a9b7c95 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue.generated.txt @@ -2,21 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Extracts the value with the specified key and converts it to the specified type. - public static T? GetValue(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, string key) => (T?)(global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetValueCore(configuration, typeof(T), key) ?? default(T)); - - /// Extracts the value with the specified key and converts it to the specified type. - public static T? GetValue(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, string key, T defaultValue) => (T?)(global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetValueCore(configuration, typeof(T), key) ?? defaultValue); - - /// Extracts the value with the specified key and converts it to the specified type. - public static object? GetValue(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Type type, string key) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetValueCore(configuration, type, key); + using System; + using System.CodeDom.Compiler; - /// Extracts the value with the specified key and converts it to the specified type. - public static object? GetValue(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Type type, string key, object? defaultValue) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetValueCore(configuration, type, key) ?? defaultValue; + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -25,11 +23,30 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System; using System.CodeDom.Compiler; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IConfiguration extensions. + /// Extracts the value with the specified key and converts it to the specified type. + [InterceptsLocationAttribute(@"src-0.cs", 13, 18)] + public static T? GetValue(this IConfiguration configuration, string key) => (T?)(BindingExtensions.GetValueCore(configuration, typeof(T), key) ?? default(T)); + + /// Extracts the value with the specified key and converts it to the specified type. + [InterceptsLocationAttribute(@"src-0.cs", 16, 24)] + public static T? GetValue(this IConfiguration configuration, string key, T defaultValue) => (T?)(BindingExtensions.GetValueCore(configuration, typeof(T), key) ?? defaultValue); + + /// Extracts the value with the specified key and converts it to the specified type. + [InterceptsLocationAttribute(@"src-0.cs", 14, 24)] + public static object? GetValue(this IConfiguration configuration, Type type, string key) => BindingExtensions.GetValueCore(configuration, type, key); + + /// Extracts the value with the specified key and converts it to the specified type. + [InterceptsLocationAttribute(@"src-0.cs", 17, 24)] + public static object? GetValue(this IConfiguration configuration, Type type, string key, object? defaultValue) => BindingExtensions.GetValueCore(configuration, type, key) ?? defaultValue; + #endregion IConfiguration extensions. + + #region Core binding extensions. public static object? GetValueCore(this IConfiguration configuration, Type type, string key) { if (configuration is null) @@ -48,18 +65,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { return ParseInt(value, () => section.Path); } - - if (type == typeof(bool?)) + else if (type == typeof(bool?)) { return ParseBool(value, () => section.Path); } - - if (type == typeof(byte[])) + else if (type == typeof(byte[])) { return ParseByteArray(value, () => section.Path); } - - if (type == typeof(CultureInfo)) + else if (type == typeof(CultureInfo)) { return ParseCultureInfo(value, () => section.Path); } @@ -114,5 +128,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(CultureInfo)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key.generated.txt index 17c963bd980a70..2438cf530ca4ce 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key.generated.txt @@ -2,12 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Extracts the value with the specified key and converts it to the specified type. - public static T? GetValue(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, string key) => (T?)(global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetValueCore(configuration, typeof(T), key) ?? default(T)); + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -16,11 +23,18 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System; using System.CodeDom.Compiler; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IConfiguration extensions. + /// Extracts the value with the specified key and converts it to the specified type. + [InterceptsLocationAttribute(@"src-0.cs", 10, 20)] + public static T? GetValue(this IConfiguration configuration, string key) => (T?)(BindingExtensions.GetValueCore(configuration, typeof(T), key) ?? default(T)); + #endregion IConfiguration extensions. + + #region Core binding extensions. public static object? GetValueCore(this IConfiguration configuration, Type type, string key) { if (configuration is null) @@ -54,5 +68,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key_DefaultValue.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key_DefaultValue.generated.txt index 1148109b9f5a81..e6db24d522f3c9 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key_DefaultValue.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key_DefaultValue.generated.txt @@ -2,12 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Extracts the value with the specified key and converts it to the specified type. - public static T? GetValue(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, string key, T defaultValue) => (T?)(global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetValueCore(configuration, typeof(T), key) ?? defaultValue); + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -16,11 +23,18 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System; using System.CodeDom.Compiler; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IConfiguration extensions. + /// Extracts the value with the specified key and converts it to the specified type. + [InterceptsLocationAttribute(@"src-0.cs", 12, 20)] + public static T? GetValue(this IConfiguration configuration, string key, T defaultValue) => (T?)(BindingExtensions.GetValueCore(configuration, typeof(T), key) ?? defaultValue); + #endregion IConfiguration extensions. + + #region Core binding extensions. public static object? GetValueCore(this IConfiguration configuration, Type type, string key) { if (configuration is null) @@ -54,5 +68,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key.generated.txt index c833b20f18dcfe..a36f9fafebcff8 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key.generated.txt @@ -2,12 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Extracts the value with the specified key and converts it to the specified type. - public static object? GetValue(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Type type, string key) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetValueCore(configuration, type, key); + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -16,11 +23,18 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System; using System.CodeDom.Compiler; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IConfiguration extensions. + /// Extracts the value with the specified key and converts it to the specified type. + [InterceptsLocationAttribute(@"src-0.cs", 10, 20)] + public static object? GetValue(this IConfiguration configuration, Type type, string key) => BindingExtensions.GetValueCore(configuration, type, key); + #endregion IConfiguration extensions. + + #region Core binding extensions. public static object? GetValueCore(this IConfiguration configuration, Type type, string key) { if (configuration is null) @@ -54,5 +68,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(bool)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key_DefaultValue.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key_DefaultValue.generated.txt index f773f79ce6c2c0..356f6bb1a933e2 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key_DefaultValue.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key_DefaultValue.generated.txt @@ -2,12 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Extracts the value with the specified key and converts it to the specified type. - public static object? GetValue(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Type type, string key, object? defaultValue) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetValueCore(configuration, type, key) ?? defaultValue; + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -16,11 +23,18 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System; using System.CodeDom.Compiler; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IConfiguration extensions. + /// Extracts the value with the specified key and converts it to the specified type. + [InterceptsLocationAttribute(@"src-0.cs", 11, 20)] + public static object? GetValue(this IConfiguration configuration, Type type, string key, object? defaultValue) => BindingExtensions.GetValueCore(configuration, type, key) ?? defaultValue; + #endregion IConfiguration extensions. + + #region Core binding extensions. public static object? GetValueCore(this IConfiguration configuration, Type type, string key) { if (configuration is null) @@ -54,5 +68,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(CultureInfo)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt index de8201fe6fed2c..85d0901de3ff60 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt @@ -2,12 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Attempts to bind the configuration instance to a new instance of type T. - public static T? Get(this global::Microsoft.Extensions.Configuration.IConfiguration configuration) => (T?)(global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetCore(configuration, typeof(T), configureOptions: null) ?? default(T)); + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -17,11 +24,18 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IConfiguration extensions. + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocationAttribute(@"src-0.cs", 11, 40)] + public static T? Get(this IConfiguration configuration) => (T?)(GetCore(configuration, typeof(T), configureOptions: null) ?? default(T)); + #endregion IConfiguration extensions. + + #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyArray", "MyDictionary" }); public static object? GetCore(this IConfiguration configuration, Type type, Action? configureOptions) @@ -45,16 +59,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration return obj; } - throw new global::System.NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -66,11 +75,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref int[] obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - var temp1 = new List(); BindCore(configuration, ref temp1, binderOptions); int originalCount = obj.Length; @@ -80,11 +84,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -96,11 +95,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -135,6 +129,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -187,7 +182,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -204,5 +199,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt index 34fadacace146d..d394cc7b269f74 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt @@ -2,12 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Attempts to bind the configuration instance to a new instance of type T. - public static T? Get(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Action? configureOptions) => (T?)(global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetCore(configuration, typeof(T), configureOptions) ?? default(T)); + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -17,11 +24,18 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IConfiguration extensions. + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocationAttribute(@"src-0.cs", 11, 40)] + public static T? Get(this IConfiguration configuration, Action? configureOptions) => (T?)(GetCore(configuration, typeof(T), configureOptions) ?? default(T)); + #endregion IConfiguration extensions. + + #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyArray", "MyDictionary" }); public static object? GetCore(this IConfiguration configuration, Type type, Action? configureOptions) @@ -45,16 +59,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration return obj; } - throw new global::System.NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -66,11 +75,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref int[] obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - var temp1 = new List(); BindCore(configuration, ref temp1, binderOptions); int originalCount = obj.Length; @@ -80,11 +84,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -96,11 +95,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -135,6 +129,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -187,7 +182,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -204,5 +199,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt index 16a98c931a705f..83cd88561310ab 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt @@ -2,12 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Attempts to bind the configuration instance to a new instance of type T. - public static object? Get(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Type type) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetCore(configuration, type, configureOptions: null); + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -17,11 +24,18 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IConfiguration extensions. + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocationAttribute(@"src-0.cs", 11, 40)] + public static object? Get(this IConfiguration configuration, Type type) => GetCore(configuration, type, configureOptions: null); + #endregion IConfiguration extensions. + + #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass2 = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyInt" }); public static object? GetCore(this IConfiguration configuration, Type type, Action? configureOptions) @@ -45,16 +59,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration return obj; } - throw new global::System.NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value1) @@ -63,6 +72,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -115,7 +125,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -132,5 +142,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt index 8d1ee9ed3cd9a3..91714c80cd0136 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt @@ -2,12 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Attempts to bind the configuration instance to a new instance of type T. - public static object? Get(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Type type, global::System.Action? configureOptions) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.GetCore(configuration, type, configureOptions); + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -17,11 +24,18 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IConfiguration extensions. + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocationAttribute(@"src-0.cs", 11, 20)] + public static object? Get(this IConfiguration configuration, Type type, Action? configureOptions) => GetCore(configuration, type, configureOptions); + #endregion IConfiguration extensions. + + #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass2 = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyInt" }); public static object? GetCore(this IConfiguration configuration, Type type, Action? configureOptions) @@ -45,16 +59,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration return obj; } - throw new global::System.NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value1) @@ -63,6 +72,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -115,7 +125,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -132,5 +142,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt index a74dbfdd04b5b9..88b35037c22c3f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt @@ -2,31 +2,18 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedOptionsBuilderBinder +namespace System.Runtime.CompilerServices { - /// Registers the dependency injection container to bind against the obtained from the DI service provider. - public static global::Microsoft.Extensions.Options.OptionsBuilder BindConfiguration(this global::Microsoft.Extensions.Options.OptionsBuilder optionsBuilder, string configSectionPath, global::System.Action? configureOptions = null) where TOptions : class - { - if (optionsBuilder is null) - { - throw new global::System.ArgumentNullException(nameof(optionsBuilder)); - } + using System; + using System.CodeDom.Compiler; - if (configSectionPath is null) + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) { - throw new global::System.ArgumentNullException(nameof(configSectionPath)); } - - optionsBuilder.Configure((obj, configuration) => - { - global::Microsoft.Extensions.Configuration.IConfiguration section = string.Equals(string.Empty, configSectionPath, global::System.StringComparison.OrdinalIgnoreCase) ? configuration : configuration.GetSection(configSectionPath); - global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCoreUntyped(section, obj, typeof(TOptions), configureOptions); - }); - - global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::Microsoft.Extensions.Options.ConfigurationChangeTokenSource>(optionsBuilder.Services); - return optionsBuilder; } } @@ -34,31 +21,74 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Options; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region OptionsBuilder extensions. + /// Registers the dependency injection container to bind against the obtained from the DI service provider. + [InterceptsLocationAttribute(@"src-0.cs", 12, 24)] + public static OptionsBuilder BindConfiguration(this OptionsBuilder optionsBuilder, string configSectionPath, Action? configureOptions = null) where TOptions : class + { + if (optionsBuilder is null) + { + throw new ArgumentNullException(nameof(optionsBuilder)); + } + + if (configSectionPath is null) + { + throw new ArgumentNullException(nameof(configSectionPath)); + } + + optionsBuilder.Configure((obj, configuration) => + { + if (obj is null) + { + throw new ArgumentNullException(nameof(obj)); + } + + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + IConfiguration section = string.Equals(string.Empty, configSectionPath, StringComparison.OrdinalIgnoreCase) ? configuration : configuration.GetSection(configSectionPath); + BindCoreMain(section, obj, typeof(TOptions), configureOptions); + }); + + optionsBuilder.Services.AddSingleton, ConfigurationChangeTokenSource>(); + return optionsBuilder; + } + #endregion OptionsBuilder extensions. + + #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList" }); - public static void BindCoreUntyped(this IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (obj is null) + { + throw new ArgumentNullException(nameof(obj)); + } if (!HasValueOrChildren(configuration)) { return; } + BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)obj; @@ -66,16 +96,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration return; } - throw new global::System.NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -87,11 +112,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -110,6 +130,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -162,7 +183,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -179,5 +200,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt index ac53b58f24da23..633196e7a742d5 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt @@ -2,49 +2,18 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedOptionsBuilderBinder +namespace System.Runtime.CompilerServices { - /// Registers a configuration instance which will bind against. - public static global::Microsoft.Extensions.Options.OptionsBuilder Bind(this global::Microsoft.Extensions.Options.OptionsBuilder optionsBuilder, global::Microsoft.Extensions.Configuration.IConfiguration configuration) where TOptions : class - { - return global::GeneratedOptionsBuilderBinder.Bind(optionsBuilder, configuration, configureOptions: null); - } - - /// Registers a configuration instance which will bind against. - public static global::Microsoft.Extensions.Options.OptionsBuilder Bind(this global::Microsoft.Extensions.Options.OptionsBuilder optionsBuilder, global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Action? configureOptions) where TOptions : class - { - if (optionsBuilder is null) - { - throw new global::System.ArgumentNullException(nameof(optionsBuilder)); - } - - global::GeneratedServiceCollectionBinder.Configure(optionsBuilder.Services, optionsBuilder.Name, configuration, configureOptions); - return optionsBuilder; - } -} + using System; + using System.CodeDom.Compiler; -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedServiceCollectionBinder -{ - /// Registers a configuration instance which TOptions will bind against. - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name, global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Action? configureOptions) where TOptions : class + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute { - if (services is null) - { - throw new global::System.ArgumentNullException(nameof(services)); - } - - if (configuration is null) + public InterceptsLocationAttribute(string filePath, int line, int column) { - throw new global::System.ArgumentNullException(nameof(configuration)); } - - global::Microsoft.Extensions.DependencyInjection.OptionsServiceCollectionExtensions.AddOptions(services); - global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, new global::Microsoft.Extensions.Options.ConfigurationChangeTokenSource(name, configuration)); - return global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, new global::Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCoreUntyped(configuration, obj, typeof(TOptions), configureOptions))); } } @@ -52,31 +21,79 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Options; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region OptionsBuilder extensions. + /// Registers a configuration instance which will bind against. + [InterceptsLocationAttribute(@"src-0.cs", 15, 24)] + public static OptionsBuilder Bind(this OptionsBuilder optionsBuilder, IConfiguration configuration) where TOptions : class + { + return Bind(optionsBuilder, configuration, configureOptions: null); + } + + /// Registers a configuration instance which will bind against. + public static OptionsBuilder Bind(this OptionsBuilder optionsBuilder, IConfiguration configuration, Action? configureOptions) where TOptions : class + { + if (optionsBuilder is null) + { + throw new ArgumentNullException(nameof(optionsBuilder)); + } + + Configure(optionsBuilder.Services, optionsBuilder.Name, configuration, configureOptions); + return optionsBuilder; + } + #endregion OptionsBuilder extensions. + + #region IServiceCollection extensions. + /// Registers a configuration instance which TOptions will bind against. + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration, Action? configureOptions) where TOptions : class + { + if (services is null) + { + throw new ArgumentNullException(nameof(services)); + } + + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + OptionsServiceCollectionExtensions.AddOptions(services); + services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); + return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions)configureOptions))); + } + #endregion IServiceCollection extensions. + + #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList" }); - public static void BindCoreUntyped(this IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (obj is null) + { + throw new ArgumentNullException(nameof(obj)); + } if (!HasValueOrChildren(configuration)) { return; } + BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)obj; @@ -84,16 +101,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration return; } - throw new global::System.NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -105,11 +117,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -128,6 +135,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -180,7 +188,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -197,5 +205,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt index fd3ec70a8a328b..fb5b4b4ad721d8 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt @@ -2,43 +2,18 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedOptionsBuilderBinder +namespace System.Runtime.CompilerServices { - /// Registers a configuration instance which will bind against. - public static global::Microsoft.Extensions.Options.OptionsBuilder Bind(this global::Microsoft.Extensions.Options.OptionsBuilder optionsBuilder, global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Action? configureOptions) where TOptions : class - { - if (optionsBuilder is null) - { - throw new global::System.ArgumentNullException(nameof(optionsBuilder)); - } - - global::GeneratedServiceCollectionBinder.Configure(optionsBuilder.Services, optionsBuilder.Name, configuration, configureOptions); - return optionsBuilder; - } -} + using System; + using System.CodeDom.Compiler; -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedServiceCollectionBinder -{ - /// Registers a configuration instance which TOptions will bind against. - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name, global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Action? configureOptions) where TOptions : class + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute { - if (services is null) - { - throw new global::System.ArgumentNullException(nameof(services)); - } - - if (configuration is null) + public InterceptsLocationAttribute(string filePath, int line, int column) { - throw new global::System.ArgumentNullException(nameof(configuration)); } - - global::Microsoft.Extensions.DependencyInjection.OptionsServiceCollectionExtensions.AddOptions(services); - global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, new global::Microsoft.Extensions.Options.ConfigurationChangeTokenSource(name, configuration)); - return global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, new global::Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCoreUntyped(configuration, obj, typeof(TOptions), configureOptions))); } } @@ -46,31 +21,73 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Options; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region OptionsBuilder extensions. + /// Registers a configuration instance which will bind against. + [InterceptsLocationAttribute(@"src-0.cs", 15, 24)] + public static OptionsBuilder Bind(this OptionsBuilder optionsBuilder, IConfiguration configuration, Action? configureOptions) where TOptions : class + { + if (optionsBuilder is null) + { + throw new ArgumentNullException(nameof(optionsBuilder)); + } + + Configure(optionsBuilder.Services, optionsBuilder.Name, configuration, configureOptions); + return optionsBuilder; + } + #endregion OptionsBuilder extensions. + + #region IServiceCollection extensions. + /// Registers a configuration instance which TOptions will bind against. + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration, Action? configureOptions) where TOptions : class + { + if (services is null) + { + throw new ArgumentNullException(nameof(services)); + } + + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + OptionsServiceCollectionExtensions.AddOptions(services); + services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); + return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions)configureOptions))); + } + #endregion IServiceCollection extensions. + + #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList" }); - public static void BindCoreUntyped(this IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (obj is null) + { + throw new ArgumentNullException(nameof(obj)); + } if (!HasValueOrChildren(configuration)) { return; } + BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)obj; @@ -78,16 +95,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration return; } - throw new global::System.NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -99,11 +111,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -122,6 +129,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -174,7 +182,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -191,5 +199,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt index 5d30288a21e785..1bf110454ec7ba 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt @@ -2,12 +2,19 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedConfigurationBinder +namespace System.Runtime.CompilerServices { - /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - public static void Bind(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::Program.MyClass obj) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCore(configuration, ref obj, binderOptions: null); + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -17,20 +24,36 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { - private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "Prop0", "Prop1", "Prop2", "Prop3", "Prop4", "Prop5", "Prop6", "Prop8", "Prop9", "Prop10", "Prop13", "Prop14", "Prop15", "Prop16", "Prop17", "Prop19", "Prop20", "Prop21", "Prop23", "Prop24", "Prop25", "Prop26", "Prop27", "Prop7", "Prop11", "Prop12", "Prop18", "Prop22" }); - - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + #region IConfiguration extensions. + /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. + [InterceptsLocationAttribute(@"src-0.cs", 13, 16)] + public static void Bind_ProgramMyClass(this IConfiguration configuration, object? obj) { + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + if (obj is null) { throw new ArgumentNullException(nameof(obj)); } + var typedObj = (Program.MyClass)obj; + BindCore(configuration, ref typedObj, binderOptions: null); + } + #endregion IConfiguration extensions. + + #region Core binding extensions. + private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "Prop0", "Prop1", "Prop2", "Prop3", "Prop4", "Prop5", "Prop6", "Prop8", "Prop9", "Prop10", "Prop13", "Prop14", "Prop15", "Prop16", "Prop17", "Prop19", "Prop20", "Prop21", "Prop23", "Prop24", "Prop25", "Prop26", "Prop27", "Prop7", "Prop11", "Prop12", "Prop18", "Prop22" }); + + public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); if (configuration["Prop0"] is string value0) @@ -168,6 +191,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -517,5 +541,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(byte[])}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt index 461f6050e2fdfe..7f626f0e27c527 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt @@ -2,64 +2,84 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedServiceCollectionBinder +namespace System.Runtime.CompilerServices { - /// Registers a configuration instance which TOptions will bind against. - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::Microsoft.Extensions.Configuration.IConfiguration configuration) where TOptions : class - { - return global::GeneratedServiceCollectionBinder.Configure(services, string.Empty, configuration, configureOptions: null); - } + using System; + using System.CodeDom.Compiler; - /// Registers a configuration instance which TOptions will bind against. - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name, global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Action? configureOptions) where TOptions : class + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute { - if (services is null) - { - throw new global::System.ArgumentNullException(nameof(services)); - } - - if (configuration is null) + public InterceptsLocationAttribute(string filePath, int line, int column) { - throw new global::System.ArgumentNullException(nameof(configuration)); } - - global::Microsoft.Extensions.DependencyInjection.OptionsServiceCollectionExtensions.AddOptions(services); - global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, new global::Microsoft.Extensions.Options.ConfigurationChangeTokenSource(name, configuration)); - return global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, new global::Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCoreUntyped(configuration, obj, typeof(TOptions), configureOptions))); } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IServiceCollection extensions. + /// Registers a configuration instance which TOptions will bind against. + [InterceptsLocationAttribute(@"src-0.cs", 14, 18)] + public static IServiceCollection Configure(this IServiceCollection services, IConfiguration configuration) where TOptions : class + { + return Configure(services, string.Empty, configuration, configureOptions: null); + } + + /// Registers a configuration instance which TOptions will bind against. + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration, Action? configureOptions) where TOptions : class + { + if (services is null) + { + throw new ArgumentNullException(nameof(services)); + } + + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + OptionsServiceCollectionExtensions.AddOptions(services); + services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); + return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions)configureOptions))); + } + #endregion IServiceCollection extensions. + + #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass2 = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyInt" }); private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyList2", "MyDictionary" }); - public static void BindCoreUntyped(this IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (obj is null) + { + throw new ArgumentNullException(nameof(obj)); + } if (!HasValueOrChildren(configuration)) { return; } + BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)obj; @@ -67,16 +87,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration return; } - throw new global::System.NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -88,11 +103,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value1) @@ -103,11 +113,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { var value = new Program.MyClass2(); @@ -118,11 +123,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -134,11 +134,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -173,6 +168,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -225,7 +221,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -242,5 +238,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt index a57f652720bc8c..5848c2412f9b78 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt @@ -2,64 +2,84 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedServiceCollectionBinder +namespace System.Runtime.CompilerServices { - /// Registers a configuration instance which TOptions will bind against. - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Action? configureOptions) where TOptions : class - { - return global::GeneratedServiceCollectionBinder.Configure(services, string.Empty, configuration, configureOptions); - } + using System; + using System.CodeDom.Compiler; - /// Registers a configuration instance which TOptions will bind against. - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name, global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Action? configureOptions) where TOptions : class + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute { - if (services is null) - { - throw new global::System.ArgumentNullException(nameof(services)); - } - - if (configuration is null) + public InterceptsLocationAttribute(string filePath, int line, int column) { - throw new global::System.ArgumentNullException(nameof(configuration)); } - - global::Microsoft.Extensions.DependencyInjection.OptionsServiceCollectionExtensions.AddOptions(services); - global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, new global::Microsoft.Extensions.Options.ConfigurationChangeTokenSource(name, configuration)); - return global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, new global::Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCoreUntyped(configuration, obj, typeof(TOptions), configureOptions))); } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IServiceCollection extensions. + /// Registers a configuration instance which TOptions will bind against. + [InterceptsLocationAttribute(@"src-0.cs", 14, 18)] + public static IServiceCollection Configure(this IServiceCollection services, IConfiguration configuration, Action? configureOptions) where TOptions : class + { + return Configure(services, string.Empty, configuration, configureOptions); + } + + /// Registers a configuration instance which TOptions will bind against. + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration, Action? configureOptions) where TOptions : class + { + if (services is null) + { + throw new ArgumentNullException(nameof(services)); + } + + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + OptionsServiceCollectionExtensions.AddOptions(services); + services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); + return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions)configureOptions))); + } + #endregion IServiceCollection extensions. + + #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass2 = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyInt" }); private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyList2", "MyDictionary" }); - public static void BindCoreUntyped(this IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (obj is null) + { + throw new ArgumentNullException(nameof(obj)); + } if (!HasValueOrChildren(configuration)) { return; } + BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)obj; @@ -67,16 +87,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration return; } - throw new global::System.NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -88,11 +103,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value1) @@ -103,11 +113,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { var value = new Program.MyClass2(); @@ -118,11 +123,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -134,11 +134,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -173,6 +168,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -225,7 +221,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -242,5 +238,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt index 66975c3164d745..91226d730166f1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt @@ -2,64 +2,84 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedServiceCollectionBinder +namespace System.Runtime.CompilerServices { - /// Registers a configuration instance which TOptions will bind against. - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name, global::Microsoft.Extensions.Configuration.IConfiguration configuration) where TOptions : class - { - return global::GeneratedServiceCollectionBinder.Configure(services, name, configuration, configureOptions: null); - } + using System; + using System.CodeDom.Compiler; - /// Registers a configuration instance which TOptions will bind against. - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name, global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Action? configureOptions) where TOptions : class + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute { - if (services is null) - { - throw new global::System.ArgumentNullException(nameof(services)); - } - - if (configuration is null) + public InterceptsLocationAttribute(string filePath, int line, int column) { - throw new global::System.ArgumentNullException(nameof(configuration)); } - - global::Microsoft.Extensions.DependencyInjection.OptionsServiceCollectionExtensions.AddOptions(services); - global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, new global::Microsoft.Extensions.Options.ConfigurationChangeTokenSource(name, configuration)); - return global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, new global::Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCoreUntyped(configuration, obj, typeof(TOptions), configureOptions))); } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IServiceCollection extensions. + /// Registers a configuration instance which TOptions will bind against. + [InterceptsLocationAttribute(@"src-0.cs", 14, 18)] + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration) where TOptions : class + { + return Configure(services, name, configuration, configureOptions: null); + } + + /// Registers a configuration instance which TOptions will bind against. + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration, Action? configureOptions) where TOptions : class + { + if (services is null) + { + throw new ArgumentNullException(nameof(services)); + } + + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + OptionsServiceCollectionExtensions.AddOptions(services); + services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); + return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions)configureOptions))); + } + #endregion IServiceCollection extensions. + + #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass2 = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyInt" }); private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyList2", "MyDictionary" }); - public static void BindCoreUntyped(this IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (obj is null) + { + throw new ArgumentNullException(nameof(obj)); + } if (!HasValueOrChildren(configuration)) { return; } + BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)obj; @@ -67,16 +87,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration return; } - throw new global::System.NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -88,11 +103,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value1) @@ -103,11 +113,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { var value = new Program.MyClass2(); @@ -118,11 +123,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -134,11 +134,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -173,6 +168,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -225,7 +221,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -242,5 +238,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt index 0263ef12179401..8c9ccaa71a779f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt @@ -2,58 +2,78 @@ #nullable enable #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. -/// Generated helper providing an AOT and linking compatible implementation for configuration binding. -[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] -internal static class GeneratedServiceCollectionBinder +namespace System.Runtime.CompilerServices { - /// Registers a configuration instance which TOptions will bind against. - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name, global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::System.Action? configureOptions) where TOptions : class - { - if (services is null) - { - throw new global::System.ArgumentNullException(nameof(services)); - } + using System; + using System.CodeDom.Compiler; - if (configuration is null) + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) { - throw new global::System.ArgumentNullException(nameof(configuration)); } - - global::Microsoft.Extensions.DependencyInjection.OptionsServiceCollectionExtensions.AddOptions(services); - global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, new global::Microsoft.Extensions.Options.ConfigurationChangeTokenSource(name, configuration)); - return global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, new global::Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCoreUntyped(configuration, obj, typeof(TOptions), configureOptions))); } } namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Globalization; + using System.Runtime.CompilerServices; - /// Provide core binding logic. [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] - file static class CoreBindingHelper + file static class BindingExtensions { + #region IServiceCollection extensions. + /// Registers a configuration instance which TOptions will bind against. + [InterceptsLocationAttribute(@"src-0.cs", 14, 18)] + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration, Action? configureOptions) where TOptions : class + { + if (services is null) + { + throw new ArgumentNullException(nameof(services)); + } + + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + OptionsServiceCollectionExtensions.AddOptions(services); + services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); + return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions)configureOptions))); + } + #endregion IServiceCollection extensions. + + #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass2 = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyInt" }); private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyList2", "MyDictionary" }); - public static void BindCoreUntyped(this IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (obj is null) + { + throw new ArgumentNullException(nameof(obj)); + } if (!HasValueOrChildren(configuration)) { return; } + BinderOptions? binderOptions = GetBinderOptions(configureOptions); + if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)obj; @@ -61,16 +81,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration return; } - throw new global::System.NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -82,11 +97,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value1) @@ -97,11 +107,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { var value = new Program.MyClass2(); @@ -112,11 +117,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) @@ -128,11 +128,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); obj.MyString = configuration["MyString"]!; @@ -167,6 +162,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) { @@ -219,7 +215,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (binderOptions.BindNonPublicProperties) { - throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); } return binderOptions; @@ -236,5 +232,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); } } + #endregion Core binding extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.Options.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.Options.cs index 8807dfb0962206..c9eb9c70927f99 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.Options.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.Options.cs @@ -8,6 +8,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests { public partial class ConfigurationBindingGeneratorTests { + #region IServiceCollection extensions. private string GetConfigureSource(string paramList) => $$""" using System.Collections.Generic; using Microsoft.Extensions.Configuration; @@ -40,7 +41,9 @@ public class MyClass2 } } """; + #endregion IServiceCollection extensions. + #region OptionsBuilder extensions. [Fact] public async Task Configure_T() => await VerifyAgainstBaselineUsingFile("Configure_T.generated.txt", GetConfigureSource("section"), extType: ExtensionClassType.ServiceCollection); @@ -126,5 +129,6 @@ public class MyClass await VerifyAgainstBaselineUsingFile("BindConfiguration.generated.txt", GetSource(), extType: ExtensionClassType.OptionsBuilder); await VerifyAgainstBaselineUsingFile("BindConfiguration.generated.txt", GetSource(@", _ => { }"), extType: ExtensionClassType.OptionsBuilder); } + #endregion OptionsBuilder extensions. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.cs index aba2a9f6184f2c..b5c3fb49c5e7eb 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Globalization; using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis; @@ -44,7 +43,6 @@ public class MyClass2 { } [Theory] [InlineData(LanguageVersion.Preview)] - [InlineData(LanguageVersion.CSharp11)] public async Task Bind(LanguageVersion langVersion) => await VerifyAgainstBaselineUsingFile("Bind.generated.txt", BindCallSampleCode, langVersion, extType: ExtensionClassType.ConfigurationBinder); @@ -651,7 +649,7 @@ public interface ICustomSet : ISet await VerifyAgainstBaselineUsingFile("Collections.generated.txt", source, assessDiagnostics: (d) => { - Console.WriteLine((d.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count() , d.Where(diag => diag.Id == Diagnostics.PropertyNotSupported.Id).Count())); + Console.WriteLine((d.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count(), d.Where(diag => diag.Id == Diagnostics.PropertyNotSupported.Id).Count())); Assert.Equal(3, d.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); Assert.Equal(6, d.Where(diag => diag.Id == Diagnostics.PropertyNotSupported.Id).Count()); }); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.cs index 5bc5145739daac..a512c5efe495b1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.cs @@ -52,15 +52,17 @@ private enum ExtensionClassType ServiceCollection, } - [Fact] - public async Task LangVersionMustBeCharp11OrHigher() + [Theory] + [InlineData(LanguageVersion.CSharp11)] + [InlineData(LanguageVersion.CSharp10)] + public async Task LangVersionMustBeCharp12OrHigher(LanguageVersion langVersion) { - var (d, r) = await RunGenerator(BindCallSampleCode, LanguageVersion.CSharp10); + var (d, r) = await RunGenerator(BindCallSampleCode, langVersion); Assert.Empty(r); Diagnostic diagnostic = Assert.Single(d); Assert.True(diagnostic.Id == "SYSLIB1102"); - Assert.Contains("C# 11", diagnostic.Descriptor.Title.ToString(CultureInfo.InvariantCulture)); + Assert.Contains("C# 12", diagnostic.Descriptor.Title.ToString(CultureInfo.InvariantCulture)); Assert.Equal(DiagnosticSeverity.Error, diagnostic.Severity); } @@ -250,9 +252,9 @@ public class MyClass2 { } Assert.Single(r); string generatedSource = string.Join('\n', r[0].SourceText.Lines.Select(x => x.ToString())); - Assert.Contains($"public static void Bind(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::Program.MyClass0 obj) => {{ }};", generatedSource); - Assert.Contains($"public static void Bind(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::Program.MyClass1 obj, global::System.Action? configureOptions) => {{ }};", generatedSource); - Assert.Contains($"public static void Bind(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, string key, global::Program.MyClass2 obj) => {{ }};", generatedSource); + Assert.Contains("public static void Bind_ProgramMyClass0(this IConfiguration configuration, object? obj)", generatedSource); + Assert.Contains("public static void Bind_ProgramMyClass1(this IConfiguration configuration, object? obj, Action? configureOptions)", generatedSource); + Assert.Contains("public static void Bind_ProgramMyClass2(this IConfiguration configuration, string key, object? obj)", generatedSource); Assert.Empty(d); } @@ -395,7 +397,7 @@ private static async Task VerifyAgainstBaselineUsingFile( private static async Task<(ImmutableArray, ImmutableArray)> RunGenerator( string testSourceCode, - LanguageVersion langVersion = LanguageVersion.CSharp11, + LanguageVersion langVersion = LanguageVersion.Preview, IEnumerable? references = null) => await RoslynTestUtils.RunGenerator( new ConfigurationBindingGenerator(), diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj index 2108bc2574ed2c..cfd45c365d42a0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj @@ -4,7 +4,7 @@ true SYSLIB1100,SYSLIB1101 - + $(Features);InterceptorsPreview true diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj index 545e2867e4de6c..c0074144e78d9f 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj @@ -3,6 +3,7 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true + $(Features);InterceptorsPreview true true Configuration support for Microsoft.Extensions.Logging. diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj index abc5c9d9792eef..0dceab438f82f3 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj @@ -7,7 +7,9 @@ $(DefineConstants);NO_SUPPRESS_GC_TRANSITION true true + $(Features);InterceptorsPreview true + true Console logger provider implementation for Microsoft.Extensions.Logging. diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/Microsoft.Extensions.Options.ConfigurationExtensions.SourceGeneration.Tests.csproj b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/Microsoft.Extensions.Options.ConfigurationExtensions.SourceGeneration.Tests.csproj index f1843ebff94a2a..0676fddc289826 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/Microsoft.Extensions.Options.ConfigurationExtensions.SourceGeneration.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/Microsoft.Extensions.Options.ConfigurationExtensions.SourceGeneration.Tests.csproj @@ -2,9 +2,9 @@ enable $(NetCoreAppCurrent);$(NetFrameworkMinimum) - true $(DefineConstants);BUILDING_SOURCE_GENERATOR_TESTS;ROSLYN4_0_OR_GREATER;ROSLYN4_4_OR_GREATER - + $(Features);InterceptorsPreview + true true From b7a3590e9906a9e889cb645b82d526eccc8b02dc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 07:43:57 -0700 Subject: [PATCH 047/783] [release/8.0] Events for IL methods without IL headers (#90844) * Events for IL methods without IL headers Dynamically generated methods like UnsafeAccessor functions are marked as IL, but don't contain an IL header. The lack of header is an indication the IL must be generated at runtime. * Debugger check for no IL header * Update src/coreclr/debug/daccess/stack.cpp Co-authored-by: Tlakaelel Axayakatl Ceja * Review feedback * Remove redundent calls and another spot to check. * Move header include --------- Co-authored-by: Aaron R Robinson Co-authored-by: Tlakaelel Axayakatl Ceja --- src/coreclr/debug/daccess/stack.cpp | 9 +- src/coreclr/inc/eventtracebase.h | 6 +- src/coreclr/utilcode/stresslog.cpp | 2 +- src/coreclr/vm/eventtrace.cpp | 21 ++-- src/coreclr/vm/jitinterface.cpp | 2 +- src/coreclr/vm/method.hpp | 2 +- src/coreclr/vm/prestub.cpp | 116 ++++++++++---------- src/coreclr/vm/versionresilienthashcode.cpp | 8 +- 8 files changed, 90 insertions(+), 76 deletions(-) diff --git a/src/coreclr/debug/daccess/stack.cpp b/src/coreclr/debug/daccess/stack.cpp index 9402d529eb8ea3..6b9f1a491c291c 100644 --- a/src/coreclr/debug/daccess/stack.cpp +++ b/src/coreclr/debug/daccess/stack.cpp @@ -1253,14 +1253,19 @@ ClrDataFrame::GetLocalSig(MetaSig** sig, { // It turns out we cannot really get rid of this check. Dynamic methods // (including IL stubs) do not have their local sig's available after JIT time. - if (!m_methodDesc->IsIL()) + // IL methods with dynamically generated IL (for example, UnsafeAccessors) may + // not have an IL header. + COR_ILMETHOD* ilHeader = m_methodDesc->IsIL() + ? m_methodDesc->GetILHeader() + : NULL; + if (ilHeader == NULL) { *sig = NULL; *count = 0; return E_FAIL; } - COR_ILMETHOD_DECODER methodDecoder(m_methodDesc->GetILHeader()); + COR_ILMETHOD_DECODER methodDecoder(ilHeader); mdSignature localSig = methodDecoder.GetLocalVarSigTok() ? methodDecoder.GetLocalVarSigTok() : mdSignatureNil; if (localSig == mdSignatureNil) diff --git a/src/coreclr/inc/eventtracebase.h b/src/coreclr/inc/eventtracebase.h index 97c3135153038c..3648b1f3a72136 100644 --- a/src/coreclr/inc/eventtracebase.h +++ b/src/coreclr/inc/eventtracebase.h @@ -905,7 +905,7 @@ namespace ETW BOOL fSendRichDebugInfoEvent, BOOL fGetCodeIds); static VOID SendEventsForNgenMethods(Module *pModule, DWORD dwEventOptions); - static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL); + static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL); static VOID SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWORD dwEventOptions, PCODE pNativeCodeStartAddress, DWORD nativeCodeId, ReJITID ilCodeId); static VOID SendMethodRichDebugInfo(MethodDesc * pMethodDesc, PCODE pNativeCodeStartAddress, DWORD nativeCodeId, ReJITID ilCodeId, MethodDescSet* sentMethodDetailsSet); static VOID SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptions, BOOL bIsJit, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, PCODE pNativeCodeStartAddress = 0, PrepareCodeConfig *pConfig = NULL, MethodDescSet* sentMethodDetailsSet = NULL); @@ -938,7 +938,7 @@ namespace ETW static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc); static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint); - static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature); + static VOID MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature); static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig); static VOID SendMethodDetailsEvent(MethodDesc *pMethodDesc); static VOID SendNonDuplicateMethodDetailsEvent(MethodDesc* pMethodDesc, MethodDescSet* set); @@ -952,7 +952,7 @@ namespace ETW public: static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc) {}; static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint) {}; - static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature); + static VOID MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature); static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig); static VOID StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName) {}; static VOID StubsInitialized(PVOID *pHelperStartAddress, PVOID *pHelperNames, LONG ulNoOfHelpers) {}; diff --git a/src/coreclr/utilcode/stresslog.cpp b/src/coreclr/utilcode/stresslog.cpp index c55c5afe9249c8..90ad5900473ed7 100644 --- a/src/coreclr/utilcode/stresslog.cpp +++ b/src/coreclr/utilcode/stresslog.cpp @@ -12,9 +12,9 @@ #include "switches.h" #include "stresslog.h" #include "clrhost.h" +#include "ex.h" #define DONOT_DEFINE_ETW_CALLBACK #include "eventtracebase.h" -#include "ex.h" #if !defined(STRESS_LOG_READONLY) #ifdef HOST_WINDOWS diff --git a/src/coreclr/vm/eventtrace.cpp b/src/coreclr/vm/eventtrace.cpp index b9a82cfb7c28e9..9498f00edf4329 100644 --- a/src/coreclr/vm/eventtrace.cpp +++ b/src/coreclr/vm/eventtrace.cpp @@ -3555,7 +3555,7 @@ VOID ETW::MethodLog::MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrC /*************************************************/ /* This is called by the runtime when method jitting started */ /*************************************************/ -VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature) +VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature) { CONTRACTL { NOTHROW; @@ -3570,7 +3570,7 @@ VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOr CLR_JIT_KEYWORD)) { pMethodDesc->GetMethodInfo(*namespaceOrClassName, *methodName, *methodSignature); - ETW::MethodLog::SendMethodJitStartEvent(pMethodDesc, namespaceOrClassName, methodName, methodSignature); + ETW::MethodLog::SendMethodJitStartEvent(pMethodDesc, methodDecoder, namespaceOrClassName, methodName, methodSignature); } } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions); } @@ -4528,7 +4528,12 @@ VOID ETW::MethodLog::SendNonDuplicateMethodDetailsEvent(MethodDesc* pMethodDesc, /*****************************************************************/ /* This routine is used to send an ETW event just before a method starts jitting*/ /*****************************************************************/ -VOID ETW::MethodLog::SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature) +VOID ETW::MethodLog::SendMethodJitStartEvent( + MethodDesc *pMethodDesc, + COR_ILMETHOD_DECODER* methodDecoder, + SString *namespaceOrClassName, + SString *methodName, + SString *methodSignature) { CONTRACTL { THROWS; @@ -4566,15 +4571,13 @@ VOID ETW::MethodLog::SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *n ulMethodToken = (ULONG)0; } else - ulMethodToken = (ULONG)pMethodDesc->GetMemberDef(); - - if(pMethodDesc->IsIL()) { - COR_ILMETHOD_DECODER::DecoderStatus decoderstatus = COR_ILMETHOD_DECODER::FORMAT_ERROR; - COR_ILMETHOD_DECODER ILHeader(pMethodDesc->GetILHeader(), pMethodDesc->GetMDImport(), &decoderstatus); - ulMethodILSize = (ULONG)ILHeader.GetCodeSize(); + ulMethodToken = (ULONG)pMethodDesc->GetMemberDef(); } + if (methodDecoder != NULL) + ulMethodILSize = methodDecoder->GetCodeSize(); + SString tNamespace, tMethodName, tMethodSignature; if(!namespaceOrClassName|| !methodName|| !methodSignature || (methodName->IsEmpty() && namespaceOrClassName->IsEmpty() && methodSignature->IsEmpty())) { diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 1a3439bdd235ef..74ee2f7482e747 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -12286,7 +12286,7 @@ static CorJitResult CompileMethodWithEtwWrapper(EEJitManager *jitMgr, SString namespaceOrClassName, methodName, methodSignature; // Fire an ETW event to mark the beginning of JIT'ing - ETW::MethodLog::MethodJitting(reinterpret_cast(info->ftn), &namespaceOrClassName, &methodName, &methodSignature); + ETW::MethodLog::MethodJitting(reinterpret_cast(info->ftn), NULL, &namespaceOrClassName, &methodName, &methodSignature); CorJitResult ret = jitMgr->m_jit->compileMethod(comp, info, flags, nativeEntry, nativeSizeOfCode); diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index 4b34045b57671e..e51d9f7453d35e 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -1819,7 +1819,7 @@ class MethodDesc PCODE GetMulticoreJitCode(PrepareCodeConfig* pConfig, bool* pWasTier0); PCODE JitCompileCode(PrepareCodeConfig* pConfig); PCODE JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry); - PCODE JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEntry* pLockEntry, ULONG* pSizeOfCode); + PCODE JitCompileCodeLocked(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pilHeader, JitListLockEntry* pLockEntry, ULONG* pSizeOfCode); public: bool TryGenerateUnsafeAccessor(DynamicResolver** resolver, COR_ILMETHOD_DECODER** methodILDecoder); diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp index 174e48565f31b8..32944952301648 100644 --- a/src/coreclr/vm/prestub.cpp +++ b/src/coreclr/vm/prestub.cpp @@ -709,6 +709,53 @@ PCODE MethodDesc::JitCompileCode(PrepareCodeConfig* pConfig) } } +namespace +{ + COR_ILMETHOD_DECODER* GetAndVerifyMetadataILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pDecoderMemory) + { + STANDARD_VM_CONTRACT; + _ASSERTE(pMD != NULL); + _ASSERTE(!pMD->IsNoMetadata()); + _ASSERTE(pConfig != NULL); + _ASSERTE(pDecoderMemory != NULL); + + COR_ILMETHOD_DECODER* pHeader = NULL; + COR_ILMETHOD* ilHeader = pConfig->GetILHeader(); + if (ilHeader == NULL) + return NULL; + + COR_ILMETHOD_DECODER::DecoderStatus status = COR_ILMETHOD_DECODER::FORMAT_ERROR; + { + // Decoder ctor can AV on a malformed method header + AVInRuntimeImplOkayHolder AVOkay; + pHeader = new (pDecoderMemory) COR_ILMETHOD_DECODER(ilHeader, pMD->GetMDImport(), &status); + } + + if (status == COR_ILMETHOD_DECODER::FORMAT_ERROR) + COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL); + + return pHeader; + } + + COR_ILMETHOD_DECODER* GetAndVerifyILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory) + { + STANDARD_VM_CONTRACT; + _ASSERTE(pMD != NULL); + if (pMD->IsIL()) + { + return GetAndVerifyMetadataILHeader(pMD, pConfig, pIlDecoderMemory); + } + else if (pMD->IsILStub()) + { + ILStubResolver* pResolver = pMD->AsDynamicMethodDesc()->GetILStubResolver(); + return pResolver->GetILHeader(); + } + + _ASSERTE(pMD->IsNoMetadata()); + return NULL; + } +} + PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry) { STANDARD_VM_CONTRACT; @@ -759,11 +806,18 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J } #endif // PROFILING_SUPPORTED + // The profiler may have changed the code on the callback. Need to + // pick up the new code. + // + // (don't want this for OSR, need to see how it works) + COR_ILMETHOD_DECODER ilDecoderTemp; + COR_ILMETHOD_DECODER* pilHeader = GetAndVerifyILHeader(this, pConfig, &ilDecoderTemp); + if (!ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context, TRACE_LEVEL_VERBOSE, CLR_JIT_KEYWORD)) { - pCode = JitCompileCodeLocked(pConfig, pEntry, &sizeOfCode); + pCode = JitCompileCodeLocked(pConfig, pilHeader, pEntry, &sizeOfCode); } else { @@ -778,12 +832,13 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J // a small stub of native code but no native-IL mapping. #ifndef FEATURE_INTERPRETER ETW::MethodLog::MethodJitting(this, + pilHeader, &namespaceOrClassName, &methodName, &methodSignature); #endif - pCode = JitCompileCodeLocked(pConfig, pEntry, &sizeOfCode); + pCode = JitCompileCodeLocked(pConfig, pilHeader, pEntry, &sizeOfCode); // Interpretted methods skip this notification #ifdef FEATURE_INTERPRETER @@ -869,66 +924,11 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J return pCode; } -namespace -{ - COR_ILMETHOD_DECODER* GetAndVerifyMetadataILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pDecoderMemory) - { - STANDARD_VM_CONTRACT; - _ASSERTE(pMD != NULL); - _ASSERTE(!pMD->IsNoMetadata()); - _ASSERTE(pConfig != NULL); - _ASSERTE(pDecoderMemory != NULL); - - COR_ILMETHOD_DECODER* pHeader = NULL; - COR_ILMETHOD* ilHeader = pConfig->GetILHeader(); - if (ilHeader == NULL) - return NULL; - - COR_ILMETHOD_DECODER::DecoderStatus status = COR_ILMETHOD_DECODER::FORMAT_ERROR; - { - // Decoder ctor can AV on a malformed method header - AVInRuntimeImplOkayHolder AVOkay; - pHeader = new (pDecoderMemory) COR_ILMETHOD_DECODER(ilHeader, pMD->GetMDImport(), &status); - } - - if (status == COR_ILMETHOD_DECODER::FORMAT_ERROR) - COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL); - - return pHeader; - } - - COR_ILMETHOD_DECODER* GetAndVerifyILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory) - { - STANDARD_VM_CONTRACT; - _ASSERTE(pMD != NULL); - if (pMD->IsIL()) - { - return GetAndVerifyMetadataILHeader(pMD, pConfig, pIlDecoderMemory); - } - else if (pMD->IsILStub()) - { - ILStubResolver* pResolver = pMD->AsDynamicMethodDesc()->GetILStubResolver(); - return pResolver->GetILHeader(); - } - - _ASSERTE(pMD->IsNoMetadata()); - return NULL; - } -} - -PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry, ULONG* pSizeOfCode) +PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pilHeader, JitListLockEntry* pEntry, ULONG* pSizeOfCode) { STANDARD_VM_CONTRACT; PCODE pCode = NULL; - - // The profiler may have changed the code on the callback. Need to - // pick up the new code. - // - // (don't want this for OSR, need to see how it works) - COR_ILMETHOD_DECODER ilDecoderTemp; - COR_ILMETHOD_DECODER* pilHeader = GetAndVerifyILHeader(this, pConfig, &ilDecoderTemp); - CORJIT_FLAGS jitFlags; PCODE pOtherCode = NULL; diff --git a/src/coreclr/vm/versionresilienthashcode.cpp b/src/coreclr/vm/versionresilienthashcode.cpp index b3ba764baac595..85bd146d8dc463 100644 --- a/src/coreclr/vm/versionresilienthashcode.cpp +++ b/src/coreclr/vm/versionresilienthashcode.cpp @@ -286,7 +286,7 @@ bool AddVersionResilientHashCodeForInstruction(ILInstructionParser *parser, xxHa hash->Add(varValue); break; } - + case InlineVar: // 2 byte value which is token change resilient { uint16_t varValue; @@ -388,6 +388,12 @@ bool GetVersionResilientILCodeHashCode(MethodDesc *pMD, int* hashCode, unsigned* initLocals = (options & CORINFO_OPT_INIT_LOCALS) == CORINFO_OPT_INIT_LOCALS; } + else if (!pMD->HasILHeader()) + { + // Dynamically generated IL methods like UnsafeAccessors may not have + // an IL header. + return false; + } else { COR_ILMETHOD_DECODER header(pMD->GetILHeader(TRUE), pMD->GetMDImport(), NULL); From b7905da1ae57c6ebf5999d9cea319da049e5b512 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 09:49:58 -0700 Subject: [PATCH 048/783] [release/8.0] Change OneLocBuild mirror branch to release/8.0 (#90813) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [main] Change OneLocBuild mirror branch to release/8.0 temporarily * Re-enable OneLocBuild in runtime-official.yml * Do not modify common, add the parameter in the uncommented lines instead. * Revert spacing * Change condition --------- Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- eng/pipelines/runtime-official.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index 172a40e24d169f..46f7872817e8f3 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -41,13 +41,13 @@ extends: # Localization build # - # disabled due to https://github.com/dotnet/runtime/issues/90466 - #- ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}: - # - template: /eng/common/templates/job/onelocbuild.yml - # parameters: - # MirrorRepo: runtime - # LclSource: lclFilesfromPackage - # LclPackageId: 'LCL-JUNO-PROD-RUNTIME' + - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/release/8.0') }}: + - template: /eng/common/templates/job/onelocbuild.yml + parameters: + MirrorRepo: runtime + MirrorBranch: release/8.0 + LclSource: lclFilesfromPackage + LclPackageId: 'LCL-JUNO-PROD-RUNTIME' # # Source Index Build From a54450d065ebd780b936213100546568d16e814f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 13:52:27 -0700 Subject: [PATCH 049/783] Add missing space in yaml (#90894) Co-authored-by: Matt Mitchell --- eng/pipelines/runtime-official.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index 46f7872817e8f3..9c341a04791289 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -42,12 +42,12 @@ extends: # - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/release/8.0') }}: - - template: /eng/common/templates/job/onelocbuild.yml - parameters: - MirrorRepo: runtime - MirrorBranch: release/8.0 - LclSource: lclFilesfromPackage - LclPackageId: 'LCL-JUNO-PROD-RUNTIME' + - template: /eng/common/templates/job/onelocbuild.yml + parameters: + MirrorRepo: runtime + MirrorBranch: release/8.0 + LclSource: lclFilesfromPackage + LclPackageId: 'LCL-JUNO-PROD-RUNTIME' # # Source Index Build From 9c4d1a368bb002cd02e7ee62c06cfcb0ff54f2b0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 09:19:48 -0700 Subject: [PATCH 050/783] Fix queue count in rate limiters (#90878) Co-authored-by: Brennan --- .../RateLimiting/ConcurrencyLimiter.cs | 40 ++++++++++++++++--- .../RateLimiting/FixedWindowRateLimiter.cs | 39 +++++++++++++++--- .../RateLimiting/SlidingWindowRateLimiter.cs | 39 +++++++++++++++--- .../RateLimiting/TokenBucketRateLimiter.cs | 40 ++++++++++++++++--- 4 files changed, 136 insertions(+), 22 deletions(-) diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/ConcurrencyLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/ConcurrencyLimiter.cs index 6b5a4014990ef0..7131b4fe1d7999 100644 --- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/ConcurrencyLimiter.cs +++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/ConcurrencyLimiter.cs @@ -156,8 +156,17 @@ protected override ValueTask AcquireAsyncCore(int permitCount, C Debug.Assert(_queueCount >= 0); if (!oldestRequest.TrySetResult(FailedLease)) { - // Updating queue count is handled by the cancellation code - _queueCount += oldestRequest.Count; + if (!oldestRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + oldestRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += oldestRequest.Count; + } } else { @@ -277,10 +286,19 @@ private void Release(int releaseCount) // Check if request was canceled if (!nextPendingRequest.TrySetResult(lease)) { - // Queued item was canceled so add count back + // Queued item was canceled so add count back, permits weren't acquired _permitCount += nextPendingRequest.Count; - // Updating queue count is handled by the cancellation code - _queueCount += nextPendingRequest.Count; + if (!nextPendingRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + nextPendingRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += nextPendingRequest.Count; + } } else { @@ -399,6 +417,9 @@ private sealed class RequestRegistration : TaskCompletionSource private readonly CancellationToken _cancellationToken; private CancellationTokenRegistration _cancellationTokenRegistration; + // Update under the limiter lock and only if the queue count was updated by the calling code + public bool QueueCountModified { get; set; } + // this field is used only by the disposal mechanics and never shared between threads private RequestRegistration? _next; @@ -429,7 +450,14 @@ private static void Cancel(object? state) var limiter = (ConcurrencyLimiter)registration.Task.AsyncState!; lock (limiter.Lock) { - limiter._queueCount -= registration.Count; + // Queuing and replenishing code might modify the _queueCount, since there is no guarantee of when the cancellation + // code runs and we only want to update the _queueCount once, we set a bool (under a lock) so either method + // can update the count and not double count. + if (!registration.QueueCountModified) + { + limiter._queueCount -= registration.Count; + registration.QueueCountModified = true; + } } } } diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs index d09c7973b18aa7..daaed9cf5ce422 100644 --- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs +++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs @@ -173,7 +173,17 @@ protected override ValueTask AcquireAsyncCore(int permitCount, C Debug.Assert(_queueCount >= 0); if (!oldestRequest.TrySetResult(FailedLease)) { - _queueCount += oldestRequest.Count; + if (!oldestRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + oldestRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += oldestRequest.Count; + } } else { @@ -330,10 +340,19 @@ private void ReplenishInternal(long nowTicks) if (!nextPendingRequest.TrySetResult(SuccessfulLease)) { - // Queued item was canceled so add count back + // Queued item was canceled so add count back, permits weren't acquired _permitCount += nextPendingRequest.Count; - // Updating queue count is handled by the cancellation code - _queueCount += nextPendingRequest.Count; + if (!nextPendingRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + nextPendingRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += nextPendingRequest.Count; + } } else { @@ -435,6 +454,9 @@ private sealed class RequestRegistration : TaskCompletionSource private readonly CancellationToken _cancellationToken; private CancellationTokenRegistration _cancellationTokenRegistration; + // Update under the limiter lock and only if the queue count was updated by the calling code + public bool QueueCountModified { get; set; } + // this field is used only by the disposal mechanics and never shared between threads private RequestRegistration? _next; @@ -465,7 +487,14 @@ private static void Cancel(object? state) var limiter = (FixedWindowRateLimiter)registration.Task.AsyncState!; lock (limiter.Lock) { - limiter._queueCount -= registration.Count; + // Queuing and replenishing code might modify the _queueCount, since there is no guarantee of when the cancellation + // code runs and we only want to update the _queueCount once, we set a bool (under a lock) so either method + // can update the count and not double count. + if (!registration.QueueCountModified) + { + limiter._queueCount -= registration.Count; + registration.QueueCountModified = true; + } } } } diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiter.cs index a179720ede33fa..23dbf98e0fcdea 100644 --- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiter.cs +++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiter.cs @@ -185,7 +185,17 @@ protected override ValueTask AcquireAsyncCore(int permitCount, C Debug.Assert(_queueCount >= 0); if (!oldestRequest.TrySetResult(FailedLease)) { - _queueCount += oldestRequest.Count; + if (!oldestRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + oldestRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += oldestRequest.Count; + } } else { @@ -342,11 +352,20 @@ private void ReplenishInternal(long nowTicks) if (!nextPendingRequest.TrySetResult(SuccessfulLease)) { - // Queued item was canceled so add count back + // Queued item was canceled so add count back, permits weren't acquired _permitCount += nextPendingRequest.Count; _requestsPerSegment[_currentSegmentIndex] -= nextPendingRequest.Count; - // Updating queue count is handled by the cancellation code - _queueCount += nextPendingRequest.Count; + if (!nextPendingRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + nextPendingRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += nextPendingRequest.Count; + } } else { @@ -448,6 +467,9 @@ private sealed class RequestRegistration : TaskCompletionSource private readonly CancellationToken _cancellationToken; private CancellationTokenRegistration _cancellationTokenRegistration; + // Update under the limiter lock and only if the queue count was updated by the calling code + public bool QueueCountModified { get; set; } + // this field is used only by the disposal mechanics and never shared between threads private RequestRegistration? _next; @@ -478,7 +500,14 @@ private static void Cancel(object? state) var limiter = (SlidingWindowRateLimiter)registration.Task.AsyncState!; lock (limiter.Lock) { - limiter._queueCount -= registration.Count; + // Queuing and replenishing code might modify the _queueCount, since there is no guarantee of when the cancellation + // code runs and we only want to update the _queueCount once, we set a bool (under a lock) so either method + // can update the count and not double count. + if (!registration.QueueCountModified) + { + limiter._queueCount -= registration.Count; + registration.QueueCountModified = true; + } } } } diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs index 5ad7859792ff7f..67a3a55a29ad03 100644 --- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs +++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs @@ -178,8 +178,17 @@ protected override ValueTask AcquireAsyncCore(int tokenCount, Ca Debug.Assert(_queueCount >= 0); if (!oldestRequest.TrySetResult(FailedLease)) { - // Updating queue count is handled by the cancellation code - _queueCount += oldestRequest.Count; + if (!oldestRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + oldestRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += oldestRequest.Count; + } } else { @@ -345,10 +354,19 @@ private void ReplenishInternal(long nowTicks) if (!nextPendingRequest.TrySetResult(SuccessfulLease)) { - // Queued item was canceled so add count back + // Queued item was canceled so add count back, permits weren't acquired _tokenCount += nextPendingRequest.Count; - // Updating queue count is handled by the cancellation code - _queueCount += nextPendingRequest.Count; + if (!nextPendingRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + nextPendingRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += nextPendingRequest.Count; + } } else { @@ -450,6 +468,9 @@ private sealed class RequestRegistration : TaskCompletionSource private readonly CancellationToken _cancellationToken; private CancellationTokenRegistration _cancellationTokenRegistration; + // Update under the limiter lock and only if the queue count was updated by the calling code + public bool QueueCountModified { get; set; } + // this field is used only by the disposal mechanics and never shared between threads private RequestRegistration? _next; @@ -480,7 +501,14 @@ private static void Cancel(object? state) var limiter = (TokenBucketRateLimiter)registration.Task.AsyncState!; lock (limiter.Lock) { - limiter._queueCount -= registration.Count; + // Queuing and replenishing code might modify the _queueCount, since there is no guarantee of when the cancellation + // code runs and we only want to update the _queueCount once, we set a bool (under a lock) so either method + // can update the count and not double count. + if (!registration.QueueCountModified) + { + limiter._queueCount -= registration.Count; + registration.QueueCountModified = true; + } } } } From 38e682f69e71b0ee46f92ef0ddc57a060d197812 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 13:38:21 -0600 Subject: [PATCH 051/783] [release/8.0] Update Fedora docker image to Fedora 38 (#90930) * Update Fedora image to Fedora 38 * (to revert) commit to check Fedora image specifically * Revert "(to revert) commit to check Fedora image specifically" This reverts commit 2e2d14e8d9586e5400ce3d7f7afd6ae26e9d9a6c. --------- Co-authored-by: Natalia Kondratyeva --- eng/pipelines/libraries/helix-queues-setup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 72d8d53cd94ddd..987d7f99c41f4a 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -62,13 +62,13 @@ jobs: - ${{ if and(eq(parameters.jobParameters.testScope, 'outerloop'), eq(parameters.jobParameters.runtimeFlavor, 'mono')) }}: - SLES.15.Amd64.Open - (Centos.8.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8-helix - - (Fedora.36.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-36-helix + - (Fedora.38.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-38-helix - (Ubuntu.2204.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-helix-amd64 - (Debian.11.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64 - ${{ if or(ne(parameters.jobParameters.testScope, 'outerloop'), ne(parameters.jobParameters.runtimeFlavor, 'mono')) }}: - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - SLES.15.Amd64.Open - - (Fedora.36.Amd64.Open)ubuntu.1804.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-36-helix + - (Fedora.38.Amd64.Open)ubuntu.1804.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-38-helix - Ubuntu.2204.Amd64.Open - (Debian.11.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64 - (Mariner.2.0.Amd64.Open)ubuntu.1804.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-helix-amd64 From d727d86b2c6270bfd7a75c0c53ce87ec6fc6fda5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 13:40:21 -0600 Subject: [PATCH 052/783] Update Microsoft.Extensions.Http.cs (#90920) Update ref, add missing `this` to extension method parameter Co-authored-by: Shreyas Jejurkar --- .../Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.cs b/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.cs index 9071751734f946..51891e8ebcf754 100644 --- a/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.cs +++ b/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.cs @@ -57,7 +57,7 @@ public static partial class HttpClientFactoryServiceCollectionExtensions public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action configureClient) where TClient : class where TImplementation : class, TClient { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Func factory) where TClient : class where TImplementation : class, TClient { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddHttpClient(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Func factory) where TClient : class where TImplementation : class, TClient { throw null; } - public static Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureHttpClientDefaults(Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configure) { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureHttpClientDefaults(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configure) { throw null; } } public partial interface IHttpClientBuilder { From 12d9907a0d8ca865767b08e99ab359a18f923cc6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 13:59:33 -0600 Subject: [PATCH 053/783] [release/8.0] Update dependencies from 7 repositories (#90766) * Update dependencies from https://github.com/dotnet/icu build 20230814.4 Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rc.1.23407.2 -> To Version 9.0.0-alpha.1.23414.4 * Update dependencies from https://github.com/dotnet/msquic build 20230812.1 System.Net.MsQuic.Transport From Version 8.0.0-alpha.1.23166.1 -> To Version 8.0.0-alpha.1.23412.1 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20230816.1 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23412.1 -> To Version 3.11.0-beta1.23416.1 * Update dependencies from https://github.com/dotnet/cecil build 20230814.1 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23407.2 -> To Version 0.11.4-alpha.23414.1 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20230817.2 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23412.1 -> To Version 3.11.0-beta1.23417.2 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20230814.1 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23381.3 -> To Version 8.0.0-alpha.1.23414.1 * Revert "Update dependencies from https://github.com/dotnet/icu build 20230814.4" This reverts commit 6e553e10c4977a6040aa044a608bb1181bb391b6. * Update dependencies from https://github.com/dotnet/icu build 20230818.1 Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rc.1.23407.2 -> To Version 8.0.0-rc.2.23418.1 * Update dependencies from https://github.com/dotnet/arcade build 20230817.3 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23415.4 -> To Version 8.0.0-beta.23417.3 * Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23415.1 -> To Version 1.0.0-beta.23416.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/arcade build 20230819.1 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23415.4 -> To Version 8.0.0-beta.23419.1 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23415.1 -> To Version 1.0.0-beta.23418.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20230820.2 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23412.1 -> To Version 3.11.0-beta1.23420.2 * Update dependencies from https://github.com/dotnet/cecil build 20230821.1 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23407.2 -> To Version 0.11.4-alpha.23421.1 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20230821.1 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23407.2 -> To Version 8.0.0-alpha.0.23421.1 * Update dependencies from https://github.com/dotnet/icu build 20230821.2 Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rc.1.23407.2 -> To Version 8.0.0-rc.2.23421.2 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20230821.3 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23412.1 -> To Version 3.11.0-beta1.23421.3 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20230821.1 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23381.3 -> To Version 8.0.0-alpha.1.23421.1 * [wasm] Fix Wasm.Build.Tests build (#90927) Prompted by the following getting caught as a warning, and converted to an error, on windows: ``` EXEC : error : dotnet-install: Failed to check the disk space. Installation will continue, but it may fail if you do not have [D:\a\_work\1\s\src\mono\wasm\Wasm.Build.Tests\Wasm.Build.Tests.csproj] enough disk space. dotnet-install: Extracting the archive. ``` (cherry picked from commit 09d7b439fa362c23d6546d1bce9a0a244ff2448f) --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Larry Ewing Co-authored-by: Ankit Jain --- eng/Version.Details.xml | 104 +++++++++++------------ eng/Versions.props | 42 ++++----- eng/common/native/init-compiler.sh | 2 +- eng/common/sdl/trim-assets-version.ps1 | 2 +- eng/common/templates/job/execute-sdl.yml | 5 ++ eng/testing/workloads-testing.targets | 1 + global.json | 6 +- 7 files changed, 84 insertions(+), 78 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6d255bdbc9f2af..492aa254177b02 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + https://github.com/dotnet/icu - 92124838d3f0efde3ac483a904691a611babb9a0 + b70521e39f983ec3da46cb4885da3a99e3477724 - + https://github.com/dotnet/msquic - a880e93af4e50d19110d228e698900c110e2b0e9 + 72811ab66f2611ac9f652cbb020dba033fc37401 https://github.com/dotnet/wcf @@ -85,9 +85,9 @@ 02fe27cd6a9b001c8feb7938e6ef4b3799745759b - + https://github.com/dotnet/cecil - 2f4ef297939628143389ddeea569874ded0b1c1b + d412306c1514a26737574838900052d8758da5be @@ -95,9 +95,9 @@ 66dbaefff04250dc72849f0172e0c53bcfb3ab38 - + https://github.com/dotnet/source-build-reference-packages - 5a1492557c8717b428b69fd4b7ca8c91d5d18cd3 + f4903e46459e0348e3793055dd8b68b8b0264034 @@ -107,79 +107,79 @@ - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/xliff-tasks - 649a1e75101b701d753ee41efbe9038f9b23a0db + bb654cd4736e7e8cb99f1c355ce2b8f0a686ba74 - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc https://github.com/dotnet/runtime-assets @@ -330,9 +330,9 @@ https://github.com/dotnet/xharness 480b9159eb7e69b182a87581d5a336e97e0b6dae - + https://github.com/dotnet/arcade - 46ff142f43e887d5f9a4d87ef39d72166f61db8d + 385129cbc980a515ddee2fa56f6b16f3183ed9bc https://dev.azure.com/dnceng/internal/_git/dotnet-optimization @@ -350,9 +350,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 068998a5d91f55a619d1d072ab3094dacd5d6a4f - + https://github.com/dotnet/hotreload-utils - 696312fd2a60671797b12311a4cf387d3cd14dd0 + e02247b9b7ec1d9e407312342147d8587a8ca20e https://github.com/dotnet/runtime-assets @@ -371,13 +371,13 @@ https://github.com/dotnet/roslyn 1fd4ff9d594b227baa3fc0962e2251323311ec19 - + https://github.com/dotnet/roslyn-analyzers - 755a4f888d64fc7c0f2802adca731f301a53283d + 76d99c5f3e11f0600fae074270c0d89042c360f0 - + https://github.com/dotnet/roslyn-analyzers - 755a4f888d64fc7c0f2802adca731f301a53283d + 76d99c5f3e11f0600fae074270c0d89042c360f0 https://github.com/dotnet/sdk diff --git a/eng/Versions.props b/eng/Versions.props index 314fcfd8e52f16..7760bd9a6a9686 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,8 +34,8 @@ - 3.11.0-beta1.23412.1 - 8.0.0-preview.23412.1 + 3.11.0-beta1.23421.3 + 8.0.0-preview.23421.3 8.0.100-preview.7.23329.3 - 8.0.0-beta.23415.4 - 8.0.0-beta.23415.4 - 8.0.0-beta.23415.4 - 8.0.0-beta.23415.4 - 8.0.0-beta.23415.4 - 2.5.1-beta.23415.4 - 8.0.0-beta.23415.4 - 8.0.0-beta.23415.4 - 8.0.0-beta.23415.4 - 8.0.0-beta.23415.4 - 8.0.0-beta.23415.4 - 8.0.0-beta.23415.4 - 8.0.0-beta.23415.4 - 8.0.0-beta.23415.4 - 8.0.0-beta.23415.4 + 8.0.0-beta.23419.1 + 8.0.0-beta.23419.1 + 8.0.0-beta.23419.1 + 8.0.0-beta.23419.1 + 8.0.0-beta.23419.1 + 2.5.1-beta.23419.1 + 8.0.0-beta.23419.1 + 8.0.0-beta.23419.1 + 8.0.0-beta.23419.1 + 8.0.0-beta.23419.1 + 8.0.0-beta.23419.1 + 8.0.0-beta.23419.1 + 8.0.0-beta.23419.1 + 8.0.0-beta.23419.1 + 8.0.0-beta.23419.1 6.0.0-preview.1.102 @@ -184,7 +184,7 @@ 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 - 8.0.0-alpha.0.23407.2 + 8.0.0-alpha.0.23421.1 2.4.2 1.0.0 2.4.5 @@ -213,14 +213,14 @@ 8.0.0-rc.1.23406.6 - 0.11.4-alpha.23407.2 + 0.11.4-alpha.23421.1 8.0.0-rc.1.23406.6 - 8.0.0-rc.1.23407.2 + 8.0.0-rc.2.23421.2 2.2.2 - 8.0.0-alpha.1.23180.2 + 8.0.0-alpha.1.23412.1 16.0.5-alpha.1.23408.1 16.0.5-alpha.1.23408.1 diff --git a/eng/common/native/init-compiler.sh b/eng/common/native/init-compiler.sh index 517401b688bf76..f5c1ec7eafeb28 100644 --- a/eng/common/native/init-compiler.sh +++ b/eng/common/native/init-compiler.sh @@ -63,7 +63,7 @@ if [ -z "$CLR_CC" ]; then # Set default versions if [ -z "$majorVersion" ]; then # note: gcc (all versions) and clang versions higher than 6 do not have minor version in file name, if it is zero. - if [ "$compiler" = "clang" ]; then versions="16 15 14 13 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5" + if [ "$compiler" = "clang" ]; then versions="17 16 15 14 13 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5" elif [ "$compiler" = "gcc" ]; then versions="13 12 11 10 9 8 7 6 5 4.9"; fi for version in $versions; do diff --git a/eng/common/sdl/trim-assets-version.ps1 b/eng/common/sdl/trim-assets-version.ps1 index d8cfec910c77e6..a2e0048770452f 100644 --- a/eng/common/sdl/trim-assets-version.ps1 +++ b/eng/common/sdl/trim-assets-version.ps1 @@ -25,7 +25,7 @@ function Install-VersionTools-Cli { Write-Host "Installing the package '$CliToolName' with a version of '$version' ..." $feed = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" - $argumentList = @("tool", "install", "--local", "$CliToolName", "--add-source $feed", "--no-cache", "--version $Version") + $argumentList = @("tool", "install", "--local", "$CliToolName", "--add-source $feed", "--no-cache", "--version $Version", "--create-manifest-if-needed") Start-Process "$dotnet" -Verbose -ArgumentList $argumentList -NoNewWindow -Wait } diff --git a/eng/common/templates/job/execute-sdl.yml b/eng/common/templates/job/execute-sdl.yml index 7aabaa18017bf6..7870f93bc17652 100644 --- a/eng/common/templates/job/execute-sdl.yml +++ b/eng/common/templates/job/execute-sdl.yml @@ -105,6 +105,11 @@ jobs: downloadPath: $(Build.ArtifactStagingDirectory)\artifacts checkDownloadedFiles: true + - powershell: eng/common/sdl/trim-assets-version.ps1 + -InputPath $(Build.ArtifactStagingDirectory)\artifacts + displayName: Trim the version from the NuGet packages + continueOnError: ${{ parameters.sdlContinueOnError }} + - powershell: eng/common/sdl/extract-artifact-packages.ps1 -InputPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts diff --git a/eng/testing/workloads-testing.targets b/eng/testing/workloads-testing.targets index 2961313c84973d..df5526e3f11583 100644 --- a/eng/testing/workloads-testing.targets +++ b/eng/testing/workloads-testing.targets @@ -76,6 +76,7 @@ Command="chmod +x $(_DotNetInstallScriptPath); $(_DotNetInstallCommand)" /> diff --git a/global.json b/global.json index cf4ac698e3e8cb..4142e57fcf5613 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.100-preview.7.23376.3" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23415.4", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23415.4", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23415.4", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23419.1", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23419.1", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23419.1", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From 5661a200c9fb5d2d58e2268b9dd11ee88caf853a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 15:45:25 -0600 Subject: [PATCH 054/783] [release/8.0] Error out when NativeLib has EventPipe enabled (#90934) * Error out when NativeLib has EventPipe enabled * Update src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets Co-authored-by: Andy Gocke * Update src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets Co-authored-by: Jan Kotas --------- Co-authored-by: Lakshan Fernando Co-authored-by: Andy Gocke Co-authored-by: Jan Kotas --- .../BuildIntegration/Microsoft.NETCore.Native.Publish.targets | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets index 647aee4993d960..32eefb307eb0fd 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets @@ -50,6 +50,8 @@ Text="RuntimeIdentifier is required for native compilation. Try running dotnet publish with the -r option value specified." /> + + From d4c6dd6b94f43424a9bea7b9eb905f0df6945a89 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 18:21:57 -0700 Subject: [PATCH 055/783] [release/8.0] [NativeAOT] Missing memory fence before bulk move of objects (#90941) * Memory fence before bulk move of objects * deleted GCMemoryHelpers.h * Introduced a GCHeapMemoryBarrier helper. --------- Co-authored-by: vsadov <8218165+VSadov@users.noreply.github.com> --- .../nativeaot/Runtime/GCMemoryHelpers.cpp | 21 +++++++++++++------ .../nativeaot/Runtime/GCMemoryHelpers.h | 8 ------- src/coreclr/nativeaot/Runtime/MiscHelpers.cpp | 1 - src/coreclr/nativeaot/Runtime/gcrhenv.cpp | 1 - src/coreclr/nativeaot/Runtime/portable.cpp | 1 - src/coreclr/nativeaot/Runtime/threadstore.cpp | 1 - 6 files changed, 15 insertions(+), 18 deletions(-) delete mode 100644 src/coreclr/nativeaot/Runtime/GCMemoryHelpers.h diff --git a/src/coreclr/nativeaot/Runtime/GCMemoryHelpers.cpp b/src/coreclr/nativeaot/Runtime/GCMemoryHelpers.cpp index 27126acbdb839f..30f2c5c5fd3e9a 100644 --- a/src/coreclr/nativeaot/Runtime/GCMemoryHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/GCMemoryHelpers.cpp @@ -10,7 +10,6 @@ #include "PalRedhawkCommon.h" #include "CommonMacros.inl" -#include "GCMemoryHelpers.h" #include "GCMemoryHelpers.inl" // This function clears a piece of memory in a GC safe way. @@ -31,11 +30,26 @@ COOP_PINVOKE_CDECL_HELPER(void *, RhpGcSafeZeroMemory, (void * mem, size_t size) return mem; } +#if defined(TARGET_X86) || defined(TARGET_AMD64) + // + // Memory writes are already ordered + // + #define GCHeapMemoryBarrier() +#else + #define GCHeapMemoryBarrier() MemoryBarrier() +#endif + // Move memory, in a way that is compatible with a move onto the heap, but // does not require the destination pointer to be on the heap. COOP_PINVOKE_HELPER(void, RhBulkMoveWithWriteBarrier, (uint8_t* pDest, uint8_t* pSrc, size_t cbDest)) { + // It is possible that the bulk write is publishing object references accessible so far only + // by the current thread to shared memory. + // The memory model requires that writes performed by current thread are observable no later + // than the writes that will actually publish the references. + GCHeapMemoryBarrier(); + if (pDest <= pSrc || pSrc + cbDest <= pDest) InlineForwardGCSafeCopy(pDest, pSrc, cbDest); else @@ -43,8 +57,3 @@ COOP_PINVOKE_HELPER(void, RhBulkMoveWithWriteBarrier, (uint8_t* pDest, uint8_t* InlinedBulkWriteBarrier(pDest, cbDest); } - -void REDHAWK_CALLCONV RhpBulkWriteBarrier(void* pMemStart, uint32_t cbMemSize) -{ - InlinedBulkWriteBarrier(pMemStart, cbMemSize); -} diff --git a/src/coreclr/nativeaot/Runtime/GCMemoryHelpers.h b/src/coreclr/nativeaot/Runtime/GCMemoryHelpers.h deleted file mode 100644 index 127b4d772040ab..00000000000000 --- a/src/coreclr/nativeaot/Runtime/GCMemoryHelpers.h +++ /dev/null @@ -1,8 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// Unmanaged GC memory helpers -// - -EXTERN_C void REDHAWK_CALLCONV RhpBulkWriteBarrier(void* pMemStart, uint32_t cbMemSize); diff --git a/src/coreclr/nativeaot/Runtime/MiscHelpers.cpp b/src/coreclr/nativeaot/Runtime/MiscHelpers.cpp index ec2fabcc540f1f..6df37cf23b9d36 100644 --- a/src/coreclr/nativeaot/Runtime/MiscHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/MiscHelpers.cpp @@ -35,7 +35,6 @@ #include "MethodTable.inl" #include "CommonMacros.inl" #include "volatile.h" -#include "GCMemoryHelpers.h" #include "GCMemoryHelpers.inl" #include "yieldprocessornormalized.h" #include "RhConfig.h" diff --git a/src/coreclr/nativeaot/Runtime/gcrhenv.cpp b/src/coreclr/nativeaot/Runtime/gcrhenv.cpp index 3d0990962b7c99..3ec488605c1b33 100644 --- a/src/coreclr/nativeaot/Runtime/gcrhenv.cpp +++ b/src/coreclr/nativeaot/Runtime/gcrhenv.cpp @@ -42,7 +42,6 @@ #include "daccess.h" -#include "GCMemoryHelpers.h" #include "interoplibinterface.h" #include "holder.h" diff --git a/src/coreclr/nativeaot/Runtime/portable.cpp b/src/coreclr/nativeaot/Runtime/portable.cpp index d45b3d062d00e3..8b425bfe2dff12 100644 --- a/src/coreclr/nativeaot/Runtime/portable.cpp +++ b/src/coreclr/nativeaot/Runtime/portable.cpp @@ -31,7 +31,6 @@ #include "MethodTable.inl" #include "ObjectLayout.h" -#include "GCMemoryHelpers.h" #include "GCMemoryHelpers.inl" #if defined(USE_PORTABLE_HELPERS) diff --git a/src/coreclr/nativeaot/Runtime/threadstore.cpp b/src/coreclr/nativeaot/Runtime/threadstore.cpp index 67a6949fd7fb06..2e8369f9175fc5 100644 --- a/src/coreclr/nativeaot/Runtime/threadstore.cpp +++ b/src/coreclr/nativeaot/Runtime/threadstore.cpp @@ -24,7 +24,6 @@ #include "yieldprocessornormalized.h" #include "slist.inl" -#include "GCMemoryHelpers.h" EXTERN_C volatile uint32_t RhpTrapThreads; volatile uint32_t RhpTrapThreads = (uint32_t)TrapThreadsFlags::None; From 6f0dd7cb1b0624a6d6de38351b665fa317a53fa2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 22:22:54 -0700 Subject: [PATCH 056/783] Update dependencies from https://github.com/dotnet/arcade build 20230817.3 (#90814) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23415.4 -> To Version 8.0.0-beta.23417.3 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23415.1 -> To Version 1.0.0-beta.23416.1 (parent: Microsoft.DotNet.Arcade.Sdk Co-authored-by: dotnet-maestro[bot] Co-authored-by: Larry Ewing Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> From ba6a4adb228567a6bb3f4a9e5789fb74c47c8c94 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 23 Aug 2023 08:59:19 -0700 Subject: [PATCH 057/783] Update dependencies from https://github.com/dotnet/arcade build 20230822.1 (#90983) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23419.1 -> To Version 8.0.0-beta.23422.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 72 +++++++++---------- eng/Versions.props | 30 ++++---- eng/common/loc/P22DotNetHtmlLocalization.lss | Bin 3842 -> 1876 bytes global.json | 6 +- 4 files changed, 54 insertions(+), 54 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 492aa254177b02..270d5c0b3ad3e8 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -107,9 +107,9 @@ - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b @@ -117,69 +117,69 @@ bb654cd4736e7e8cb99f1c355ce2b8f0a686ba74 - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b https://github.com/dotnet/runtime-assets @@ -330,9 +330,9 @@ https://github.com/dotnet/xharness 480b9159eb7e69b182a87581d5a336e97e0b6dae - + https://github.com/dotnet/arcade - 385129cbc980a515ddee2fa56f6b16f3183ed9bc + 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index 7760bd9a6a9686..f86168bdf919a3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -85,21 +85,21 @@ 8.0.100-preview.7.23329.3 - 8.0.0-beta.23419.1 - 8.0.0-beta.23419.1 - 8.0.0-beta.23419.1 - 8.0.0-beta.23419.1 - 8.0.0-beta.23419.1 - 2.5.1-beta.23419.1 - 8.0.0-beta.23419.1 - 8.0.0-beta.23419.1 - 8.0.0-beta.23419.1 - 8.0.0-beta.23419.1 - 8.0.0-beta.23419.1 - 8.0.0-beta.23419.1 - 8.0.0-beta.23419.1 - 8.0.0-beta.23419.1 - 8.0.0-beta.23419.1 + 8.0.0-beta.23422.1 + 8.0.0-beta.23422.1 + 8.0.0-beta.23422.1 + 8.0.0-beta.23422.1 + 8.0.0-beta.23422.1 + 2.5.1-beta.23422.1 + 8.0.0-beta.23422.1 + 8.0.0-beta.23422.1 + 8.0.0-beta.23422.1 + 8.0.0-beta.23422.1 + 8.0.0-beta.23422.1 + 8.0.0-beta.23422.1 + 8.0.0-beta.23422.1 + 8.0.0-beta.23422.1 + 8.0.0-beta.23422.1 6.0.0-preview.1.102 diff --git a/eng/common/loc/P22DotNetHtmlLocalization.lss b/eng/common/loc/P22DotNetHtmlLocalization.lss index 858a0b237c62ce4f2ee12aa14794f160f6b122b7..5d892d619398f9feeac4cefc1c53ff18a807f732 100644 GIT binary patch literal 1876 zcmd5-O>Y`85WVMDO!tse0|`=3Kq5qFvJwFroLr(PGHdUyD`QjJ8$y14$Ln3lZW2{J zwGs!I&o^(Lhrz|mTEa6oR%kVh&N`>j#re@-x_nwr2#IG`%ct-0baH+K&@f(3mgC!a zLE`z$`_TL4VSG6vqld@GGPwJ;L@RorHxAn^xdXw5(R4X4f7_@k)pTF-lorz22$--N zNp~~4=EJDUfxSBovWjDy#&0y*A$Y%{951Lgf#O!hPmkZU}#I!)Wng z1f<%)R3}u5SL$^NOII+VJC!`W+V>zz0i%$|xtEKJRoWJsS2-4>j6oFy0;9}2)ZXS? z!4+5B;BS?^g*W;n#c6Okuah`~R7l#LlUM`Wwgi;X`GgRCXg2Aj93+p!!wlyufdm#b2J0d!FWGIX~B#Nn{?*T z-%qWy16eI?CAp^@t!rT|vicQ-vsH(!kP=oLa9cnNr~Mvq*K+4!SBpR#0ixlQVLn!4 z_-b`9x-gH#c?z0gti{WerraQ#kQ%)%r?a{+35PnWsUFnNN^8lf0v68Oy&oSBa0E$V ze5J~88to5MDZA?699~0Him^%vH|v?chtS*Ws!BWhyEn^bjuBh5M+wg@h`3AQ cw&^?j6MgS4IM#l5)SHHef6(}&EB`Bh1GJK71^@s6 literal 3842 zcmd^?%T5$g5Qb}Q;yWB!uo4gwSD=IdDhbFa0~=!u%y4NlOykf9`fh|r;uZYH%XVd_Hn3nn?a)ScZi%Hfv^O?o^EPX*xG&pV zdv4F4*^+JAj(y{^Ze6Yo`)Kdu$~&GnS-les=(}Hd4Z$5-wa;woL^azeDs1)bFYF6K zYqo;O3eR7;3PMXZcdt9G7M2L|%(A;+cL+Vh<;40ia7DRYcz+HE1jrRpV_p*&!nF z$63@IaaFcvPRXqUT!EoEiMw~cG<%Xu1rqKRFp4w~aJ8hjgHT7ZDe-mb8W8O!t5`M} ztjgBRJpt|=SdiLxc+i9U&FGh9|IZv$NUelFF6qG*xY~f;wk`WWC*7iH2HNhpSVO7O zyjh))z5&gu%l(Qp>Nx07A`jIOXn!e02v|!Y!amv(`^`P?xq%*=(IC|pQx2Mm#Wop? zaijLey=o_a!^t>PhS7L4AbHDoC--rqkF#Y>vg5i&^y;GPmsmXHUEuiBT|Lj=5A8Un zViJHWkF=5jOaLV5s#-dX{vP4sfVZ=}?;@uYMqc~3{L6QHIy{PC)9lJ@k#y=HUqMdP z=#t_YRzBG-DDIK;Y5PHn(kQ#ieaMsI&5-MIikcQm zB9?pn%E>6AT}IUVSi2;S8K#g0d(Ee4XBw2{|D?DN(56#J`IN_F465Cx8|@w=tHXbj zU&@|NZLLZ7222|77ga@RWjf<2u>)ikm8K_A{31S!HRE05qRWsu=1qcb*PrKMEaNuH zxG7hoiSg&T9>yF6JSZ32L1c$;kl)UW(|FgMr)Xcsb Date: Wed, 23 Aug 2023 12:49:33 -0700 Subject: [PATCH 058/783] [release/8.0] Update dependencies from dotnet/roslyn (#90816) * Update dependencies from https://github.com/dotnet/roslyn build 20230818.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23418.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230818.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23418.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230818.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23418.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230818.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23418.5 * Update dependencies from https://github.com/dotnet/roslyn build 20230818.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23418.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230819.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23419.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230821.15 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23421.15 * Update dependencies from https://github.com/dotnet/roslyn build 20230822.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23422.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230822.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23422.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230822.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23422.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230822.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23422.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230822.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23422.5 * Update dependencies from https://github.com/dotnet/roslyn build 20230821.10 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23421.10 * Update dependencies from https://github.com/dotnet/roslyn build 20230822.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23422.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230822.8 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23422.8 * Update dependencies from https://github.com/dotnet/roslyn build 20230822.9 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23422.9 * Update dependencies from https://github.com/dotnet/roslyn build 20230822.7 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23422.7 * Update dependencies from https://github.com/dotnet/roslyn build 20230822.11 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23422.11 * Update dependencies from https://github.com/dotnet/roslyn build 20230822.12 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23422.12 * Update dependencies from https://github.com/dotnet/roslyn build 20230822.13 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-1.23422.13 * Update dependencies from https://github.com/dotnet/roslyn build 20230822.14 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-1.23408.8 -> To Version 4.8.0-2.23422.14 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 270d5c0b3ad3e8..22b39bcd09b8bf 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 48270e734aa881c737b80c4fe0459e68aaf08ad6 - + https://github.com/dotnet/roslyn - 1fd4ff9d594b227baa3fc0962e2251323311ec19 + 93ce610622875b8e843f348e96496abd7056360d - + https://github.com/dotnet/roslyn - 1fd4ff9d594b227baa3fc0962e2251323311ec19 + 93ce610622875b8e843f348e96496abd7056360d - + https://github.com/dotnet/roslyn - 1fd4ff9d594b227baa3fc0962e2251323311ec19 + 93ce610622875b8e843f348e96496abd7056360d https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index f86168bdf919a3..6fa3fc30b30156 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -42,9 +42,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-1.23408.8 - 4.8.0-1.23408.8 - 4.8.0-1.23408.8 + 4.8.0-2.23422.14 + 4.8.0-2.23422.14 + 4.8.0-2.23422.14 - 8.0.0-beta.23408.1 - 8.0.0-beta.23408.1 - 8.0.0-beta.23408.1 - 8.0.0-beta.23408.1 - 8.0.0-beta.23408.1 - 8.0.0-beta.23408.1 - 8.0.0-beta.23408.1 - 8.0.0-beta.23408.1 - 8.0.0-beta.23408.1 - 8.0.0-beta.23408.1 - 8.0.0-beta.23408.1 - 8.0.0-beta.23408.1 - 8.0.0-beta.23408.1 - 8.0.0-beta.23408.1 + 8.0.0-beta.23421.1 + 8.0.0-beta.23421.1 + 8.0.0-beta.23421.1 + 8.0.0-beta.23421.1 + 8.0.0-beta.23421.1 + 8.0.0-beta.23421.1 + 8.0.0-beta.23421.1 + 8.0.0-beta.23421.1 + 8.0.0-beta.23421.1 + 8.0.0-beta.23421.1 + 8.0.0-beta.23421.1 + 8.0.0-beta.23421.1 + 8.0.0-beta.23421.1 + 8.0.0-beta.23421.1 1.0.0-prerelease.23362.5 1.0.0-prerelease.23362.5 From 010980181b380f712bde42d3c1efab0e180414fc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 23 Aug 2023 12:51:40 -0700 Subject: [PATCH 060/783] [release/8.0] [mono] Initialize module's image ALC for dynamic objects (#90912) * Use the image's ALC instead of the default one if exists * Init module's image ALC * Add runtime test for dynamic objects * Fix lint * Disable test on platforms that don't support dynamic code generation --------- Co-authored-by: Milos Kotlar --- src/mono/mono/metadata/sre.c | 2 + .../Loader/CustomAttributes/DynamicObjects.cs | 107 ++++++++++++++++++ .../CustomAttributes/DynamicObjects.csproj | 9 ++ src/tests/issues.targets | 7 ++ 4 files changed, 125 insertions(+) create mode 100644 src/tests/Loader/CustomAttributes/DynamicObjects.cs create mode 100644 src/tests/Loader/CustomAttributes/DynamicObjects.csproj diff --git a/src/mono/mono/metadata/sre.c b/src/mono/mono/metadata/sre.c index de94e8c4bf9a3b..3f47f9e84d008e 100644 --- a/src/mono/mono/metadata/sre.c +++ b/src/mono/mono/metadata/sre.c @@ -1289,6 +1289,7 @@ image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *e * determined at assembly save time. */ /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */ + MonoAssemblyLoadContext *alc = mono_alc_get_default (); MonoStringHandle abname = MONO_HANDLE_NEW_GET (MonoString, ab, name); char *name = mono_string_handle_to_utf8 (abname, error); return_val_if_nok (error, FALSE); @@ -1300,6 +1301,7 @@ image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *e } MonoDynamicAssembly *dynamic_assembly = MONO_HANDLE_GETVAL (ab, dynamic_assembly); image = mono_dynamic_image_create (dynamic_assembly, name, fqname); + image->image.alc = alc; MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionModule, moduleb), image, MonoImage*, &image->image); MONO_HANDLE_SETVAL (moduleb, dynamic_image, MonoDynamicImage*, image); diff --git a/src/tests/Loader/CustomAttributes/DynamicObjects.cs b/src/tests/Loader/CustomAttributes/DynamicObjects.cs new file mode 100644 index 00000000000000..5b232d83eba3bb --- /dev/null +++ b/src/tests/Loader/CustomAttributes/DynamicObjects.cs @@ -0,0 +1,107 @@ +using System; +using System.Resources; +using System.Reflection; +using System.Reflection.Emit; +using System.ComponentModel.DataAnnotations; +using System.Linq; + +using Xunit; + +#nullable disable + +namespace DynamicObjects { + public class M { + public const string ObjectRequiredMessage = "some string"; + public static int Main() { + var instance = createObject(); + var attrs = instance.GetType().GetProperty("prop1").GetCustomAttributes(); + + Assert.True(attrs.Count() == 2); + Assert.Equal(attrs.ElementAt(0).ToString(), "System.ComponentModel.DataAnnotations.DisplayAttribute"); + Assert.Equal(attrs.ElementAt(1).ToString(), "System.ComponentModel.DataAnnotations.RequiredAttribute"); + Assert.Equal(typeof(RequiredAttribute), attrs.ElementAt(1).GetType()); + Assert.Equal(ObjectRequiredMessage, ((RequiredAttribute)attrs.ElementAt(1)).FormatErrorMessage("abc")); + + Console.WriteLine("Success"); + return 100; + } + + public static object createObject () { + var an = new AssemblyName { Name = "TempAssembly" ,Version = new Version(1, 0, 0, 0) }; + var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); + var moduleBuilder = assemblyBuilder.DefineDynamicModule("TempWorkflowAssembly.dll"); + var tb = moduleBuilder.DefineType("namespace.myclass" + , TypeAttributes.Public | + TypeAttributes.Class | + TypeAttributes.AnsiClass | + TypeAttributes.BeforeFieldInit + , typeof(object)); + + FieldBuilder fb = tb.DefineField("_prop1", + typeof(string), + FieldAttributes.Private); + + var pb = tb.DefineProperty("prop1", PropertyAttributes.HasDefault, typeof(string), null); + MethodAttributes getSetAttr = + MethodAttributes.Public | MethodAttributes.SpecialName | + MethodAttributes.HideBySig; + + // Define the "get" accessor method for prop1. + MethodBuilder custNameGetPropMthdBldr = + tb.DefineMethod("get_prop1", + getSetAttr, + typeof(string), + Type.EmptyTypes); + + ILGenerator custNameGetIL = custNameGetPropMthdBldr.GetILGenerator(); + + custNameGetIL.Emit(OpCodes.Ldarg_0); + custNameGetIL.Emit(OpCodes.Ldfld, fb); + custNameGetIL.Emit(OpCodes.Ret); + + // Define the "set" accessor method for prop1. + MethodBuilder custNameSetPropMthdBldr = + tb.DefineMethod("set_prop1", + getSetAttr, + null, + new Type[] { typeof(string) }); + + ILGenerator custNameSetIL = custNameSetPropMthdBldr.GetILGenerator(); + + custNameSetIL.Emit(OpCodes.Ldarg_0); + custNameSetIL.Emit(OpCodes.Ldarg_1); + custNameSetIL.Emit(OpCodes.Stfld, fb); + custNameSetIL.Emit(OpCodes.Ret); + + // Last, we must map the two methods created above to our PropertyBuilder to + // their corresponding behaviors, "get" and "set" respectively. + pb.SetGetMethod(custNameGetPropMthdBldr); + pb.SetSetMethod(custNameSetPropMthdBldr); + + + ///create display attribute + var dat = typeof(DisplayAttribute); + CustomAttributeBuilder CAB = new CustomAttributeBuilder(dat.GetConstructor(new Type[0]), + new object[0], + new PropertyInfo[1] { dat.GetProperty(nameof(DisplayAttribute.Name))}, + new object[] { "property 1"}); + pb.SetCustomAttribute(CAB); + + // //create required attribute + var rat = typeof(RequiredAttribute); + CustomAttributeBuilder CABR = new CustomAttributeBuilder(rat.GetConstructor(new Type[0]), + new object[0], + new PropertyInfo[2] { rat.GetProperty(nameof(RequiredAttribute.ErrorMessageResourceType)),rat.GetProperty(nameof(RequiredAttribute.ErrorMessageResourceName))}, + new object[] {typeof(ValidationErrors), "ObjectRequired" }); + pb.SetCustomAttribute(CABR); + + var objectType = tb.CreateType(); + return Activator.CreateInstance(objectType); + } + } + + public class ValidationErrors { + public static string ObjectRequired => M.ObjectRequiredMessage; + } + +} diff --git a/src/tests/Loader/CustomAttributes/DynamicObjects.csproj b/src/tests/Loader/CustomAttributes/DynamicObjects.csproj new file mode 100644 index 00000000000000..3e62bfd677e86a --- /dev/null +++ b/src/tests/Loader/CustomAttributes/DynamicObjects.csproj @@ -0,0 +1,9 @@ + + + Exe + + + + + + diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 22178e4b3b506d..bdccec81ac1f49 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -1177,6 +1177,10 @@ + + + Dynamic code generation is not supported on this platform + From 482bfb96ccd63da733bea3fe1f7f65fb4a3b6c67 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 23 Aug 2023 14:43:00 -0700 Subject: [PATCH 065/783] [release/8.0] Only initialize listeners once (#90932) * Only initialize listeners once. * Add test * Second call --------- Co-authored-by: Chris R --- .../Microsoft.Extensions.Diagnostics.sln | 49 +++++++++++++++++++ .../src/Metrics/MetricsServiceExtensions.cs | 10 +++- .../tests/MetricsSubscriptionManagerTests.cs | 44 +++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 src/libraries/Microsoft.Extensions.Diagnostics/tests/MetricsSubscriptionManagerTests.cs diff --git a/src/libraries/Microsoft.Extensions.Diagnostics/Microsoft.Extensions.Diagnostics.sln b/src/libraries/Microsoft.Extensions.Diagnostics/Microsoft.Extensions.Diagnostics.sln index 5e4931ef73fb1d..5b249c373b11c6 100644 --- a/src/libraries/Microsoft.Extensions.Diagnostics/Microsoft.Extensions.Diagnostics.sln +++ b/src/libraries/Microsoft.Extensions.Diagnostics/Microsoft.Extensions.Diagnostics.sln @@ -59,6 +59,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Config EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options", "..\Microsoft.Extensions.Options\ref\Microsoft.Extensions.Options.csproj", "{DBAB1C82-A3A0-4ADC-95BC-B87557C61C42}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Primitives", "..\Microsoft.Extensions.Primitives\ref\Microsoft.Extensions.Primitives.csproj", "{6BB43905-3DBD-47E4-A38F-2BE319300B15}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Primitives", "..\Microsoft.Extensions.Primitives\src\Microsoft.Extensions.Primitives.csproj", "{711B2905-FDC7-4D67-B40B-9DEFF042CB01}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options", "..\Microsoft.Extensions.Options\src\Microsoft.Extensions.Options.csproj", "{B233AB55-788C-48B6-9557-098B8D0DDBFF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Configuration.Binder", "..\Microsoft.Extensions.Configuration.Binder\src\Microsoft.Extensions.Configuration.Binder.csproj", "{ECF14067-8633-4DDA-8EAE-124989F8E09E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Configuration.Binder", "..\Microsoft.Extensions.Configuration.Binder\ref\Microsoft.Extensions.Configuration.Binder.csproj", "{D835A0A8-C213-461F-8B41-6F2715DBEC43}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options.ConfigurationExtensions", "..\Microsoft.Extensions.Options.ConfigurationExtensions\ref\Microsoft.Extensions.Options.ConfigurationExtensions.csproj", "{F2C0D619-8CAF-4F81-B681-3F75AF79661F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Configuration", "..\Microsoft.Extensions.Configuration\ref\Microsoft.Extensions.Configuration.csproj", "{57AF678A-3671-4B9E-9608-053E2197D0A4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -161,6 +175,34 @@ Global {DBAB1C82-A3A0-4ADC-95BC-B87557C61C42}.Debug|Any CPU.Build.0 = Debug|Any CPU {DBAB1C82-A3A0-4ADC-95BC-B87557C61C42}.Release|Any CPU.ActiveCfg = Release|Any CPU {DBAB1C82-A3A0-4ADC-95BC-B87557C61C42}.Release|Any CPU.Build.0 = Release|Any CPU + {6BB43905-3DBD-47E4-A38F-2BE319300B15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6BB43905-3DBD-47E4-A38F-2BE319300B15}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6BB43905-3DBD-47E4-A38F-2BE319300B15}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6BB43905-3DBD-47E4-A38F-2BE319300B15}.Release|Any CPU.Build.0 = Release|Any CPU + {711B2905-FDC7-4D67-B40B-9DEFF042CB01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {711B2905-FDC7-4D67-B40B-9DEFF042CB01}.Debug|Any CPU.Build.0 = Debug|Any CPU + {711B2905-FDC7-4D67-B40B-9DEFF042CB01}.Release|Any CPU.ActiveCfg = Release|Any CPU + {711B2905-FDC7-4D67-B40B-9DEFF042CB01}.Release|Any CPU.Build.0 = Release|Any CPU + {B233AB55-788C-48B6-9557-098B8D0DDBFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B233AB55-788C-48B6-9557-098B8D0DDBFF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B233AB55-788C-48B6-9557-098B8D0DDBFF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B233AB55-788C-48B6-9557-098B8D0DDBFF}.Release|Any CPU.Build.0 = Release|Any CPU + {ECF14067-8633-4DDA-8EAE-124989F8E09E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ECF14067-8633-4DDA-8EAE-124989F8E09E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ECF14067-8633-4DDA-8EAE-124989F8E09E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ECF14067-8633-4DDA-8EAE-124989F8E09E}.Release|Any CPU.Build.0 = Release|Any CPU + {D835A0A8-C213-461F-8B41-6F2715DBEC43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D835A0A8-C213-461F-8B41-6F2715DBEC43}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D835A0A8-C213-461F-8B41-6F2715DBEC43}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D835A0A8-C213-461F-8B41-6F2715DBEC43}.Release|Any CPU.Build.0 = Release|Any CPU + {F2C0D619-8CAF-4F81-B681-3F75AF79661F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F2C0D619-8CAF-4F81-B681-3F75AF79661F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F2C0D619-8CAF-4F81-B681-3F75AF79661F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F2C0D619-8CAF-4F81-B681-3F75AF79661F}.Release|Any CPU.Build.0 = Release|Any CPU + {57AF678A-3671-4B9E-9608-053E2197D0A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57AF678A-3671-4B9E-9608-053E2197D0A4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57AF678A-3671-4B9E-9608-053E2197D0A4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57AF678A-3671-4B9E-9608-053E2197D0A4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -190,6 +232,13 @@ Global {A2853038-B04A-4BAA-B0B4-0481457003B8} = {A447D0CB-601B-479E-A2B2-76E48F5D4D61} {A77E804D-4576-4962-A248-92E538ED997C} = {A447D0CB-601B-479E-A2B2-76E48F5D4D61} {DBAB1C82-A3A0-4ADC-95BC-B87557C61C42} = {9BF048D0-411D-4C2A-8C32-3A3255501D27} + {6BB43905-3DBD-47E4-A38F-2BE319300B15} = {9BF048D0-411D-4C2A-8C32-3A3255501D27} + {711B2905-FDC7-4D67-B40B-9DEFF042CB01} = {A447D0CB-601B-479E-A2B2-76E48F5D4D61} + {B233AB55-788C-48B6-9557-098B8D0DDBFF} = {A447D0CB-601B-479E-A2B2-76E48F5D4D61} + {ECF14067-8633-4DDA-8EAE-124989F8E09E} = {A447D0CB-601B-479E-A2B2-76E48F5D4D61} + {D835A0A8-C213-461F-8B41-6F2715DBEC43} = {9BF048D0-411D-4C2A-8C32-3A3255501D27} + {F2C0D619-8CAF-4F81-B681-3F75AF79661F} = {9BF048D0-411D-4C2A-8C32-3A3255501D27} + {57AF678A-3671-4B9E-9608-053E2197D0A4} = {9BF048D0-411D-4C2A-8C32-3A3255501D27} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7D279EE5-E38F-4125-AE82-6ADE52D72F26} diff --git a/src/libraries/Microsoft.Extensions.Diagnostics/src/Metrics/MetricsServiceExtensions.cs b/src/libraries/Microsoft.Extensions.Diagnostics/src/Metrics/MetricsServiceExtensions.cs index 79a08c78b82e7c..47fa1e0dee8193 100644 --- a/src/libraries/Microsoft.Extensions.Diagnostics/src/Metrics/MetricsServiceExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Diagnostics/src/Metrics/MetricsServiceExtensions.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Diagnostics.Metrics; using Microsoft.Extensions.Diagnostics.Metrics.Configuration; +using Microsoft.Extensions.Options; using System; using System.Diagnostics.Metrics; @@ -32,7 +33,9 @@ public static IServiceCollection AddMetrics(this IServiceCollection services) services.TryAddSingleton(); // Make sure the subscription manager is started when the host starts. // The host will trigger options validation. - services.AddOptions().Configure((_, manager) => manager.Initialize()).ValidateOnStart(); + services.AddOptions().ValidateOnStart(); + // Make sure this is only registered/run once. + services.TryAddSingleton, SubscriptionActivator>(); services.TryAddSingleton(); @@ -66,5 +69,10 @@ private sealed class MetricsBuilder(IServiceCollection services) : IMetricsBuild } private sealed class NoOpOptions { } + + private sealed class SubscriptionActivator(MetricsSubscriptionManager manager) : IConfigureOptions + { + public void Configure(NoOpOptions options) => manager.Initialize(); + } } } diff --git a/src/libraries/Microsoft.Extensions.Diagnostics/tests/MetricsSubscriptionManagerTests.cs b/src/libraries/Microsoft.Extensions.Diagnostics/tests/MetricsSubscriptionManagerTests.cs new file mode 100644 index 00000000000000..60049f6820e963 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Diagnostics/tests/MetricsSubscriptionManagerTests.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics.Metrics; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.Metrics; +using Microsoft.Extensions.Options; +using Xunit; + +namespace Microsoft.Extensions.Diagnostics.Tests +{ + public class MetricsSubscriptionManagerTests + { + [Fact] + public void AddMetrics_InitializesListeners() + { + var serviceCollection = new ServiceCollection(); + serviceCollection.AddMetrics(); // Duplicate call, should not add things twice. + serviceCollection.AddMetrics(l => l.AddListener()); + var serviceProvider = serviceCollection.BuildServiceProvider(); + + // Make sure the subscription manager is started. + serviceProvider.GetRequiredService().Validate(); + + var listeners = serviceProvider.GetRequiredService>(); + + var listener = Assert.Single(listeners); + var fakeListener = Assert.IsType(listener); + Assert.Equal(1, fakeListener.InitializeCount); + } + + private class FakeListener : IMetricsListener + { + public string Name => "Fake"; + public int InitializeCount { get; private set; } + public MeasurementHandlers GetMeasurementHandlers() => new MeasurementHandlers(); + public void Initialize(IObservableInstrumentsSource source) => InitializeCount++; + public bool InstrumentPublished(Instrument instrument, out object? userState) => throw new NotImplementedException(); + public void MeasurementsCompleted(Instrument instrument, object? userState) => throw new NotImplementedException(); + } + } +} From eb124c5b6c07f91f8f5eb846e1db235fe84030a6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 23 Aug 2023 14:44:09 -0700 Subject: [PATCH 066/783] [release/8.0] Fix Type.ContainsGenericParameters for function pointers (#90963) * Fix Type.ContainsGenericParameters for function pointers Fixes #84916 * Fix System.Reflection.MetadataLoadContext * Fix Mono * Update test --------- Co-authored-by: Jan Kotas --- src/coreclr/vm/typedesc.cpp | 40 +++++++++++++++++++ src/coreclr/vm/typedesc.h | 4 ++ src/coreclr/vm/typehandle.cpp | 24 ++--------- .../tests/System/FunctionPointerTests.cs | 19 +++++++++ .../Types/RoFunctionPointerType.cs | 18 ++++++++- .../src/System/RuntimeType.Mono.cs | 10 +++++ 6 files changed, 94 insertions(+), 21 deletions(-) diff --git a/src/coreclr/vm/typedesc.cpp b/src/coreclr/vm/typedesc.cpp index 6c3226882503c6..95e86ccc961691 100644 --- a/src/coreclr/vm/typedesc.cpp +++ b/src/coreclr/vm/typedesc.cpp @@ -104,6 +104,31 @@ BOOL TypeDesc::IsSharedByGenericInstantiations() return FALSE; } +BOOL TypeDesc::ContainsGenericVariables(BOOL methodOnly) +{ + if (IsGenericVariable()) + { + if (!methodOnly) + return TRUE; + + PTR_TypeVarTypeDesc pTyVar = dac_cast(this); + return TypeFromToken(pTyVar->GetTypeOrMethodDef()) == mdtMethodDef; + } + + if (HasTypeParam()) + { + return GetRootTypeParam().ContainsGenericVariables(methodOnly); + } + + if (IsFnPtr()) + { + return dac_cast(this)->ContainsGenericVariables(methodOnly); + } + + return FALSE; +} + + PTR_BaseDomain TypeDesc::GetDomain() { CONTRACTL @@ -1670,6 +1695,21 @@ FnPtrTypeDesc::IsSharedByGenericInstantiations() return FALSE; } // FnPtrTypeDesc::IsSharedByGenericInstantiations +BOOL +FnPtrTypeDesc::ContainsGenericVariables(BOOL methodOnly) +{ + LIMITED_METHOD_DAC_CONTRACT; + + for (DWORD i = 0; i <= m_NumArgs; i++) + { + if (m_RetAndArgTypes[i].ContainsGenericVariables(methodOnly)) + { + return TRUE; + } + } + return FALSE; +} // FnPtrTypeDesc::ContainsGenericVariables + #ifndef DACCESS_COMPILE // Returns TRUE if all return and argument types are externally visible. diff --git a/src/coreclr/vm/typedesc.h b/src/coreclr/vm/typedesc.h index 51614c3b110778..b86845c81e21c0 100644 --- a/src/coreclr/vm/typedesc.h +++ b/src/coreclr/vm/typedesc.h @@ -182,6 +182,8 @@ class TypeDesc BOOL IsSharedByGenericInstantiations(); + BOOL ContainsGenericVariables(BOOL methodOnly); + protected: // See methodtable.h for details of the flags with the same name there enum @@ -527,6 +529,8 @@ class FnPtrTypeDesc : public TypeDesc BOOL IsSharedByGenericInstantiations(); + BOOL ContainsGenericVariables(BOOL methodOnly); + #ifndef DACCESS_COMPILE // Returns TRUE if all return and argument types are externally visible. BOOL IsExternallyVisible() const; diff --git a/src/coreclr/vm/typehandle.cpp b/src/coreclr/vm/typehandle.cpp index 59eed8b5030d86..053cc759217c76 100644 --- a/src/coreclr/vm/typehandle.cpp +++ b/src/coreclr/vm/typehandle.cpp @@ -138,26 +138,10 @@ BOOL TypeHandle::ContainsGenericVariables(BOOL methodOnly /*=FALSE*/) const STATIC_CONTRACT_NOTHROW; SUPPORTS_DAC; - if (HasTypeParam()) - { - return GetTypeParam().ContainsGenericVariables(methodOnly); - } - - if (IsGenericVariable()) - { - if (!methodOnly) - return TRUE; - - PTR_TypeVarTypeDesc pTyVar = dac_cast(AsTypeDesc()); - return TypeFromToken(pTyVar->GetTypeOrMethodDef()) == mdtMethodDef; - } - else if (HasInstantiation()) - { - if (GetMethodTable()->ContainsGenericVariables(methodOnly)) - return TRUE; - } - - return FALSE; + if (IsTypeDesc()) + return AsTypeDesc()->ContainsGenericVariables(methodOnly); + else + return AsMethodTable()->ContainsGenericVariables(methodOnly); } //@GENERICS: diff --git a/src/libraries/Common/tests/System/FunctionPointerTests.cs b/src/libraries/Common/tests/System/FunctionPointerTests.cs index 925c8683f8f7f4..8a344e01e78955 100644 --- a/src/libraries/Common/tests/System/FunctionPointerTests.cs +++ b/src/libraries/Common/tests/System/FunctionPointerTests.cs @@ -173,6 +173,22 @@ public static unsafe void RequiredModifiers() Assert.Equal(typeof(Runtime.InteropServices.OutAttribute).Project(), parameters[1].GetRequiredCustomModifiers()[0]); } + [Fact] + public static unsafe void GenericFunctionPointer() + { + Type t = typeof(FunctionPointerHolder).Project(); + + MethodInfo m1 = t.GetMethod(nameof(FunctionPointerHolder.GenericReturnValue), Bindings); + Type fcnPtr1 = m1.ReturnType; + Assert.True(fcnPtr1.IsFunctionPointer); + Assert.True(fcnPtr1.ContainsGenericParameters); + + MethodInfo m2 = t.GetMethod(nameof(FunctionPointerHolder.GenericArgument), Bindings); + Type fcnPtr2 = m2.GetParameters()[1].ParameterType; + Assert.True(fcnPtr2.IsFunctionPointer); + Assert.True(fcnPtr2.ContainsGenericParameters); + } + [Theory] [InlineData(nameof(FunctionPointerHolder.MethodReturnValue1), "MethodReturnValue1()", @@ -278,6 +294,9 @@ private unsafe class FunctionPointerHolder public delegate* unmanaged[Stdcall, MemberFunction] SeveralArguments() => default; public delegate* RequiredModifiers() => default; + public delegate* GenericReturnValue() => default; + public bool GenericArgument(int x, delegate* fptr) => default; + public class MyClass { } public struct MyStruct { } } diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoFunctionPointerType.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoFunctionPointerType.cs index 73cd87437551f6..426ab7085d9fdd 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoFunctionPointerType.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoFunctionPointerType.cs @@ -147,7 +147,23 @@ public sealed override bool Equals([NotNullWhen(true)] object? obj) public sealed override bool IsGenericParameter => false; public sealed override bool IsGenericTypeParameter => false; public sealed override bool IsGenericMethodParameter => false; - public sealed override bool ContainsGenericParameters => IsGenericTypeDefinition; + + public sealed override bool ContainsGenericParameters + { + get + { + if (_returnType.ContainsGenericParameters) + return true; + + foreach (Type parameterType in _parameterTypes) + { + if (parameterType.ContainsGenericParameters) + return true; + } + + return false; + } + } protected sealed override TypeCode GetTypeCodeImpl() => TypeCode.Object; diff --git a/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs b/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs index e7feb145b18846..5924d5c0640df7 100644 --- a/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs @@ -2048,6 +2048,16 @@ public override bool ContainsGenericParameters if (HasElementType) return GetElementType().ContainsGenericParameters; + if (IsFunctionPointer) + { + if (GetFunctionPointerReturnType().ContainsGenericParameters) + return true; + + foreach (Type arg in GetFunctionPointerParameterTypes()) + if (arg.ContainsGenericParameters) + return true; + } + return false; } } From ac16ae11a6e1f613aa363656507e682222d156fd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 23 Aug 2023 14:53:41 -0700 Subject: [PATCH 067/783] [release/8.0] Support assignment to multiple refs in trim analyzer (#90936) * Support assignment to multiple refs * Add support for assigning to arrays * Fix tests for illink/nativeaot * Remove ref local test, add issue links --------- Co-authored-by: Sven Boemer --- .../DataFlow/CapturedReferenceValue.cs | 21 +-- .../DataFlow/LValueFlowCaptureProvider.cs | 28 +++- .../DataFlow/LocalDataFlowVisitor.cs | 131 +++++++++++---- .../DataFlow/LocalStateLattice.cs | 12 +- .../TrimAnalysis/TrimAnalysisVisitor.cs | 13 +- .../src/ILLink.Shared/DataFlow/ValueSet.cs | 2 + .../MethodWithUnmanagedConstraint.cs | 1 - .../DataFlow/ByRefDataflow.cs | 155 +++++++++++++++++- .../TestCasesRunner/TestCaseCompiler.cs | 3 - 9 files changed, 293 insertions(+), 73 deletions(-) diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/CapturedReferenceValue.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/CapturedReferenceValue.cs index d7033d9d799615..37e22e2228175c 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/CapturedReferenceValue.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/CapturedReferenceValue.cs @@ -10,7 +10,7 @@ namespace ILLink.RoslynAnalyzer.DataFlow { public readonly struct CapturedReferenceValue : IEquatable { - public readonly IOperation? Reference; + public readonly IOperation Reference; public CapturedReferenceValue (IOperation operation) { @@ -48,23 +48,4 @@ public override bool Equals (object obj) public override int GetHashCode () => Reference?.GetHashCode () ?? 0; } - - - public struct CapturedReferenceLattice : ILattice - { - public CapturedReferenceValue Top => default; - - public CapturedReferenceValue Meet (CapturedReferenceValue left, CapturedReferenceValue right) - { - if (left.Equals (right)) - return left; - if (left.Reference == null) - return right; - if (right.Reference == null) - return left; - // Both non-null and different shouldn't happen. - // We assume that a flow capture can capture only a single property. - throw new InvalidOperationException (); - } - } } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LValueFlowCaptureProvider.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LValueFlowCaptureProvider.cs index 610a4cfd44606c..446379586e5b29 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LValueFlowCaptureProvider.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LValueFlowCaptureProvider.cs @@ -1,7 +1,7 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -#nullable disable +#nullable enable using System.Collections.Generic; using System.Collections.Immutable; @@ -15,7 +15,7 @@ namespace ILLink.RoslynAnalyzer.DataFlow { - // Copied from https://github.com/dotnet/roslyn/blob/c8ebc8682889b395fcb84c85bf4ff54577377d26/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/FlowAnalysis/LValueFlowCaptureProvider.cs + // Adapted from https://github.com/dotnet/roslyn/blob/c8ebc8682889b395fcb84c85bf4ff54577377d26/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/FlowAnalysis/LValueFlowCaptureProvider.cs /// /// Helper class to detect s that are l-value captures. /// L-value captures are essentially captures of a symbol's location/address. @@ -38,6 +38,22 @@ namespace ILLink.RoslynAnalyzer.DataFlow /// internal static class LValueFlowCapturesProvider { + static bool IsLValueFlowCapture (IFlowCaptureReferenceOperation flowCaptureReference, out IAssignmentOperation? assignment) + { + assignment = flowCaptureReference.Parent as IAssignmentOperation; + if (assignment?.Target == flowCaptureReference) + return true; + + if (flowCaptureReference.Parent is IArrayElementReferenceOperation arrayAlementRef) { + assignment = arrayAlementRef.Parent as IAssignmentOperation; + if (assignment?.Target == arrayAlementRef) + return true; + } + + assignment = null; + return flowCaptureReference.IsInLeftOfDeconstructionAssignment (out _); + } + public static ImmutableDictionary CreateLValueFlowCaptures (ControlFlowGraph cfg) { // This method identifies flow capture reference operations that are target of an assignment @@ -47,15 +63,13 @@ public static ImmutableDictionary CreateLValueFlowCa // the flow graph. Specifically, for an ICoalesceOperation a flow capture acts // as both an r-value and l-value flow capture. - ImmutableDictionary.Builder lvalueFlowCaptureIdBuilder = null; + ImmutableDictionary.Builder? lvalueFlowCaptureIdBuilder = null; var rvalueFlowCaptureIds = new HashSet (); foreach (var flowCaptureReference in cfg.DescendantOperations (OperationKind.FlowCaptureReference)) { - if (flowCaptureReference.Parent is IAssignmentOperation assignment && - assignment.Target == flowCaptureReference || - flowCaptureReference.IsInLeftOfDeconstructionAssignment (out _)) { + if (IsLValueFlowCapture (flowCaptureReference, out IAssignmentOperation? assignment)) { lvalueFlowCaptureIdBuilder ??= ImmutableDictionary.CreateBuilder (); - var captureKind = flowCaptureReference.Parent.IsAnyCompoundAssignment () || rvalueFlowCaptureIds.Contains (flowCaptureReference.Id) + var captureKind = assignment?.IsAnyCompoundAssignment () == true || rvalueFlowCaptureIds.Contains (flowCaptureReference.Id) ? FlowCaptureKind.LValueAndRValueCapture : FlowCaptureKind.LValueCapture; lvalueFlowCaptureIdBuilder.Add (flowCaptureReference.Id, captureKind); diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs index 6143e03ab935da..80ce7a66f4d231 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs @@ -96,7 +96,7 @@ public void Transfer (BlockProxy block, LocalDataFlowState state) + void SetLocal (ILocalReferenceOperation operation, TValue value, LocalDataFlowState state, bool merge = false) { var local = new LocalKey (operation.Local); if (IsReferenceToCapturedVariable (operation)) @@ -149,27 +149,14 @@ void SetLocal (ILocalReferenceOperation operation, TValue value, LocalDataFlowSt if (InterproceduralState.TrySetHoistedLocal (local, value)) return; - state.Set (local, value); + var newValue = merge + ? state.Lattice.Lattice.ValueLattice.Meet (state.Get (local), value) + : value; + state.Set (local, newValue); } - public override TValue VisitSimpleAssignment (ISimpleAssignmentOperation operation, LocalDataFlowState state) + TValue ProcessSingleTargetAssignment (IOperation targetOperation, ISimpleAssignmentOperation operation, LocalDataFlowState state, bool merge) { - var targetOperation = operation.Target; - if (targetOperation is IFlowCaptureReferenceOperation flowCaptureReference) { - Debug.Assert (IsLValueFlowCapture (flowCaptureReference.Id)); - Debug.Assert (!flowCaptureReference.GetValueUsageInfo (Method).HasFlag (ValueUsageInfo.Read)); - var capturedReference = state.Current.CapturedReferences.Get (flowCaptureReference.Id).Reference; - targetOperation = capturedReference; - if (targetOperation == null) - throw new InvalidOperationException (); - - // Note: technically we should avoid visiting the target operation below when assigning to a flow capture reference, - // because this should be done when the capture is created. For example, a flow capture used as both an LValue and a RValue - // should only evaluate the expression that computes the object instance of a property reference once. - // However, we just visit the instance again below for simplicity. This could be generalized if we encounter a dataflow - // behavior where this makes a difference. - } - switch (targetOperation) { case IFieldReferenceOperation: case IParameterReferenceOperation: { @@ -237,17 +224,52 @@ public override TValue VisitSimpleAssignment (ISimpleAssignmentOperation operati // TODO: when setting a property in an attribute, target is an IPropertyReference. case ILocalReferenceOperation localRef: { TValue value = Visit (operation.Value, state); - SetLocal (localRef, value, state); + SetLocal (localRef, value, state, merge); return value; } case IArrayElementReferenceOperation arrayElementRef: { if (arrayElementRef.Indices.Length != 1) break; - TValue arrayRef = Visit (arrayElementRef.ArrayReference, state); - TValue index = Visit (arrayElementRef.Indices[0], state); - TValue value = Visit (operation.Value, state); - HandleArrayElementWrite (arrayRef, index, value, operation); + // Similarly to VisitSimpleAssignment, this needs to handle cases where the array reference + // is a captured variable, even if the target of the assignment (the array element reference) is not. + + TValue arrayRef; + TValue index; + TValue value; + if (arrayElementRef.ArrayReference is not IFlowCaptureReferenceOperation captureReference) { + arrayRef = Visit (arrayElementRef.ArrayReference, state); + index = Visit (arrayElementRef.Indices[0], state); + value = Visit (operation.Value, state); + HandleArrayElementWrite (arrayRef, index, value, operation, merge: merge); + return value; + } + + index = Visit (arrayElementRef.Indices[0], state); + value = Visit (operation.Value, state); + + var capturedReferences = state.Current.CapturedReferences.Get (captureReference.Id); + if (!capturedReferences.HasMultipleValues) { + // Single captured reference. Treat this as an overwriting assignment, + // unless the caller already told us to merge values because this is an + // assignment to one of multiple captured array element references. + var enumerator = capturedReferences.GetEnumerator (); + enumerator.MoveNext (); + var capture = enumerator.Current; + arrayRef = Visit (capture.Reference, state); + HandleArrayElementWrite (arrayRef, index, value, operation, merge: merge); + return value; + } + + // The capture id may have captured multiple references, as in: + // (b ? arr1 : arr2)[0] = value; + // We treat this as possible write to each of the captured references, + // which requires merging with the previous values of each. + + foreach (var capture in state.Current.CapturedReferences.Get (captureReference.Id)) { + arrayRef = Visit (capture.Reference, state); + HandleArrayElementWrite (arrayRef, index, value, operation, merge: true); + } return value; } case IDiscardOperation: @@ -293,8 +315,50 @@ public override TValue VisitSimpleAssignment (ISimpleAssignmentOperation operati return Visit (operation.Value, state); } - // Similar to VisitLocalReference - public override TValue VisitFlowCaptureReference (IFlowCaptureReferenceOperation operation, LocalDataFlowState state) + public override TValue VisitSimpleAssignment (ISimpleAssignmentOperation operation, LocalDataFlowState state) + { + var targetOperation = operation.Target; + if (targetOperation is not IFlowCaptureReferenceOperation flowCaptureReference) + return ProcessSingleTargetAssignment (targetOperation, operation, state, merge: false); + + // Note: technically we should avoid visiting the target operation in ProcessNonCapturedAssignment when assigning + // to a flow capture reference, because this should be done when the capture is created. + // For example, a flow capture used as both an LValue and a RValue should only evaluate the expression that + // computes the object instance of a property reference once. However, we just visit the instance again below + // for simplicity. This could be generalized if we encounter a dataflow behavior where this makes a difference. + + Debug.Assert (IsLValueFlowCapture (flowCaptureReference.Id)); + Debug.Assert (!flowCaptureReference.GetValueUsageInfo (Method).HasFlag (ValueUsageInfo.Read)); + var capturedReferences = state.Current.CapturedReferences.Get (flowCaptureReference.Id); + if (!capturedReferences.HasMultipleValues) { + // Single captured reference. Treat this as an overwriting assignment. + var enumerator = capturedReferences.GetEnumerator (); + enumerator.MoveNext (); + targetOperation = enumerator.Current.Reference; + return ProcessSingleTargetAssignment (targetOperation, operation, state, merge: false); + } + + // The capture id may have captured multiple references, as in: + // (b ? ref v1 : ref v2) = value; + // We treat this as a possible write to each of the captured references, + // which requires merging with the previous values of each. + + // Note: technically this should only visit the RHS of the assignment once. + // For now we visit the RHS in ProcessSingleTargetAssignment for simplicity, and + // rely on the warning deduplication to prevent this from producing multiple warnings + // if the RHS has dataflow warnings. + + TValue value = TopValue; + foreach (var capturedReference in capturedReferences) { + targetOperation = capturedReference.Reference; + var singleValue = ProcessSingleTargetAssignment (targetOperation, operation, state, merge: true); + value = LocalStateLattice.Lattice.ValueLattice.Meet (value, singleValue); + } + + return value; + } + + TValue GetFlowCaptureValue (IFlowCaptureReferenceOperation operation, LocalDataFlowState state) { if (!operation.GetValueUsageInfo (Method).HasFlag (ValueUsageInfo.Read)) { // There are known cases where this assert doesn't hold, because LValueFlowCaptureProvider @@ -304,10 +368,21 @@ public override TValue VisitFlowCaptureReference (IFlowCaptureReferenceOperation return TopValue; } - Debug.Assert (IsRValueFlowCapture (operation.Id)); + // This assert is incorrect for cases like (b ? arr1 : arr2)[0] = v; + // Here the ValueUsageInfo shows that the value usage is for reading (this is probably wrong!) + // but the value is actually an LValueFlowCapture. + // Let's just disable the assert for now. + // Debug.Assert (IsRValueFlowCapture (operation.Id)); + return state.Get (new LocalKey (operation.Id)); } + // Similar to VisitLocalReference + public override TValue VisitFlowCaptureReference (IFlowCaptureReferenceOperation operation, LocalDataFlowState state) + { + return GetFlowCaptureValue (operation, state); + } + // Similar to VisitSimpleAssignment when assigning to a local, but for values which are captured without a // corresponding local variable. The "flow capture" is like a local assignment, and the "flow capture reference" // is like a local reference. diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalStateLattice.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalStateLattice.cs index 6b5677df686a52..84270212ec5e5f 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalStateLattice.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalStateLattice.cs @@ -43,22 +43,22 @@ public struct LocalState : IEquatable> // Stores any operations which are captured by reference in a FlowCaptureOperation. // Only stores captures which are assigned through. Captures of the values of operations // are tracked as part of the dictionary of values, keyed by LocalKey. - public DefaultValueDictionary CapturedReferences; + public DefaultValueDictionary> CapturedReferences; public LocalState (TValue defaultValue) : this (new DefaultValueDictionary (defaultValue), - new DefaultValueDictionary (default (CapturedReferenceValue))) + new DefaultValueDictionary> (default (ValueSet))) { } - public LocalState (DefaultValueDictionary dictionary, DefaultValueDictionary capturedReferences) + public LocalState (DefaultValueDictionary dictionary, DefaultValueDictionary> capturedReferences) { Dictionary = dictionary; CapturedReferences = capturedReferences; } public LocalState (DefaultValueDictionary dictionary) - : this (dictionary, new DefaultValueDictionary (default (CapturedReferenceValue))) + : this (dictionary, new DefaultValueDictionary> (default (ValueSet))) { } @@ -83,12 +83,12 @@ public override int GetHashCode () where TValueLattice : ILattice { public readonly DictionaryLattice Lattice; - public readonly DictionaryLattice CapturedReferenceLattice; + public readonly DictionaryLattice, ValueSetLattice> CapturedReferenceLattice; public LocalStateLattice (TValueLattice valueLattice) { Lattice = new DictionaryLattice (valueLattice); - CapturedReferenceLattice = new DictionaryLattice (default (CapturedReferenceLattice)); + CapturedReferenceLattice = new DictionaryLattice, ValueSetLattice> (default (ValueSetLattice)); Top = new (Lattice.Top); } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs index dccf85a2c5b240..04c7b06fa048e6 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs @@ -219,7 +219,7 @@ public override MultiValue HandleArrayElementRead (MultiValue arrayValue, MultiV return result.Equals (TopValue) ? UnknownValue.Instance : result; } - public override void HandleArrayElementWrite (MultiValue arrayValue, MultiValue indexValue, MultiValue valueToWrite, IOperation operation) + public override void HandleArrayElementWrite (MultiValue arrayValue, MultiValue indexValue, MultiValue valueToWrite, IOperation operation, bool merge) { int? index = indexValue.AsConstInt (); foreach (var arraySingleValue in arrayValue) { @@ -227,12 +227,11 @@ public override void HandleArrayElementWrite (MultiValue arrayValue, MultiValue if (index == null) { // Reset the array to all unknowns - since we don't know which index is being assigned arr.IndexValues.Clear (); - } else { - if (arr.IndexValues.TryGetValue (index.Value, out _)) { - arr.IndexValues[index.Value] = ArrayValue.SanitizeArrayElementValue(valueToWrite); - } else if (arr.IndexValues.Count < MaxTrackedArrayValues) { - arr.IndexValues[index.Value] = ArrayValue.SanitizeArrayElementValue(valueToWrite); - } + } else if (arr.IndexValues.TryGetValue (index.Value, out _) || arr.IndexValues.Count < MaxTrackedArrayValues) { + var sanitizedValue = ArrayValue.SanitizeArrayElementValue(valueToWrite); + arr.IndexValues[index.Value] = merge + ? _multiValueLattice.Meet (arr.IndexValues[index.Value], sanitizedValue) + : sanitizedValue; } } } diff --git a/src/tools/illink/src/ILLink.Shared/DataFlow/ValueSet.cs b/src/tools/illink/src/ILLink.Shared/DataFlow/ValueSet.cs index 2fb1fc3f21746e..d538d358e8cea3 100644 --- a/src/tools/illink/src/ILLink.Shared/DataFlow/ValueSet.cs +++ b/src/tools/illink/src/ILLink.Shared/DataFlow/ValueSet.cs @@ -132,6 +132,8 @@ public void Reset () public static implicit operator ValueSet (TValue value) => new (value); + public bool HasMultipleValues => _values is EnumerableValues; + public override bool Equals (object? obj) => obj is ValueSet other && Equals (other); public bool Equals (ValueSet other) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/MethodWithUnmanagedConstraint.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/MethodWithUnmanagedConstraint.cs index e2d3e86fb6679d..713ed17db49d54 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/MethodWithUnmanagedConstraint.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/MethodWithUnmanagedConstraint.cs @@ -4,7 +4,6 @@ namespace Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed { [SetupCSharpCompilerToUse ("csc")] - [SetupCompileArgument ("/langversion:7.3")] [SetupLinkerArgument ("--used-attrs-only", "true")] public class MethodWithUnmanagedConstraint { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs index b7c71da382b731..8348f5d6e68fbd 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs @@ -5,10 +5,10 @@ using System.Diagnostics.CodeAnalysis; using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Cases.Expectations.Metadata; +using Mono.Linker.Tests.Cases.Expectations.Helpers; namespace Mono.Linker.Tests.Cases.DataFlow { - [SetupCompileArgument ("/langversion:7.3")] [SetupCompileArgument ("/unsafe")] [Kept] [ExpectedNoWarnings] @@ -35,6 +35,7 @@ public static void Main () PointerDereference.Test (); MultipleOutRefsToField.Test (); + MultipleRefCaptures.Test (); } [Kept] @@ -187,5 +188,157 @@ public static void Test () TwoOutRefs (out _publicMethodsField, out _publicPropertiesField); } } + + [Kept] + class MultipleRefCaptures + { + [Kept] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + static Type _publicMethodsField; + + [Kept] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] + static Type _publicPropertiesField; + + static Type Prop { get; set; } + + [Kept] + [ExpectedWarning ("IL2074", nameof (_publicMethodsField), nameof (GetUnknownType))] + [ExpectedWarning ("IL2074", nameof (_publicPropertiesField), nameof (GetUnknownType))] + static void TestFieldAssignment (bool b = true) + { + (b ? ref _publicMethodsField : ref _publicPropertiesField) = GetUnknownType (); + } + + [Kept] + [ExpectedWarning ("IL2072", nameof (publicMethodsParameter), nameof (GetUnknownType))] + [ExpectedWarning ("IL2072", nameof (publicPropertiesParameter), nameof (GetUnknownType))] + static void TestParameterAssignment ( + bool b = true, + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + Type publicMethodsParameter = null, + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] + Type publicPropertiesParameter = null) + { + (b ? ref publicMethodsParameter : ref publicPropertiesParameter) = GetUnknownType (); + } + + [Kept] + [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll))] + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicFields), nameof (DataFlowTypeExtensions.RequiresAll))] + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), nameof (DataFlowTypeExtensions.RequiresAll))] + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestLocalAssignment (bool b = true) + { + var local1 = GetUnknownType (); + var local2 = GetTypeWithPublicFields (); + (b ? ref local1 : ref local2) = GetTypeWithPublicConstructors (); + local1.RequiresAll (); + local2.RequiresAll (); + } + + [Kept] + [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicFields), nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicFields), nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] + // ILLink/ILCompiler produce different warning code: https://github.com/dotnet/linker/issues/2737 + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + static void TestArrayElementReferenceAssignment (bool b = true) + { + var arr1 = new Type[] { GetUnknownType () }; + var arr2 = new Type[] { GetTypeWithPublicConstructors () }; + (b ? ref arr1[0] : ref arr2[0]) = GetTypeWithPublicFields (); + arr1[0].RequiresAll (); + arr2[0].RequiresAll (); + } + + [Kept] + [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll))] + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), nameof (DataFlowTypeExtensions.RequiresAll))] + // ILLink/ILCompiler analysis hole: https://github.com/dotnet/runtime/issues/90335 + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicFields), nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicFields), nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] + static void TestArrayElementAssignment (bool b = true) + { + var arr1 = new Type[] { GetUnknownType () }; + var arr2 = new Type[] { GetTypeWithPublicConstructors () }; + (b ? arr1 : arr2)[0] = GetTypeWithPublicFields (); + arr1[0].RequiresAll (); + arr2[0].RequiresAll (); + } + + [Kept] + [ExpectedWarning ("IL2074", nameof (_publicMethodsField), nameof (GetUnknownType))] + [ExpectedWarning ("IL2074", nameof (_publicPropertiesField), nameof (GetUnknownType))] + static void TestNullCoalescingAssignment (bool b = true) + { + (b ? ref _publicMethodsField : ref _publicPropertiesField) ??= GetUnknownType (); + } + + [Kept] + [ExpectedWarning ("IL2074", nameof (_publicMethodsField), nameof (GetUnknownType))] + [ExpectedWarning ("IL2074", nameof (_publicMethodsField), nameof (GetTypeWithPublicConstructors))] + [ExpectedWarning ("IL2074", nameof (_publicPropertiesField), nameof (GetUnknownType))] + [ExpectedWarning ("IL2074", nameof (_publicPropertiesField), nameof (GetTypeWithPublicConstructors))] + static void TestNullCoalescingAssignmentComplex (bool b = true) + { + (b ? ref _publicMethodsField : ref _publicPropertiesField) ??= GetUnknownType () ?? GetTypeWithPublicConstructors (); + } + + [Kept] + [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DynamicallyAccessedMemberTypes.PublicConstructors), nameof (type))] + [ExpectedWarning ("IL2074", nameof (_publicMethodsField), nameof (GetUnknownType))] + [ExpectedWarning ("IL2074", nameof (_publicPropertiesField), nameof (GetUnknownType))] + static void TestDataFlowOnRightHandOfAssignment ( + bool b = true, + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type type = null) + { + (b ? ref _publicMethodsField : ref _publicPropertiesField) = (type = GetUnknownType ()); + } + + [Kept] + [ExpectedWarning ("IL2074", nameof (_publicMethodsField), nameof (GetUnknownType))] + [ExpectedWarning ("IL2074", nameof (_publicPropertiesField), nameof (GetUnknownType))] + [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestReturnValue (bool b = true) + { + var value = (b ? ref _publicMethodsField : ref _publicPropertiesField) = GetUnknownType (); + value.RequiresAll (); + } + + [Kept] + public static void Test () + { + TestFieldAssignment (); + TestParameterAssignment (); + TestLocalAssignment (); + TestArrayElementReferenceAssignment (); + TestArrayElementAssignment (); + TestNullCoalescingAssignment (); + TestNullCoalescingAssignmentComplex (); + TestDataFlowOnRightHandOfAssignment (); + TestReturnValue (); + } + } + + [Kept] + static Type GetUnknownType () => null; + + [Kept] + [return: KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] + static Type GetTypeWithPublicConstructors () => null; + + [Kept] + [return: KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + static Type GetTypeWithPublicFields () => null; } } diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs index aba20b96f3b157..ec427ebdbc4858 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs @@ -267,9 +267,6 @@ protected virtual NPath CompileCSharpAssemblyWithRoslyn (CompilerOptions options emitPdb = true; debugType = DebugInformationFormat.Embedded; break; - case "/langversion:7.3": - languageVersion = LanguageVersion.CSharp7_3; - break; default: var splitIndex = option.IndexOf (":"); if (splitIndex != -1 && option[..splitIndex] == "/main") { From 303f1d3908c9dace1ee0d4a23682730ab51c7678 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 23 Aug 2023 16:03:15 -0700 Subject: [PATCH 068/783] Fix --make-repro-path option (#90989) Co-authored-by: Ivan Povazan Co-authored-by: Jan Kotas --- src/coreclr/tools/Common/CommandLineHelpers.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/coreclr/tools/Common/CommandLineHelpers.cs b/src/coreclr/tools/Common/CommandLineHelpers.cs index 205592c1c91dca..3fb977a3047a6a 100644 --- a/src/coreclr/tools/Common/CommandLineHelpers.cs +++ b/src/coreclr/tools/Common/CommandLineHelpers.cs @@ -210,7 +210,7 @@ public static void MakeReproPackage(string makeReproPath, string outputFilePath, foreach (CliOption option in res.CommandResult.Command.Options) { OptionResult optionResult = res.GetResult(option); - if (optionResult is null || option.Name == "make-repro-path") + if (optionResult is null || option.Name == "--make-repro-path") { continue; } @@ -233,7 +233,7 @@ public static void MakeReproPackage(string makeReproPath, string outputFilePath, } foreach (string inputFile in dictionary.Values) { - rspFile.Add($"--{option.Name}:{ConvertFromOriginalPathToReproPackagePath(input: true, inputFile)}"); + rspFile.Add($"{option.Name}:{ConvertFromOriginalPathToReproPackagePath(input: true, inputFile)}"); } } else @@ -241,7 +241,7 @@ public static void MakeReproPackage(string makeReproPath, string outputFilePath, foreach (string optInList in values) { if (!string.IsNullOrEmpty(optInList)) - rspFile.Add($"--{option.Name}:{optInList}"); + rspFile.Add($"{option.Name}:{optInList}"); } } } @@ -254,11 +254,11 @@ public static void MakeReproPackage(string makeReproPath, string outputFilePath, // if output option is used, overwrite the path to the repro package stringVal = ConvertFromOriginalPathToReproPackagePath(input: false, stringVal); } - rspFile.Add($"--{option.Name}:{stringVal}"); + rspFile.Add($"{option.Name}:{stringVal}"); } else { - rspFile.Add($"--{option.Name}:{val}"); + rspFile.Add($"{option.Name}:{val}"); } } } From 09e32660cd775f57b375826178b9f6d2fa3338a7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 23 Aug 2023 16:03:49 -0700 Subject: [PATCH 069/783] [release/8.0] [mono][interp] Mask all shift amounts (#90991) * [tests] Enable tests * [mono][interp] Mask all shift amounts --------- Co-authored-by: Vlad Brezae --- src/mono/mono/mini/interp/interp-simd.c | 18 +++++++++--------- .../VectorImmBinaryOperatorTest.template | 1 - 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/mono/mono/mini/interp/interp-simd.c b/src/mono/mono/mini/interp/interp-simd.c index 5031c87aaf206b..f21fdec5aefd3b 100644 --- a/src/mono/mono/mini/interp/interp-simd.c +++ b/src/mono/mono/mini/interp/interp-simd.c @@ -215,57 +215,57 @@ interp_v128_i2_op_left_shift (gpointer res, gpointer v1, gpointer s1) static void interp_v128_i4_op_left_shift (gpointer res, gpointer v1, gpointer s1) { - *(v128_i4*)res = *(v128_i4*)v1 << *(gint32*)s1; + *(v128_i4*)res = *(v128_i4*)v1 << (*(gint32*)s1 & 31); } static void interp_v128_i8_op_left_shift (gpointer res, gpointer v1, gpointer s1) { - *(v128_i8*)res = *(v128_i8*)v1 << *(gint32*)s1; + *(v128_i8*)res = *(v128_i8*)v1 << (*(gint32*)s1 & 63); } // op_RightShift static void interp_v128_i1_op_right_shift (gpointer res, gpointer v1, gpointer s1) { - *(v128_i1*)res = *(v128_i1*)v1 >> *(gint32*)s1; + *(v128_i1*)res = *(v128_i1*)v1 >> (*(gint32*)s1 & 7); } static void interp_v128_i2_op_right_shift (gpointer res, gpointer v1, gpointer s1) { - *(v128_i2*)res = *(v128_i2*)v1 >> *(gint32*)s1; + *(v128_i2*)res = *(v128_i2*)v1 >> (*(gint32*)s1 & 15); } static void interp_v128_i4_op_right_shift (gpointer res, gpointer v1, gpointer s1) { - *(v128_i4*)res = *(v128_i4*)v1 >> *(gint32*)s1; + *(v128_i4*)res = *(v128_i4*)v1 >> (*(gint32*)s1 & 31); } // op_UnsignedRightShift static void interp_v128_i1_op_uright_shift (gpointer res, gpointer v1, gpointer s1) { - *(v128_u1*)res = *(v128_u1*)v1 >> *(gint32*)s1; + *(v128_u1*)res = *(v128_u1*)v1 >> (*(gint32*)s1 & 7); } static void interp_v128_i2_op_uright_shift (gpointer res, gpointer v1, gpointer s1) { - *(v128_u2*)res = *(v128_u2*)v1 >> *(gint32*)s1; + *(v128_u2*)res = *(v128_u2*)v1 >> (*(gint32*)s1 & 15); } static void interp_v128_i4_op_uright_shift (gpointer res, gpointer v1, gpointer s1) { - *(v128_u4*)res = *(v128_u4*)v1 >> *(gint32*)s1; + *(v128_u4*)res = *(v128_u4*)v1 >> (*(gint32*)s1 & 31); } static void interp_v128_i8_op_uright_shift (gpointer res, gpointer v1, gpointer s1) { - *(v128_u8*)res = *(v128_u8*)v1 >> *(gint32*)s1; + *(v128_u8*)res = *(v128_u8*)v1 >> (*(gint32*)s1 & 63); } // op_OnesComplement diff --git a/src/tests/JIT/HardwareIntrinsics/General/Shared/VectorImmBinaryOperatorTest.template b/src/tests/JIT/HardwareIntrinsics/General/Shared/VectorImmBinaryOperatorTest.template index ff62ffcfc91335..d9b2108472675b 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Shared/VectorImmBinaryOperatorTest.template +++ b/src/tests/JIT/HardwareIntrinsics/General/Shared/VectorImmBinaryOperatorTest.template @@ -19,7 +19,6 @@ namespace JIT.HardwareIntrinsics.General public static partial class Program { [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/89938", TestRuntimes.Mono)] public static void {Method}{RetBaseType}{Imm}() { var test = new VectorImmBinaryOpTest__{Method}{RetBaseType}{Imm}(); From 3d1b2543593f0dc3fbbdc2b8cad9b1f8e7554af6 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Wed, 23 Aug 2023 16:05:56 -0700 Subject: [PATCH 070/783] Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2251098 (#90996) * Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2250829 * Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2250829 --- .../gen/Resources/xlf/Strings.cs.xlf | 60 +++++++++---------- .../gen/Resources/xlf/Strings.de.xlf | 60 +++++++++---------- .../gen/Resources/xlf/Strings.es.xlf | 60 +++++++++---------- .../gen/Resources/xlf/Strings.fr.xlf | 60 +++++++++---------- .../gen/Resources/xlf/Strings.it.xlf | 60 +++++++++---------- .../gen/Resources/xlf/Strings.ja.xlf | 60 +++++++++---------- .../gen/Resources/xlf/Strings.ko.xlf | 60 +++++++++---------- .../gen/Resources/xlf/Strings.pl.xlf | 60 +++++++++---------- .../gen/Resources/xlf/Strings.pt-BR.xlf | 60 +++++++++---------- .../gen/Resources/xlf/Strings.ru.xlf | 60 +++++++++---------- .../gen/Resources/xlf/Strings.tr.xlf | 60 +++++++++---------- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 60 +++++++++---------- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 60 +++++++++---------- .../gen/Common/Resources/xlf/Strings.cs.xlf | 6 +- .../gen/Common/Resources/xlf/Strings.de.xlf | 6 +- .../gen/Common/Resources/xlf/Strings.es.xlf | 6 +- .../gen/Common/Resources/xlf/Strings.fr.xlf | 4 +- .../gen/Common/Resources/xlf/Strings.it.xlf | 4 +- .../gen/Common/Resources/xlf/Strings.ja.xlf | 6 +- .../gen/Common/Resources/xlf/Strings.ko.xlf | 6 +- .../gen/Common/Resources/xlf/Strings.pl.xlf | 4 +- .../Common/Resources/xlf/Strings.pt-BR.xlf | 6 +- .../gen/Common/Resources/xlf/Strings.ru.xlf | 4 +- .../gen/Common/Resources/xlf/Strings.tr.xlf | 4 +- .../Common/Resources/xlf/Strings.zh-Hans.xlf | 6 +- .../Common/Resources/xlf/Strings.zh-Hant.xlf | 4 +- .../gen/Resources/xlf/Strings.cs.xlf | 2 +- .../gen/Resources/xlf/Strings.de.xlf | 2 +- .../gen/Resources/xlf/Strings.es.xlf | 2 +- .../gen/Resources/xlf/Strings.fr.xlf | 2 +- .../gen/Resources/xlf/Strings.it.xlf | 2 +- .../gen/Resources/xlf/Strings.ja.xlf | 2 +- .../gen/Resources/xlf/Strings.ko.xlf | 2 +- .../gen/Resources/xlf/Strings.pl.xlf | 2 +- .../gen/Resources/xlf/Strings.pt-BR.xlf | 2 +- .../gen/Resources/xlf/Strings.ru.xlf | 2 +- .../gen/Resources/xlf/Strings.tr.xlf | 2 +- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 2 +- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 2 +- 39 files changed, 436 insertions(+), 436 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf index 7054599d224576..cf1eaeedf07021 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf @@ -4,122 +4,122 @@ Type {0} already implements the Validate method. - Type {0} already implements the Validate method. + Typ {0} již implementuje metodu Validate. A type already includes an implementation of the 'Validate' method. - A type already includes an implementation of the 'Validate' method. + Typ už obsahuje implementaci metody Validate. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] cannot be applied to static class {0}. + [OptionsValidator] nelze použít pro statickou třídu {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' can't be applied to a static class. + OptionsValidatorAttribute nelze použít pro statickou třídu. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. + U polí nebo vlastností s otevřeným obecným typem {0} nelze použít [ValidateObjectMembers] nebo [ValidateEnumeratedItems]. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. + U polí nebo vlastností s otevřenými obecnými typy nelze použít ValidateObjectMembersAttribute nebo ValidateEnumeratedItemsAttribute. Can't apply validation attributes to constant or static member {0}. - Can't apply validation attributes to constant or static member {0}. + Atributy ověřování nelze použít u konstantního ani statického člena {0}. Can't validate constants, static fields or properties. - Can't validate constants, static fields or properties. + Nelze ověřit konstanty, statická pole ani vlastnosti. There is a circular type reference involving type {0} preventing it from being used for static validation. - There is a circular type reference involving type {0} preventing it from being used for static validation. + Existuje cyklický odkaz obsahující typ {0}, který brání jeho použití pro statické ověření. Unsupported circular references in model types. - Unsupported circular references in model types. + Nepodporované cyklické odkazy v typech modelů. Type {0} does not implement the required IValidateOptions<{1}> interface. - Type {0} does not implement the required IValidateOptions<{1}> interface. + Typ {0} neimplementuje požadované rozhraní IValidateOptions<{1}> . A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. + Typ anotovaný třídou OptionsValidatorAttribute neimplementuje nezbytné rozhraní. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Ověřovací atribut „{0}“ u člena „{1}“ není přístupný z typu validátoru „{2}“. Validation attribute on the member is inaccessible from the validator type.. - Validation attribute on the member is inaccessible from the validator type.. + Ověřovací atribut u člena není přístupný z typu validátoru. Can't apply validation attributes to private field or property {0}. - Can't apply validation attributes to private field or property {0}. + Ověřovací atributy nelze použít u privátního pole nebo vlastnosti {0}. Can't validate private fields or properties. - Can't validate private fields or properties. + Nelze ověřit privátní pole nebo vlastnosti. Type {0} has no fields or properties to validate, referenced from member {1}. - Type {0} has no fields or properties to validate, referenced from member {1}. + Typ {0} nemá žádná pole ani vlastnosti k ověření, na které odkazuje člen {1}. A member type has no fields or properties to validate. - A member type has no fields or properties to validate. + Typ člena nemá žádná pole ani vlastnosti k ověření. Type {0} has no fields or properties to validate, referenced by type {1}. - Type {0} has no fields or properties to validate, referenced by type {1}. + Typ {0} nemá žádná pole ani vlastnosti k ověření, na které odkazuje typ {1}. A type has no fields or properties to validate. - A type has no fields or properties to validate. + Typ nemá žádná pole ani vlastnosti k ověření. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. + [ValidateEnumeratedItems] nelze použít u členů typu {0}, protože neimplementuje rozhraní IEnumerable<T>. Member type is not enumerable. - Member type is not enumerable. + Typ členu není výčtový. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. + Typ validátoru s hodnotou null zadaný v atributech [ValidateObjectMembers] nebo [ValidateEnumeratedItems]. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + Pro atributy ValidateObjectMembersAttribute nebo ValidateEnumeratedItemsAttribute byl specifikovaný typ validátoru s hodnotou null. @@ -134,32 +134,32 @@ Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. + Typ {0} obsahuje validační anotace, ale člen {1} neurčuje [ValidateEnumeratedItems], což může být přehlédnutí. Member potentially missing enumerable validation. - Member potentially missing enumerable validation. + U člena potenciálně chybí ověření výčtu. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. + Typ {0} obsahuje validační anotace, ale člen {1} neurčuje [ValidateObjectMembers], což může být přehlédnutí. Member potentially missing transitive validation. - Member potentially missing transitive validation. + U člena potenciálně chybí přenositelné ověření. Validator type {0} doesn't have a parameterless constructor. - Validator type {0} doesn't have a parameterless constructor. + Typ validátoru {0} nemá konstruktor bez parametrů. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validators used for transitive or enumerable validation must have a constructor with no parameters. + Validátory používané pro přenositelné nebo výčtové ověřování musí mít konstruktor bez parametrů. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf index 5f6febba85c205..507e5896457a51 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf @@ -4,122 +4,122 @@ Type {0} already implements the Validate method. - Type {0} already implements the Validate method. + Der Typ "{0}" implementiert bereits die Validate-Methode. A type already includes an implementation of the 'Validate' method. - A type already includes an implementation of the 'Validate' method. + Ein Typ enthält bereits eine Implementierung der Validate-Methode. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] cannot be applied to static class {0}. + [OptionsValidator] kann nicht auf die statische Klasse "{0}" angewendet werden. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' can't be applied to a static class. + "OptionsValidatorAttribute" kann nicht auf eine statische Klasse angewendet werden. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. + "ValidateObjectMembers" oder "ValidateEnumeratedItems" kann nicht für Felder oder Eigenschaften mit offenem generischen Typ {0} verwendet werden. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. + "ValidateObjectMembersAttribute" oder "ValidateEnumeratedItemsAttribute" kann nicht für Felder oder Eigenschaften mit offenen generischen Typen verwendet werden. Can't apply validation attributes to constant or static member {0}. - Can't apply validation attributes to constant or static member {0}. + Validierungsattribute können nicht auf konstanten oder statischen Member {0} angewendet werden. Can't validate constants, static fields or properties. - Can't validate constants, static fields or properties. + Konstanten, statische Felder oder Eigenschaften können nicht überprüft werden. There is a circular type reference involving type {0} preventing it from being used for static validation. - There is a circular type reference involving type {0} preventing it from being used for static validation. + Es gibt einen Zirkelverweis, der den Typ "{0}" verhindert, dass er für die statische Validierung verwendet wird. Unsupported circular references in model types. - Unsupported circular references in model types. + Nicht unterstützte Zirkelverweise in Modelltypen. Type {0} does not implement the required IValidateOptions<{1}> interface. - Type {0} does not implement the required IValidateOptions<{1}> interface. + Der Typ "{0}" implementiert nicht die erforderliche IValidateOptions<{1}>-Schnittstelle. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. + Ein mit "OptionsValidatorAttribute" versehener Typ implementiert nicht die erforderliche Schnittstelle. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Auf das Validierungsattribut "{0}" für den Member "{1}" kann vom Validierungssteuerelementtyp "{2}" nicht zugegriffen werden. Validation attribute on the member is inaccessible from the validator type.. - Validation attribute on the member is inaccessible from the validator type.. + Auf das Validierungsattribut für den Member kann vom Validierungssteuerelementtyp nicht zugegriffen werden. Can't apply validation attributes to private field or property {0}. - Can't apply validation attributes to private field or property {0}. + Validierungsattribute können nicht auf private Felder oder Eigenschaften {0} angewendet werden. Can't validate private fields or properties. - Can't validate private fields or properties. + Private Felder oder Eigenschaften können nicht überprüft werden. Type {0} has no fields or properties to validate, referenced from member {1}. - Type {0} has no fields or properties to validate, referenced from member {1}. + Der Typ "{0}" weist keine zu überprüfenden Felder oder Eigenschaften auf, auf die von Member "{1}" verwiesen wird. A member type has no fields or properties to validate. - A member type has no fields or properties to validate. + Ein Membertyp weist keine zu überprüfenden Felder oder Eigenschaften auf. Type {0} has no fields or properties to validate, referenced by type {1}. - Type {0} has no fields or properties to validate, referenced by type {1}. + Der Typ "{0}" weist keine zu überprüfenden Felder oder Eigenschaften auf, auf die vom Typ "{1}" verwiesen wird. A type has no fields or properties to validate. - A type has no fields or properties to validate. + Ein Typ weist keine zu überprüfenden Felder oder Eigenschaften auf. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. + [ValidateEnumeratedItems] kann nicht für Member vom Typ "{0}" verwendet werden, da es IEnumerable<T> nicht implementiert. Member type is not enumerable. - Member type is not enumerable. + Der Membertyp ist nicht aufzählbar. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. + Der in den Attributen [ValidateObjectMembers] oder [ValidateEnumeratedItems] angegebene NULL-Validierungssteuerelementtyp. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + Für die Attribute "ValidateObjectMembersAttribute" oder "ValidateEnumeratedItemsAttribute" wurde ein NULL-Validierungssteuerelementtyp angegeben. @@ -134,32 +134,32 @@ Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. + Der Typ "{0}" weist Validierungsanmerkungen auf, der Member "{1}" gibt jedoch keine [ValidateEnumeratedItems] an, die eine Vorhersage darstellen könnten. Member potentially missing enumerable validation. - Member potentially missing enumerable validation. + Dem Mitglied fehlt möglicherweise eine aufzählbare Validierung. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. + Der Typ "{0}" weist Validierungsanmerkungen auf, aber Member "{1}" gibt [ValidateObjectMembers] nicht an, was ein Versehen sein könnte. Member potentially missing transitive validation. - Member potentially missing transitive validation. + Dem Member fehlt möglicherweise die transitive Validierung. Validator type {0} doesn't have a parameterless constructor. - Validator type {0} doesn't have a parameterless constructor. + Der Validierungssteuerelementtyp "{0}" hat keinen parameterlosen Konstruktor. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validators used for transitive or enumerable validation must have a constructor with no parameters. + Validierungssteuerelemente, die für die transitive oder enumerierbare Validierung verwendet werden, müssen über einen Konstruktor ohne Parameter verfügen. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf index 84c12b9739ab1a..4ee57aa7312aa0 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf @@ -4,122 +4,122 @@ Type {0} already implements the Validate method. - Type {0} already implements the Validate method. + El tipo {0} ya implementa el método Validate. A type already includes an implementation of the 'Validate' method. - A type already includes an implementation of the 'Validate' method. + Un tipo ya incluye una implementación del método “Validate”. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] cannot be applied to static class {0}. + No se puede aplicar [OptionsValidator] a la clase estática {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' can't be applied to a static class. + “OptionsValidatorAttribute” no se puede aplicar a una clase estática. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. + No se puede usar [ValidateObjectMembers] ni [ValidateEnumeratedItems] en campos o propiedades con tipos genéricos abiertos {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. + No se puede usar “ValidateObjectMembersAttribute” o “ValidateEnumeratedItemsAttribute” en campos o propiedades con tipos genéricos abiertos. Can't apply validation attributes to constant or static member {0}. - Can't apply validation attributes to constant or static member {0}. + No se pueden aplicar atributos de validación a un miembro {0}constante o estático. Can't validate constants, static fields or properties. - Can't validate constants, static fields or properties. + No se pueden validar constantes, campos estáticos ni propiedades. There is a circular type reference involving type {0} preventing it from being used for static validation. - There is a circular type reference involving type {0} preventing it from being used for static validation. + Hay una referencia de tipo circular que implica al tipo {0} que impide que se use para la validación estática. Unsupported circular references in model types. - Unsupported circular references in model types. + Referencias circulares no admitidas en los tipos de modelo. Type {0} does not implement the required IValidateOptions<{1}> interface. - Type {0} does not implement the required IValidateOptions<{1}> interface. + El tipo {0} no implementa la interfaz IValidateOptions<{1}> necesaria. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. + Un tipo anotado con “OptionsValidatorAttribute” no implementa la interfaz necesaria. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + No se puede obtener acceso al atributo de validación '{0}' en el miembro '{1}' desde el tipo de validador '{2}'. Validation attribute on the member is inaccessible from the validator type.. - Validation attribute on the member is inaccessible from the validator type.. + No se puede obtener acceso al atributo de validación en el miembro desde el tipo de validador. Can't apply validation attributes to private field or property {0}. - Can't apply validation attributes to private field or property {0}. + No se pueden aplicar atributos de validación a la propiedad o campo privado {0}. Can't validate private fields or properties. - Can't validate private fields or properties. + No se pueden validar los campos o propiedades privadas. Type {0} has no fields or properties to validate, referenced from member {1}. - Type {0} has no fields or properties to validate, referenced from member {1}. + El tipo {0} no tiene campos ni propiedades para validar, al que hace referencia el tipo {1}. A member type has no fields or properties to validate. - A member type has no fields or properties to validate. + Un tipo de miembro no tiene campos ni propiedades para validar. Type {0} has no fields or properties to validate, referenced by type {1}. - Type {0} has no fields or properties to validate, referenced by type {1}. + El tipo {0} no tiene campos ni propiedades para validar, al que hace referencia el tipo {1}. A type has no fields or properties to validate. - A type has no fields or properties to validate. + Un tipo no tiene campos ni propiedades para validar. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. + [ValidateEnumeratedItems] no se puede usar en miembros de tipo {0} porque no implementa IEnumerable<T>. Member type is not enumerable. - Member type is not enumerable. + El tipo de miembro no es enumerable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. + Se especificó un tipo de validador nulo en los atributos [ValidateObjectMembers] o [ValidateEnumeratedItems]. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + Se especificó un tipo de validador nulo para los atributos “ValidateObjectMembersAttribute” o “ValidateEnumeratedItemsAttribute”. @@ -134,32 +134,32 @@ Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. + El tipo {0} tiene anotaciones de validación, pero el miembro {1} no especifica [ValidateEnumeratedItems], lo que podría ser un error. Member potentially missing enumerable validation. - Member potentially missing enumerable validation. + Posiblemente falta la validación enumerable en el miembro. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. + El tipo {0} tiene anotaciones de validación, pero el miembro {1} no especifica [ValidateObjectMembers], lo que podría ser un error. Member potentially missing transitive validation. - Member potentially missing transitive validation. + Posiblemente falta la validación transitiva en el miembro. Validator type {0} doesn't have a parameterless constructor. - Validator type {0} doesn't have a parameterless constructor. + El tipo de validador {0} no tiene un constructor sin parámetros. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validators used for transitive or enumerable validation must have a constructor with no parameters. + Los validadores usados para la validación transitiva o enumerable deben tener un constructor sin parámetros. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf index 58a27f1e4b33cb..9e300eaed00812 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf @@ -4,122 +4,122 @@ Type {0} already implements the Validate method. - Type {0} already implements the Validate method. + Le type {0} implémente déjà la méthode Validate. A type already includes an implementation of the 'Validate' method. - A type already includes an implementation of the 'Validate' method. + Un type inclut déjà une implémentation de la méthode 'Validate'. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] cannot be applied to static class {0}. + [OptionsValidator] ne peut pas être appliqué à la classe statique {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' can't be applied to a static class. + 'OptionsValidatorAttribute' ne peut pas être appliqué à une classe statique. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. + Impossible d’utiliser [ValidateObjectMembers] ou [ValidateEnumeratedItems] sur des champs ou des propriétés avec un type générique ouvert {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. + Impossible d’utiliser 'ValidateObjectMembersAttribute' ou 'ValidateEnumeratedItemsAttribute' sur des champs ou des propriétés avec des types génériques ouverts. Can't apply validation attributes to constant or static member {0}. - Can't apply validation attributes to constant or static member {0}. + Impossible d’appliquer les attributs de validation au membre constant ou statique {0}. Can't validate constants, static fields or properties. - Can't validate constants, static fields or properties. + Impossible de valider les constantes, les champs statiques ou les propriétés. There is a circular type reference involving type {0} preventing it from being used for static validation. - There is a circular type reference involving type {0} preventing it from being used for static validation. + Une référence de type circulaire implique un type {0} l’empêche d’être utilisé pour la validation statique. Unsupported circular references in model types. - Unsupported circular references in model types. + Références circulaires non prises en charge dans les types de modèle. Type {0} does not implement the required IValidateOptions<{1}> interface. - Type {0} does not implement the required IValidateOptions<{1}> interface. + Le type {0} n’implémente pas l’interface<{1}> IValidateOptions requise. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. + Un type annoté avec 'OptionsValidatorAttribute' n’implémente pas l’interface nécessaire. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + L’attribut de validation '{0}' sur le membre '{1}' n’est pas accessible à partir du type de validateur '{2}'. Validation attribute on the member is inaccessible from the validator type.. - Validation attribute on the member is inaccessible from the validator type.. + L’attribut de validation sur le membre n’est pas accessible à partir du type de validateur. Can't apply validation attributes to private field or property {0}. - Can't apply validation attributes to private field or property {0}. + Impossible d’appliquer les attributs de validation au champ privé ou à la propriété {0}. Can't validate private fields or properties. - Can't validate private fields or properties. + Impossible de valider les champs ou propriétés privés. Type {0} has no fields or properties to validate, referenced from member {1}. - Type {0} has no fields or properties to validate, referenced from member {1}. + Le type {0} n’a aucun champ ou propriété à valider, référencé à partir du membre {1}. A member type has no fields or properties to validate. - A member type has no fields or properties to validate. + Un type de membre n’a aucun champ ou propriété à valider. Type {0} has no fields or properties to validate, referenced by type {1}. - Type {0} has no fields or properties to validate, referenced by type {1}. + Le type {0} n’a pas de champs ou de propriétés à valider, référencé par type {1}. A type has no fields or properties to validate. - A type has no fields or properties to validate. + Un type n’a pas de champs ou de propriétés à valider. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. + [ValidateEnumeratedItems] ne peut pas être utilisé sur des membres de type {0}, car il n’implémente pas IEnumerable<T>. Member type is not enumerable. - Member type is not enumerable. + Le type de membre n’est pas énumérable. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. + Type de validateur Null spécifié dans les attributs [ValidateObjectMembers] ou [ValidateEnumeratedItems]. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + Type de validateur Null spécifié pour les attributs 'ValidateObjectMembersAttribute' ou 'ValidateEnumeratedItemsAttribute'. @@ -134,32 +134,32 @@ Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. + Le type {0} a des annotations de validation, mais le membre {1} ne spécifie pas [ValidateEnumeratedItems] qui peut être une supervision. Member potentially missing enumerable validation. - Member potentially missing enumerable validation. + Le membre n’a peut-être pas de validation énumérable. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. + Le type {0} a des annotations de validation, mais le membre {1} ne spécifie pas [ValidateObjectMembers] qui pourrait être une méthode de récupération. Member potentially missing transitive validation. - Member potentially missing transitive validation. + Le membre n’a peut-être pas de validation transitive. Validator type {0} doesn't have a parameterless constructor. - Validator type {0} doesn't have a parameterless constructor. + Le type de validateur {0} n’a pas de constructeur sans paramètre. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validators used for transitive or enumerable validation must have a constructor with no parameters. + Les validateurs utilisés pour la validation transitive ou énumérable doivent avoir un constructeur sans paramètres. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf index 2355a93c01db99..f59cc9dcbeeefb 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf @@ -4,122 +4,122 @@ Type {0} already implements the Validate method. - Type {0} already implements the Validate method. + Il tipo {0} implementa già il metodo Validate. A type already includes an implementation of the 'Validate' method. - A type already includes an implementation of the 'Validate' method. + Un tipo include già un'implementazione del metodo 'Validate'. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] cannot be applied to static class {0}. + impossibile applicare [OptionsValidator] alla classe statica {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' can't be applied to a static class. + 'OptionsValidatorAttribute' non può essere applicato a una classe statica. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. + Non è possibile usare [ValidateObjectMembers] o [ValidateEnumeratedItems] in campi o proprietà con tipo generico aperto {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. + Non è possibile usare 'ValidateObjectMembersAttribute' o 'ValidateEnumeratedItemsAttribute' nei campi o nelle proprietà con tipi generici aperti. Can't apply validation attributes to constant or static member {0}. - Can't apply validation attributes to constant or static member {0}. + Non è possibile applicare attributi di convalida a un membro costante o statico {0}. Can't validate constants, static fields or properties. - Can't validate constants, static fields or properties. + Non è possibile convalidare costanti, campi statici o proprietà. There is a circular type reference involving type {0} preventing it from being used for static validation. - There is a circular type reference involving type {0} preventing it from being used for static validation. + Esiste un riferimento di tipo circolare che interessa il tipo {0} e ne impedisce l'utilizzo per la convalida statica. Unsupported circular references in model types. - Unsupported circular references in model types. + Riferimenti circolari non supportati nei tipi di modello. Type {0} does not implement the required IValidateOptions<{1}> interface. - Type {0} does not implement the required IValidateOptions<{1}> interface. + Il tipo {0} non implementa l'interfaccia IValidateOptions<{1}> richiesta. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. + Un tipo annotato con 'OptionsValidatorAttribute' non implementa l'interfaccia necessaria. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + L'attributo di convalida '{0}' nel membro '{1}' non è accessibile dal tipo di validator '{2}'. Validation attribute on the member is inaccessible from the validator type.. - Validation attribute on the member is inaccessible from the validator type.. + L'attributo di convalida nel membro non è accessibile dal tipo di validator. Can't apply validation attributes to private field or property {0}. - Can't apply validation attributes to private field or property {0}. + Non è possibile applicare gli attributi di convalida al campo privato o alla proprietà {0}. Can't validate private fields or properties. - Can't validate private fields or properties. + Non è possibile convalidare proprietà o campi privati. Type {0} has no fields or properties to validate, referenced from member {1}. - Type {0} has no fields or properties to validate, referenced from member {1}. + Il tipo {0} non contiene campi o proprietà da convalidare, riferiti dal membro {1}. A member type has no fields or properties to validate. - A member type has no fields or properties to validate. + Un tipo di membro non contiene campi o proprietà da convalidare. Type {0} has no fields or properties to validate, referenced by type {1}. - Type {0} has no fields or properties to validate, referenced by type {1}. + Il tipo {0} non contiene campi o proprietà da convalidare, riferiti per tipo {1}. A type has no fields or properties to validate. - A type has no fields or properties to validate. + Un tipo non contiene campi o proprietà da convalidare. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. + [ValidateEnumeratedItems] non può essere usato nei membri di tipo {0} perché non implementa IEnumerable<T>. Member type is not enumerable. - Member type is not enumerable. + Il tipo di membro non è enumerabile. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. + Tipo di validator Null specificato negli attributi [ValidateObjectMembers] o [ValidateEnumeratedItems]. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + Tipo di validator Null specificato per gli attributi 'ValidateObjectMembersAttribute' o 'ValidateEnumeratedItemsAttribute'. @@ -134,32 +134,32 @@ Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. + Il tipo {0} include annotazioni di convalida, ma il membro {1} non specifica [ValidateEnumeratedItems] che potrebbe essere una supervisione. Member potentially missing enumerable validation. - Member potentially missing enumerable validation. + Convalida enumerabile potenzialmente mancante nel membro. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. + Il tipo {0} include annotazioni di convalida, ma il membro {1} non specifica [ValidateObjectMembers] che potrebbe essere una supervisione. Member potentially missing transitive validation. - Member potentially missing transitive validation. + Il membro potrebbe non avere una convalida transitiva. Validator type {0} doesn't have a parameterless constructor. - Validator type {0} doesn't have a parameterless constructor. + Il tipo di convalida {0} non dispone di un costruttore senza parametri. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validators used for transitive or enumerable validation must have a constructor with no parameters. + I convalidatori usati per la convalida transitiva o enumerabile devono avere un costruttore senza parametri. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf index 60e9a7db80c8d4..72a828f97c5e29 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf @@ -4,122 +4,122 @@ Type {0} already implements the Validate method. - Type {0} already implements the Validate method. + 型 {0} に Validate メソッドが既に実装されています。 A type already includes an implementation of the 'Validate' method. - A type already includes an implementation of the 'Validate' method. + 型には 'Validate' メソッドの実装が既に含まれています。 [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] cannot be applied to static class {0}. + 静的クラス {0} には [OptionsValidator] を適用できません。 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' can't be applied to a static class. + 'OptionsValidatorAttribute' は静的クラスに適用できません。 Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. + [ValidateObjectMembers] または [ValidateEnumeratedItems] は、オープンジェネリック型 {0} を持つフィールドまたはプロパティでは使用できません。 Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. + 'ValidateObjectMembersAttribute' または 'ValidateEnumeratedItemsAttribute' は、オープンジェネリック型を持つフィールドまたはプロパティでは使用できません。 Can't apply validation attributes to constant or static member {0}. - Can't apply validation attributes to constant or static member {0}. + 定数または静的メンバー {0} に検証属性を適用できません。 Can't validate constants, static fields or properties. - Can't validate constants, static fields or properties. + 定数、静的フィールド、またはプロパティを検証できません。 There is a circular type reference involving type {0} preventing it from being used for static validation. - There is a circular type reference involving type {0} preventing it from being used for static validation. + 型{0}を含む循環型参照があるため、静的検証に使用できません。 Unsupported circular references in model types. - Unsupported circular references in model types. + モデル型でサポートされていない循環参照です。 Type {0} does not implement the required IValidateOptions<{1}> interface. - Type {0} does not implement the required IValidateOptions<{1}> interface. + 必要な IValidateOptions<{1}> インターフェイスが型 {0} に実装されていません。 A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. + 'OptionsValidatorAttribute' の注釈が付けられた型が、必要とされるインターフェイスを実装していません。 Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + メンバー '{0}' の検証属性 '{1}' は、検証コントロールの種類 '{2}'からアクセスできません。 Validation attribute on the member is inaccessible from the validator type.. - Validation attribute on the member is inaccessible from the validator type.. + メンバーの検証属性は、検証コントロールの種類からアクセスできません... Can't apply validation attributes to private field or property {0}. - Can't apply validation attributes to private field or property {0}. + プライベート フィールドまたはプロパティ {0} には検証属性を適用できません。 Can't validate private fields or properties. - Can't validate private fields or properties. + プライベート フィールドまたはプロパティを検証できません。 Type {0} has no fields or properties to validate, referenced from member {1}. - Type {0} has no fields or properties to validate, referenced from member {1}. + 型 {0} にメンバー {1} から参照されている検証対象のフィールドまたはプロパティがありません。 A member type has no fields or properties to validate. - A member type has no fields or properties to validate. + メンバー型に検証対象のフィールドまたはプロパティがありません。 Type {0} has no fields or properties to validate, referenced by type {1}. - Type {0} has no fields or properties to validate, referenced by type {1}. + 型 {0} に型 {1} で参照されている検証対象のフィールドまたはプロパティがありません。 A type has no fields or properties to validate. - A type has no fields or properties to validate. + 型に検証対象のフィールドまたはプロパティがありません。 [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. + [ValidateEnumeratedItems] は IEnumerable<T> を実装していないため、型 {0} のメンバーでは使用できません。 Member type is not enumerable. - Member type is not enumerable. + メンバー型は列挙型ではありません。 Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. + [ValidateObjectMembers] 属性または [ValidateEnumeratedItems] 属性で null のバリデーター型が指定されています。 Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + 'ValidateObjectMembersAttribute' 属性または 'ValidateEnumeratedItemsAttribute' 属性に対して NULL のバリデーター型が指定されています。 @@ -134,32 +134,32 @@ Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. + 型 {0} には検証の注釈がありますが、メンバー {1} では [ValidateEnumeratedItem] が指定されていません。これは誤りである可能性があります。 Member potentially missing enumerable validation. - Member potentially missing enumerable validation. + 列挙型の検証がメンバーに存在しない可能性があります。 Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. + 型 {0} には検証の注釈がありますが、メンバー {1} では [ValidateObjectMembers] が指定されていません。これは誤りである可能性があります。 Member potentially missing transitive validation. - Member potentially missing transitive validation. + メンバーに推移性の検証がない可能性があります。 Validator type {0} doesn't have a parameterless constructor. - Validator type {0} doesn't have a parameterless constructor. + バリデーター型 {0} にパラメーターなしのコンストラクターがありません。 Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validators used for transitive or enumerable validation must have a constructor with no parameters. + 推移性または列挙型の検証に使用されるバリデーターには、パラメーターのないコンストラクターが必要です。 diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf index e350b2f6f437de..9018aaf6993610 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf @@ -4,122 +4,122 @@ Type {0} already implements the Validate method. - Type {0} already implements the Validate method. + 형식 {0}은(는) Validate 메서드를 이미 구현하고 있습니다. A type already includes an implementation of the 'Validate' method. - A type already includes an implementation of the 'Validate' method. + 형식에 'Validate' 메서드 구현이 이미 포함되어 있습니다. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] cannot be applied to static class {0}. + [OptionsValidator]은(는) 정적 클래스 {0}에 적용할 수 없습니다. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' can't be applied to a static class. + 'OptionsValidatorAttribute'는 정적 클래스에 적용할 수 없습니다. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. + 열린 제네릭 형식 {0}의 필드 또는 속성에는 [ValidateObjectMembers] 또는 [ValidateEnumeratedItems]을(를) 사용할 수 없습니다. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. + 열린 제네릭 형식의 필드 또는 속성에는 'ValidateObjectMembersAttribute' 또는 'ValidateEnumeratedItemsAttribute'를 사용할 수 없습니다. Can't apply validation attributes to constant or static member {0}. - Can't apply validation attributes to constant or static member {0}. + 상수 또는 정적 멤버 {0}에 유효성 검사 특성을 적용할 수 없습니다. Can't validate constants, static fields or properties. - Can't validate constants, static fields or properties. + 상수, 정적 필드 또는 속성을 확인할 수 없습니다. There is a circular type reference involving type {0} preventing it from being used for static validation. - There is a circular type reference involving type {0} preventing it from being used for static validation. + 정적 유효성 검사에 사용할 수 없으므로 형식 {0} 관련된 순환 형식 참조가 있습니다. Unsupported circular references in model types. - Unsupported circular references in model types. + 모델 형식에 지원되지 않는 순환 참조가 있습니다. Type {0} does not implement the required IValidateOptions<{1}> interface. - Type {0} does not implement the required IValidateOptions<{1}> interface. + 형식 {0}은(는) 필요한 IValidateOptions<{1}> 인터페이스를 구현하지 않습니다. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. + 'OptionsValidatorAttribute'로 주석이 추가된 형식은 필요한 인터페이스를 구현하지 않습니다. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + 유효성 검사기 유형 '{2}'에서 '{1}' 멤버의 '{0}' 유효성 검사 특성에 액세스할 수 없습니다. Validation attribute on the member is inaccessible from the validator type.. - Validation attribute on the member is inaccessible from the validator type.. + 유효성 검사기 유형에서 멤버의 유효성 검사 특성에 액세스할 수 없습니다. Can't apply validation attributes to private field or property {0}. - Can't apply validation attributes to private field or property {0}. + 프라이빗 필드 또는 속성 {0}에 유효성 검사 특성을 적용할 수 없습니다. Can't validate private fields or properties. - Can't validate private fields or properties. + 프라이빗 필드 또는 속성의 유효성을 검사할 수 없습니다. Type {0} has no fields or properties to validate, referenced from member {1}. - Type {0} has no fields or properties to validate, referenced from member {1}. + 형식 {0}은(는) 유효성을 검사할 필드 또는 속성이 없으므로 멤버 {1}을(를) 참조합니다. A member type has no fields or properties to validate. - A member type has no fields or properties to validate. + 멤버 형식에 유효성을 검사할 필드 또는 속성이 없습니다. Type {0} has no fields or properties to validate, referenced by type {1}. - Type {0} has no fields or properties to validate, referenced by type {1}. + 형식 {0}은(는) 유효성을 검사할 필드 또는 속성이 없으므로 형식 {1}을(를) 참조합니다. A type has no fields or properties to validate. - A type has no fields or properties to validate. + 형식에 유효성을 검사할 필드 또는 속성이 없습니다. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. + [ValidateEnumeratedItems]은(는) IEnumerable<T>을(를) 구현하지 않으므로 형식 {0}의 멤버에 사용할 수 없습니다. Member type is not enumerable. - Member type is not enumerable. + 멤버 형식을 열거할 수 없습니다. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. + [ValidateObjectMembers] 또는 [ValidateEnumeratedItems] 특성에 Null 유효성 검사기 형식이 지정되었습니다. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + 'ValidateObjectMembersAttribute' 또는 'ValidateEnumeratedItemsAttribute' 특성에 Null 유효성 검사기 형식이 지정되었습니다. @@ -134,32 +134,32 @@ Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. + 형식 {0}은(는) 유효성 검사 주석이 있지만 멤버 {1}은(는) 참조할 수 있는 [ValidateEnumeratedItems]을(를) 지정하지 않습니다. Member potentially missing enumerable validation. - Member potentially missing enumerable validation. + 멤버에 열거 가능한 유효성 검사가 누락되었을 수 있습니다. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. + 형식 {0}은(는) 유효성 검사 주석이 있지만 멤버 {1}은(는) 참조할 수 있는 [ValidateObjectMembers]을(를) 지정하지 않습니다. Member potentially missing transitive validation. - Member potentially missing transitive validation. + 멤버에 전이적 유효성 검사가 누락되었을 수 있습니다. Validator type {0} doesn't have a parameterless constructor. - Validator type {0} doesn't have a parameterless constructor. + 유효성 검사기 형식 {0}은(는) 매개 변수가 없는 생성자가 없습니다. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validators used for transitive or enumerable validation must have a constructor with no parameters. + 전이적 또는 열거형 유효성 검사에 사용되는 유효성 검사기에는 매개 변수가 없는 생성자가 있어야 합니다. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf index edaf8b9d00e9ba..126471f22a6c9e 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf @@ -4,122 +4,122 @@ Type {0} already implements the Validate method. - Type {0} already implements the Validate method. + Typ {0} już implementuje metodę Validate. A type already includes an implementation of the 'Validate' method. - A type already includes an implementation of the 'Validate' method. + Typ zawiera już implementację metody „Validate”. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] cannot be applied to static class {0}. + Nie można zastosować elementu [OptionsValidator] do klasy statycznej {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' can't be applied to a static class. + Nie można zastosować elementu „OptionsValidatorAttribute” do klasy statycznej. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. + Nie można użyć atrybutu [ValidateObjectMembers] lub [ValidateEnumeratedItems] w polach lub właściwościach z otwartymi typami ogólnymi {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. + Nie można użyć atrybutu „ValidateObjectMembersAttribute” lub „ValidateEnumeratedItemsAttribute” w polach lub właściwościach z otwartymi typami ogólnymi. Can't apply validation attributes to constant or static member {0}. - Can't apply validation attributes to constant or static member {0}. + Nie można zastosować atrybutów walidacji do stałych lub statycznych elementów członkowskich {0}. Can't validate constants, static fields or properties. - Can't validate constants, static fields or properties. + Nie można zweryfikować stałych, pól statycznych lub właściwości. There is a circular type reference involving type {0} preventing it from being used for static validation. - There is a circular type reference involving type {0} preventing it from being used for static validation. + Istnieje cykliczne odwołanie do typu dotyczące typu {0} uniemożliwiające użycie go do weryfikacji statycznej. Unsupported circular references in model types. - Unsupported circular references in model types. + Nieobsługiwane odwołania cykliczne w typach modeli. Type {0} does not implement the required IValidateOptions<{1}> interface. - Type {0} does not implement the required IValidateOptions<{1}> interface. + Typ {0} nie implementuje wymaganego interfejsu IValidateOptions<{1}>. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. + Typ z adnotacją „OptionsValidatorAttribute” nie implementuje wymaganego interfejsu. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Atrybut walidacji „{0}” elementu członkowskiego „{1}” jest niedostępny z typu modułu sprawdzania poprawności „{2}”. Validation attribute on the member is inaccessible from the validator type.. - Validation attribute on the member is inaccessible from the validator type.. + Atrybut walidacji elementu członkowskiego jest niedostępny z typu modułu sprawdzania poprawności. Can't apply validation attributes to private field or property {0}. - Can't apply validation attributes to private field or property {0}. + Nie można zastosować atrybutów weryfikacji do pola prywatnego lub właściwości {0}. Can't validate private fields or properties. - Can't validate private fields or properties. + Nie można zweryfikować prywatnych pól lub właściwości. Type {0} has no fields or properties to validate, referenced from member {1}. - Type {0} has no fields or properties to validate, referenced from member {1}. + Typ {0} nie ma pól ani właściwości do zweryfikowania, do których odwołuje się element członkowski {1}. A member type has no fields or properties to validate. - A member type has no fields or properties to validate. + Typ elementu członkowskiego nie ma pól ani właściwości do zweryfikowania. Type {0} has no fields or properties to validate, referenced by type {1}. - Type {0} has no fields or properties to validate, referenced by type {1}. + Typ {0} nie ma pól ani właściwości do zweryfikowania, do których odwołuje się typ {1}. A type has no fields or properties to validate. - A type has no fields or properties to validate. + Typ nie ma pól ani właściwości do zweryfikowania. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. + Atrybutu [ValidateEnumeratedItems] nie można używać w przypadku elementów członkowskich typu {0}, ponieważ nie implementuje interfejsu IEnumerable<T>. Member type is not enumerable. - Member type is not enumerable. + Nie można wyliczyć typu elementu członkowskiego. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. + W atrybutach [ValidateObjectMembers] lub [ValidateEnumeratedItems] określono typ modułu sprawdzania poprawności o wartości null. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + Określono typ modułu sprawdzania poprawności o wartości null dla atrybutu „ValidateObjectMembersAttribute” lub „ValidateEnumeratedItemsAttribute”. @@ -134,32 +134,32 @@ Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. + Typ {0} ma adnotacje walidacji, ale element członkowski {1} nie określa atrybutu [ValidateEnumeratedItems], co może być przeoczeniem. Member potentially missing enumerable validation. - Member potentially missing enumerable validation. + W elemencie członkowskim może brakować walidacji możliwej do wyliczenia. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. + Typ {0} ma adnotacje walidacji, ale element członkowski {1} nie określa atrybutu [ValidateObjectMembers], co może być przeoczeniem. Member potentially missing transitive validation. - Member potentially missing transitive validation. + W przypadku elementu członkowskiego może potencjalnie brakować weryfikacji przechodniej. Validator type {0} doesn't have a parameterless constructor. - Validator type {0} doesn't have a parameterless constructor. + Typ modułu sprawdzania poprawności {0} nie ma konstruktora bez parametrów. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validators used for transitive or enumerable validation must have a constructor with no parameters. + Moduły sprawdzania poprawności używane do weryfikacji przechodniej lub weryfikacji możliwej do wyliczenia muszą mieć konstruktora bez żadnych parametrów. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf index f62a1ef241e372..dcc8db9dcbefe4 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf @@ -4,122 +4,122 @@ Type {0} already implements the Validate method. - Type {0} already implements the Validate method. + O tipo {0} já implementa o método Validar. A type already includes an implementation of the 'Validate' method. - A type already includes an implementation of the 'Validate' method. + Um tipo já inclui uma implementação do método "Validar". [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] cannot be applied to static class {0}. + [OptionsValidator] não pode ser aplicado à classe estática {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' can't be applied to a static class. + "OptionsValidatorAttribute" não pode ser aplicado a uma classe estática. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. + Não é possível usar [ValidateObjectMembers] ou [ValidateEnumeratedItems] em campos ou propriedades com o tipo genérico aberto {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. + Não é possível usar "ValidateObjectMembersAttribute" ou "ValidateEnumeratedItemsAttribute" em campos ou propriedades com tipos genéricos abertos. Can't apply validation attributes to constant or static member {0}. - Can't apply validation attributes to constant or static member {0}. + Não é possível aplicar atributos de validação a um membro constante ou estático {0}. Can't validate constants, static fields or properties. - Can't validate constants, static fields or properties. + Não é possível validar constantes, campos estáticos ou propriedades. There is a circular type reference involving type {0} preventing it from being used for static validation. - There is a circular type reference involving type {0} preventing it from being used for static validation. + Há uma referência de tipo circular que envolve o tipo {0} que a impede de ser usada para validação estática. Unsupported circular references in model types. - Unsupported circular references in model types. + Referências circulares sem suporte em tipos de modelo. Type {0} does not implement the required IValidateOptions<{1}> interface. - Type {0} does not implement the required IValidateOptions<{1}> interface. + O tipo {0} não implementa a interface IValidateOptions<{1}> necessária. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. + Um tipo anotado com "OptionsValidatorAttribute" não implementa a interface necessária. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + O atributo de validação '{0}' no membro '{1}' está inacessível do tipo de validador '{2}'. Validation attribute on the member is inaccessible from the validator type.. - Validation attribute on the member is inaccessible from the validator type.. + O atributo de validação no membro está inacessível do tipo de validador. Can't apply validation attributes to private field or property {0}. - Can't apply validation attributes to private field or property {0}. + Não é possível aplicar atributos de validação a um campo privado ou propriedade {0}. Can't validate private fields or properties. - Can't validate private fields or properties. + Não é possível validar propriedades ou campos privados. Type {0} has no fields or properties to validate, referenced from member {1}. - Type {0} has no fields or properties to validate, referenced from member {1}. + O tipo {0} não tem campos ou propriedades para validar, referenciados do membro {1}. A member type has no fields or properties to validate. - A member type has no fields or properties to validate. + Um tipo de membro não tem campos ou propriedades a serem validados. Type {0} has no fields or properties to validate, referenced by type {1}. - Type {0} has no fields or properties to validate, referenced by type {1}. + O tipo {0} não tem campos ou propriedades para validar, referenciados por tipo {1}. A type has no fields or properties to validate. - A type has no fields or properties to validate. + Um tipo não tem campos ou propriedades a serem validados. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. + [ValidateEnumeratedItems] não pode ser usado em membros do tipo {0}, pois ele não implementa IEnumerable<T>. Member type is not enumerable. - Member type is not enumerable. + O tipo de membro não é enumerável. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. + Tipo de validador nulo especificado nos atributos [ValidateObjectMembers] ou [ValidateEnumeratedItems]. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + Tipo de validador nulo especificado para os atributos "ValidateObjectMembersAttribute" ou "ValidateEnumeratedItemsAttribute". @@ -134,32 +134,32 @@ Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. + O tipo {0} tem anotações de validação, mas o membro {1} não especifica [ValidateEnumeratedItems], o que pode ser uma desatenção. Member potentially missing enumerable validation. - Member potentially missing enumerable validation. + Membro potencialmente ausente na validação enumerável. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. + O tipo {0} tem anotações de validação, mas o membro {1} não especifica [ValidateObjectMembers], o que pode ser uma desatenção. Member potentially missing transitive validation. - Member potentially missing transitive validation. + Membro potencialmente ausente na validação transitiva. Validator type {0} doesn't have a parameterless constructor. - Validator type {0} doesn't have a parameterless constructor. + O tipo de validador {0} não tem um construtor sem parâmetros. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validators used for transitive or enumerable validation must have a constructor with no parameters. + Os validadores usados para validação transitiva ou enumerável devem ter um construtor sem parâmetros. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf index b8069e4266ae37..c1fd957bf6c53d 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf @@ -4,122 +4,122 @@ Type {0} already implements the Validate method. - Type {0} already implements the Validate method. + Тип {0} уже реализует метод Validate. A type already includes an implementation of the 'Validate' method. - A type already includes an implementation of the 'Validate' method. + Тип уже содержит реализацию метода Validate. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] cannot be applied to static class {0}. + [OptionsValidator] невозможно применить к статическому классу {0}. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' can't be applied to a static class. + Параметр OptionsValidatorAttribute не может быть применен к статическому классу. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. + Нельзя использовать [ValidateObjectMembers] или [ValidateEnumeratedItems] для полей или свойств с открытыми универсальными типами {0}. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. + Нельзя использовать "ValidateObjectMembersAttribute" или "ValidateEnumeratedItemsAttribute" для полей или свойств с открытыми универсальными типами. Can't apply validation attributes to constant or static member {0}. - Can't apply validation attributes to constant or static member {0}. + Не удалось применить атрибуты проверки к константе или статическому элементу {0}. Can't validate constants, static fields or properties. - Can't validate constants, static fields or properties. + Не удалось проверить константы, статические поля или свойства. There is a circular type reference involving type {0} preventing it from being used for static validation. - There is a circular type reference involving type {0} preventing it from being used for static validation. + Существует циклическая ссылка на тип, включающая тип {0}, предотвращающий его использование для статической проверки. Unsupported circular references in model types. - Unsupported circular references in model types. + Неподдерживаемые циклические ссылки в типах моделей. Type {0} does not implement the required IValidateOptions<{1}> interface. - Type {0} does not implement the required IValidateOptions<{1}> interface. + Тип {0} не реализует требуемый интерфейс IValidateOptions<{1}>. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. + Тип с аннотацией OptionsValidatorAttribute не реализует необходимый интерфейс. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + Атрибут проверки "{0}" элемента "{1}" недоступен из типа средства проверки "{2}". Validation attribute on the member is inaccessible from the validator type.. - Validation attribute on the member is inaccessible from the validator type.. + Атрибут проверки элемента недоступен из типа средства проверки. Can't apply validation attributes to private field or property {0}. - Can't apply validation attributes to private field or property {0}. + Не удается применить атрибуты проверки к закрытому полю или свойству {0}. Can't validate private fields or properties. - Can't validate private fields or properties. + Не удается проверить частные поля или свойства. Type {0} has no fields or properties to validate, referenced from member {1}. - Type {0} has no fields or properties to validate, referenced from member {1}. + Тип {0} не содержит полей или свойств для проверки, на которые ссылается из элемента {1}. A member type has no fields or properties to validate. - A member type has no fields or properties to validate. + Тип элемента не имеет полей или свойств для проверки. Type {0} has no fields or properties to validate, referenced by type {1}. - Type {0} has no fields or properties to validate, referenced by type {1}. + Тип {0} не содержит полей или свойств для проверки, на которые ссылается тип {1}. A type has no fields or properties to validate. - A type has no fields or properties to validate. + Тип не имеет полей или свойств для проверки. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. + [ValidateEnumeratedItems] не может использоваться для элементов типа {0}, так как он не реализует IEnumerable<T>. Member type is not enumerable. - Member type is not enumerable. + Тип элемента не является перечисляемым. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. + Тип проверяющего элемента управления, указанный в [ValidateObjectMembers] или [ValidateEnumeratedItems] атрибутах, имеет значение NULL. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + Для атрибутов ValidateObjectMembersAttribute или ValidateEnumeratedItemsAttribute указан тип проверяющего элемента управления NULL. @@ -134,32 +134,32 @@ Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. + Тип {0} содержит примечания проверки, но элемент {1} не указывает [ValidateEnumeratedItems], который может быть задан. Member potentially missing enumerable validation. - Member potentially missing enumerable validation. + Элемент потенциально пропускает перечисляемую проверку. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. + Тип {0} содержит примечания проверки, но элемент {1} не указывает [ValidateObjectMembers], который может быть задан. Member potentially missing transitive validation. - Member potentially missing transitive validation. + Возможно, в элементе отсутствует транзитивная проверка. Validator type {0} doesn't have a parameterless constructor. - Validator type {0} doesn't have a parameterless constructor. + Тип проверяющего элемента управления {0} не имеет конструктора без параметров. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validators used for transitive or enumerable validation must have a constructor with no parameters. + У проверяющих элементов управления, используемых для транзитивной или перечисляемой проверки, должен быть конструктор без параметров. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf index 8cb34b9b6f900a..4adda20ccd1581 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf @@ -4,122 +4,122 @@ Type {0} already implements the Validate method. - Type {0} already implements the Validate method. + {0} türü Doğrulama yöntemini zaten uyguluyor. A type already includes an implementation of the 'Validate' method. - A type already includes an implementation of the 'Validate' method. + Bir tür zaten 'Validate' yönteminin bir uygulamasını içeriyor. [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] cannot be applied to static class {0}. + [OptionsValidator], {0} statik sınıfına uygulanamıyor. 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' can't be applied to a static class. + 'OptionsValidatorAttribute' statik sınıfa uygulanamaz. Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. + {0} açık genel türündeki alanlarda veya özelliklerde [ValidateObjectMembers] veya [ValidateEnumeratedItems] kullanılamaz. Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. + Açık genel türleri olan alanlarda veya özelliklerde 'ValidateObjectMembersAttribute' veya 'ValidateEnumeratedItemsAttribute' kullanılamaz. Can't apply validation attributes to constant or static member {0}. - Can't apply validation attributes to constant or static member {0}. + Doğrulama öznitelikleri sabit veya statik üye {0} için geçerli değildir. Can't validate constants, static fields or properties. - Can't validate constants, static fields or properties. + Sabitler, statik alanlar veya özellikler doğrulanamıyor. There is a circular type reference involving type {0} preventing it from being used for static validation. - There is a circular type reference involving type {0} preventing it from being used for static validation. + Statik doğrulama için kullanılmasını engelleyen {0} türü içeren döngüsel bir tür başvurusu var. Unsupported circular references in model types. - Unsupported circular references in model types. + Model türlerde döngüsel başvurular desteklenmiyor. Type {0} does not implement the required IValidateOptions<{1}> interface. - Type {0} does not implement the required IValidateOptions<{1}> interface. + {0} türü gerekli IValidateOptions<{1}> arabirimini uygulamıyor. A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. + 'OptionsValidatorAttribute' ile açıklama eklenmiş bir tür gerekli arabirimi uygulamıyor. Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + '{1}' adlı üye üzerindeki '{0}' doğrulama özniteliğine '{2}' doğrulayıcı türünden erişilemiyor. Validation attribute on the member is inaccessible from the validator type.. - Validation attribute on the member is inaccessible from the validator type.. + Üye üzerindeki doğrulama özniteliğine doğrulayıcı türünden erişilemiyor. Can't apply validation attributes to private field or property {0}. - Can't apply validation attributes to private field or property {0}. + Doğrulama öznitelikleri, {0} özel alanına veya özelliğine uygulanamıyor. Can't validate private fields or properties. - Can't validate private fields or properties. + Özel alanlar veya özellikler doğrulanamıyor. Type {0} has no fields or properties to validate, referenced from member {1}. - Type {0} has no fields or properties to validate, referenced from member {1}. + {0} türünde doğrulanacak alan veya özellik yok, {1} üyesinden başvurulur. A member type has no fields or properties to validate. - A member type has no fields or properties to validate. + Üye türünde doğrulanacak alan veya özellik yok. Type {0} has no fields or properties to validate, referenced by type {1}. - Type {0} has no fields or properties to validate, referenced by type {1}. + {0} türünde doğrulanacak alan veya özellik yok, {1} türü tarafından başvurulur. A type has no fields or properties to validate. - A type has no fields or properties to validate. + Türde doğrulanacak alan veya özellik yok. [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. + [ValidateEnumeratedItems], IEnumerable<T> uygulamadığından {0} türündeki üyeler üzerinde kullanılamıyor. Member type is not enumerable. - Member type is not enumerable. + Üye türü numaralandırılabilir değil. Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. + [ValidateObjectMembers] veya [ValidateEnumeratedItems] özniteliklerinde null doğrulayıcı türü belirtildi. Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + 'ValidateObjectMembersAttribute' veya 'ValidateEnumeratedItemsAttribute' öznitelikleri için null doğrulayıcı türü belirtildi. @@ -134,32 +134,32 @@ Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. + {0} türünde doğrulama ek açıklamaları var, ancak {1} üyesi gözden kaçmış olabilecek [ValidateEnumeratedItems] belirtmiyor. Member potentially missing enumerable validation. - Member potentially missing enumerable validation. + Üyede numaralandırılabilir doğrulama eksik olabilir. Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. + {0} türünde doğrulama ek açıklamaları var, ancak {1} üyesi gözden kaçmış olabilecek [ValidateObjectMembers] belirtmiyor. Member potentially missing transitive validation. - Member potentially missing transitive validation. + Üyede geçişli doğrulama eksik olabilir. Validator type {0} doesn't have a parameterless constructor. - Validator type {0} doesn't have a parameterless constructor. + {0} doğrulayıcı türü parametresiz bir oluşturucuya sahip değil. Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validators used for transitive or enumerable validation must have a constructor with no parameters. + Geçişli veya numaralandırılabilir doğrulama için kullanılan doğrulayıcıların parametresi olmayan bir oluşturucusu olmalıdır. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf index 707dcb36c697b0..4a6d79badc79f4 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -4,122 +4,122 @@ Type {0} already implements the Validate method. - Type {0} already implements the Validate method. + 类型 {0} 已实现 Validate 方法。 A type already includes an implementation of the 'Validate' method. - A type already includes an implementation of the 'Validate' method. + 类型已包含“Validate”方法的实现。 [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] cannot be applied to static class {0}. + [OptionsValidator] 无法应用于静态类 {0}。 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' can't be applied to a static class. + “OptionsValidatorAttribute”不能应用于静态类。 Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. + 不能对具有开放泛型类型 {0} 的字段或属性使用 [ValidateObjectMembers] 或 [ValidateEnumeratedItems]。 Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. + 不能对具有开放泛型类型的字段或属性使用 "ValidateObjectMembersAttribute" 或 "ValidateEnumeratedItemsAttribute"。 Can't apply validation attributes to constant or static member {0}. - Can't apply validation attributes to constant or static member {0}. + 无法将验证属性应用于常量或静态成员 {0}。 Can't validate constants, static fields or properties. - Can't validate constants, static fields or properties. + 无法验证常量、静态字段或属性。 There is a circular type reference involving type {0} preventing it from being used for static validation. - There is a circular type reference involving type {0} preventing it from being used for static validation. + 存在一个循环类型引用,其中涉及的类型 {0} 阻止将其用于静态验证。 Unsupported circular references in model types. - Unsupported circular references in model types. + 模型类型中不支持的循环引用。 Type {0} does not implement the required IValidateOptions<{1}> interface. - Type {0} does not implement the required IValidateOptions<{1}> interface. + 类型 {0} 未实现所需的 IValidateOptions<{1}> 接口。 A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. + 用 "OptionsValidatorAttribute" 批注的类型未实现必要的接口。 Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + 无法从验证程序类型“{2}”访问成员“{1}”上的验证属性“{0}”。 Validation attribute on the member is inaccessible from the validator type.. - Validation attribute on the member is inaccessible from the validator type.. + 无法从验证程序类型访问成员上的验证属性。 Can't apply validation attributes to private field or property {0}. - Can't apply validation attributes to private field or property {0}. + 无法将验证属性应用于专用字段或属性 {0}。 Can't validate private fields or properties. - Can't validate private fields or properties. + 无法验证专用字段或属性。 Type {0} has no fields or properties to validate, referenced from member {1}. - Type {0} has no fields or properties to validate, referenced from member {1}. + 类型 {0} 没有要验证的字段或属性,从成员 {1} 中引用。 A member type has no fields or properties to validate. - A member type has no fields or properties to validate. + 成员类型没有要验证的字段或属性。 Type {0} has no fields or properties to validate, referenced by type {1}. - Type {0} has no fields or properties to validate, referenced by type {1}. + 类型 {0} 没有要验证的字段或属性,由类型 {1} 引用。 A type has no fields or properties to validate. - A type has no fields or properties to validate. + 类型没有要验证的字段或属性。 [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. + 无法对类型 {0} 的成员使用 [ValidateEnumeratedItems],因为它未实现 IEnumerable<T>。 Member type is not enumerable. - Member type is not enumerable. + 成员类型不可枚举。 Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. + [ValidateObjectMembers] 或 [ValidateEnumeratedItems] 属性中指定的 Null 验证程序类型。 Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + 为“ValidateObjectMembersAttribute”或“ValidateEnumeratedItemsAttribute”属性指定的验证程序类型为 Null。 @@ -134,32 +134,32 @@ Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. + 类型 {0} 具有验证注释,但成员 {1} 未指定 [ValidateEnumeratedItems],这可能是一种监督。 Member potentially missing enumerable validation. - Member potentially missing enumerable validation. + 成员可能缺少可枚举验证。 Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. + 类型 {0} 具有验证注释,但成员 {1} 未指定 [ValidateObjectMembers],这可能是一种监督。 Member potentially missing transitive validation. - Member potentially missing transitive validation. + 成员可能缺少可传递验证。 Validator type {0} doesn't have a parameterless constructor. - Validator type {0} doesn't have a parameterless constructor. + 验证程序类型 {0} 没有无参数构造函数。 Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validators used for transitive or enumerable validation must have a constructor with no parameters. + 用于可传递验证或可枚举验证的验证程序必须具有没有参数的构造函数。 diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf index f8087186cb294b..f0d9a24cdfb1eb 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -4,122 +4,122 @@ Type {0} already implements the Validate method. - Type {0} already implements the Validate method. + 類型 {0} 已實作 [驗證] 方法。 A type already includes an implementation of the 'Validate' method. - A type already includes an implementation of the 'Validate' method. + 類型已經包含 [驗證] 方法的實作。 [OptionsValidator] cannot be applied to static class {0}. - [OptionsValidator] cannot be applied to static class {0}. + [OptionsValidator] 無法套用至靜態類別 {0}。 'OptionsValidatorAttribute' can't be applied to a static class. - 'OptionsValidatorAttribute' can't be applied to a static class. + 無法將 'OptionsValidatorAttribute' 套用至靜態類別。 Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. - Can't use [ValidateObjectMembers] or [ValidateEnumeratedItems] on fields or properties with open generic type {0}. + 無法在有開放式泛型型別 {0} 的欄位或屬性上使用 [ValidateObjectMembers] 或 [ValidateEnumeratedItems]。 Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. - Can't use 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' on fields or properties with open generic types. + 無法在有開放式泛型型別的欄位或屬性上使用 'ValidateObjectMembersAttribute' 或 'ValidateEnumeratedItemsAttribute'。 Can't apply validation attributes to constant or static member {0}. - Can't apply validation attributes to constant or static member {0}. + 無法將驗證屬性套用至常數或靜態成員 {0}。 Can't validate constants, static fields or properties. - Can't validate constants, static fields or properties. + 無法驗證常數、靜態欄位或屬性。 There is a circular type reference involving type {0} preventing it from being used for static validation. - There is a circular type reference involving type {0} preventing it from being used for static validation. + 有涉及類型 {0} 的循環類型參考讓它無法用於靜態驗證。 Unsupported circular references in model types. - Unsupported circular references in model types. + 模型類型中不支援的循環參考。 Type {0} does not implement the required IValidateOptions<{1}> interface. - Type {0} does not implement the required IValidateOptions<{1}> interface. + 類型 {0} 未實作必要的 IValidateOptions<{1}> 介面。 A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. - A type annotated with 'OptionsValidatorAttribute' doesn't implement the necessary interface. + 以 'OptionsValidatorAttribute' 附註的類型未實作必要的介面。 Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. - Validation attribute '{0}' on the member '{1}' is inaccessible from the validator type '{2}'. + 無法從驗證程式類型 '{2}' 存取成員 '{1}' 上的驗證屬性 '{0}'。 Validation attribute on the member is inaccessible from the validator type.. - Validation attribute on the member is inaccessible from the validator type.. + 無法從驗證程式類型存取成員上的驗證屬性。 Can't apply validation attributes to private field or property {0}. - Can't apply validation attributes to private field or property {0}. + 無法將驗證屬性套用至私用欄位或屬性 {0}。 Can't validate private fields or properties. - Can't validate private fields or properties. + 無法驗證私人欄位或屬性。 Type {0} has no fields or properties to validate, referenced from member {1}. - Type {0} has no fields or properties to validate, referenced from member {1}. + 參照會員 {1},類型 {0} 沒有欄位或屬性可供驗證。 A member type has no fields or properties to validate. - A member type has no fields or properties to validate. + 成員類型沒有欄位或屬性可供驗證。 Type {0} has no fields or properties to validate, referenced by type {1}. - Type {0} has no fields or properties to validate, referenced by type {1}. + 參照類型 {1},類型 {0} 沒有欄位或屬性可供驗證。 A type has no fields or properties to validate. - A type has no fields or properties to validate. + 類型沒有欄位或屬性可供驗證。 [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. - [ValidateEnumeratedItems] cannot be used on members of type {0} as it doesn't implement IEnumerable<T>. + [ValidateEnumeratedItems] 無法用於類型 {0} 的成員,因為其未實作 IEnumerable<T>。 Member type is not enumerable. - Member type is not enumerable. + 成員類型無法列舉。 Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. - Null validator type specified in [ValidateObjectMembers] or [ValidateEnumeratedItems] attributes. + [ValidateObjectMembers] 或 [ValidateEnumeratedItems] 屬性中指定的 Null 驗證程式類型。 Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. - Null validator type specified for the 'ValidateObjectMembersAttribute' or 'ValidateEnumeratedItemsAttribute' attributes. + 為 'ValidateObjectMembersAttribute' 或 'ValidateEnumeratedItemsAttribute' 屬性指定的 Null 驗證程式類型。 @@ -134,32 +134,32 @@ Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateEnumeratedItems] which could be an oversight. + 成員 {0} 具備驗證註釋,但成員 {1} 未指定 [ValidateObjectMembers] (可能為監督)。 Member potentially missing enumerable validation. - Member potentially missing enumerable validation. + 成員可能遺漏可列舉的驗證。 Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. - Type {0} has validation annotations, but member {1} doesn't specify [ValidateObjectMembers] which could be an oversight. + 類型 {0} 具備驗證註釋,但成員 {1} 未指定 [ValidateObjectMembers] (可能為監督)。 Member potentially missing transitive validation. - Member potentially missing transitive validation. + 成員可能遺漏轉移的驗證。 Validator type {0} doesn't have a parameterless constructor. - Validator type {0} doesn't have a parameterless constructor. + 驗證程式類型 {0} 沒有無參數建構函式。 Validators used for transitive or enumerable validation must have a constructor with no parameters. - Validators used for transitive or enumerable validation must have a constructor with no parameters. + 用於轉移或可列舉驗證的驗證程式必須具備沒有參數的建構函式。 diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf index aba6380486a3b7..e1b25c7690ffa4 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf @@ -439,12 +439,12 @@ The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. - The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. + Typ {0} bude v nativním podpisu považován za strukturu, nikoli za nativní HRESULT. Pokud jej chcete považovat za HRESULT, přidejte do metody [return:MarshalAs(UnmanagedType.Error)]. This type will be treated as a struct in the native signature, not as a native HRESULT - This type will be treated as a struct in the native signature, not as a native HRESULT + Tento typ bude v nativním podpisu považován za strukturu, nikoli za nativní HRESULT. @@ -904,7 +904,7 @@ The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + Atribut „[Out]“ se podporuje pouze u parametrů pole. Zvažte použití klíčových slov „out“ nebo „ref“, aby se parametr dalo měnit. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf index 6b978f9aff5a9f..1b056b0cb4118e 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf @@ -439,12 +439,12 @@ The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. - The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. + Der Typ '{0}' wird als Struktur in der nativen Signatur und nicht als natives HRESULT behandelt. Um ihn als HRESULT zu behandeln, fügen Sie der Methode "[return:MarshalAs(UnmanagedType.Error)]" hinzu. This type will be treated as a struct in the native signature, not as a native HRESULT - This type will be treated as a struct in the native signature, not as a native HRESULT + Dieser Typ wird als Struktur in der nativen Signatur und nicht als natives HRESULT behandelt @@ -904,7 +904,7 @@ The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + Das [Out]-Attribut wird nur für Arrayparameter gemarshallt werden. Erwägen Sie die Verwendung der Schlüsselwörter "out" oder "ref", um den Parameter änderbar zu machen. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf index 077827dbf7ef9b..7d67b06c68960e 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf @@ -439,12 +439,12 @@ The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. - The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. + El tipo '{0}' se tratará como un struct en la firma nativa, no como un HRESULT nativo. Para tratarlo como un HRESULT, añade '[return:MarshalAs(UnmanagedType.Error)]' al método. This type will be treated as a struct in the native signature, not as a native HRESULT - This type will be treated as a struct in the native signature, not as a native HRESULT + Este tipo se tratará como una estructura en la firma nativa, no como un HRESULT nativo. @@ -904,7 +904,7 @@ The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + El atributo "[Out]" solo se admite en parámetros de matriz. Considere la posibilidad de usar palabras clave "out" o "ref" para hacer que el parámetro sea mutable. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf index 7b06fbb9966ce1..e4a153641da409 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf @@ -439,12 +439,12 @@ The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. - The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. + Le type « {0} » sera traité en tant que struct dans la signature native, et non en tant que HRESULT natif. Pour le traiter en tant que HRESULT, ajoutez « [return:MarshalAs(UnmanagedType.Error)] » à la méthode. This type will be treated as a struct in the native signature, not as a native HRESULT - This type will be treated as a struct in the native signature, not as a native HRESULT + Ce type sera traité en tant que struct dans la signature native, et non en tant que HRESULT natif diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf index ee4ead36b3e114..acc74fc43e9ed5 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf @@ -439,12 +439,12 @@ The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. - The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. + Il tipo '{0}' verrà considerato come uno struct nella firma nativa, non come HRESULT nativo. Per considerare questo valore come HRESULT, aggiungere '[return:MarshalAs(UnmanagedType.Error)]' al metodo. This type will be treated as a struct in the native signature, not as a native HRESULT - This type will be treated as a struct in the native signature, not as a native HRESULT + Questo tipo verrà considerato come uno struct nella firma nativa, non come HRESULT nativo diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf index 9c12755cb80b44..946718bd8962ed 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf @@ -439,12 +439,12 @@ The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. - The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. + 型 '{0}' は、ネイティブ HRESULT としてではなく、ネイティブ シグネチャ内の構造体として扱われます。これを HRESULT として扱うには、'[return:MarshalAs(UnmanagedType.Error)]' をメソッドに追加します。 This type will be treated as a struct in the native signature, not as a native HRESULT - This type will be treated as a struct in the native signature, not as a native HRESULT + この型はネイティブの HRESULT ではなく、ネイティブ シグネチャの構造体として扱われます @@ -904,7 +904,7 @@ The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + '[Out]' 属性は、配列パラメーターでのみサポートされます。パラメーターを変更可能にするには、'out' または 'ref' キーワードを使用することを検討してください。 diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf index 53b72d47f60fa3..baa3e6381b26d7 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf @@ -439,12 +439,12 @@ The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. - The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. + '{0}' 형식은 네이티브 HRESULT가 아니라 네이티브 서명에서 구조체로 처리됩니다. HRESULT로 처리하려면 메서드에 '[return:MarshalAs(UnmanagedType.Error)]'를 추가하세요. This type will be treated as a struct in the native signature, not as a native HRESULT - This type will be treated as a struct in the native signature, not as a native HRESULT + 이 형식은 네이티브 HRESULT가 아니라 네이티브 서명의 구조체로 처리됩니다. @@ -904,7 +904,7 @@ The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + '[Out]' 특성은 배열 매개 변수에서만 지원됩니다. 매개 변수를 변경할 수 있도록 'out' 또는 'ref' 키워드를 사용하는 것이 좋습니다. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf index fb6cf9f172c21b..5f5447d2cd1ec5 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf @@ -439,12 +439,12 @@ The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. - The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. + Typ „{0}” będzie traktowany jako struktura w podpisie natywnym, a nie jako natywny wynik HRESULT. Aby traktować to jako HRESULT, dodaj element „[return:MarshalAs(UnmanagedType.Error)]” do metody. This type will be treated as a struct in the native signature, not as a native HRESULT - This type will be treated as a struct in the native signature, not as a native HRESULT + Ten typ będzie traktowany jako struktura w podpisie natywnym, a nie jako natywny wynik HRESULT diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf index 8d2e606d2d0307..5eac2e488d6ee1 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf @@ -439,12 +439,12 @@ The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. - The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. + O tipo '{0}' será tratado como uma estrutura na assinatura nativa, não como um HRESULT nativo. Para tratar isso como um HRESULT, adicione '[return:MarshalAs(UnmanagedType.Error)]' ao método. This type will be treated as a struct in the native signature, not as a native HRESULT - This type will be treated as a struct in the native signature, not as a native HRESULT + Este tipo será tratado como uma estrutura na assinatura nativa, não como um HRESULT nativo @@ -904,7 +904,7 @@ The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + O atributo "[Out]" só tem suporte em parâmetros de matriz. Considere usar palavras-chave "out" ou "ref" para tornar o parâmetro mutável. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf index fca13d2b25e7f6..3c763338f053c4 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf @@ -439,12 +439,12 @@ The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. - The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. + Тип "{0}" будет рассматриваться как структура в собственной подписи, а не как собственный HRESULT. Чтобы обработать это как HRESULT, добавьте в метод "[return:MarshalAs(UnmanagedType.Error)]". This type will be treated as a struct in the native signature, not as a native HRESULT - This type will be treated as a struct in the native signature, not as a native HRESULT + Этот тип будет рассматриваться как структура в собственной подписи, а не как собственный HRESULT. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf index 44d2a4a4cbadd3..b3551845a81494 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf @@ -439,12 +439,12 @@ The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. - The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. + '{0}' türü, yerel HRESULT olarak değil, yerel imzada bir yapı olarak değerlendirilir. Bunu bir HRESULT olarak değerlendirmek için yönteme '[return:MarshalAs(UnmanagedType.Error)]' ekleyin. This type will be treated as a struct in the native signature, not as a native HRESULT - This type will be treated as a struct in the native signature, not as a native HRESULT + Bu tür, yerel HRESULT olarak değil, yerel imzada bir yapı olarak değerlendirilir diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf index e6fbf9115aec2d..5f77e5d137a900 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf @@ -439,12 +439,12 @@ The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. - The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. + 类型“{0}”将被视为本机签名中的结构,而不是本机 HRESULT。若要将其视为 HRESULT,请将“[return:MarshalAs(UnmanagedType.Error)]”添加到方法。 This type will be treated as a struct in the native signature, not as a native HRESULT - This type will be treated as a struct in the native signature, not as a native HRESULT + 此类型将被视为本机签名中的结构,而不是本机 HRESULT @@ -904,7 +904,7 @@ The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + `[Out]` 属性仅在数组参数上受支持。请考虑使用“out”或“ref”关键字使参数可变。 diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf index 528339678cefdb..30be4f574082e7 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf @@ -439,12 +439,12 @@ The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. - The type '{0}' will be treated as a struct in the native signature, not as a native HRESULT. To treat this as an HRESULT, add '[return:MarshalAs(UnmanagedType.Error)]' to the method. + 類型 '{0}' 會被視為原生簽章中的結構,而非原生 HRESULT。若要將此視為 HRESULT,請將 '[return:MarshalAs(UnmanagedType.Error)]' 新增至方法。 This type will be treated as a struct in the native signature, not as a native HRESULT - This type will be treated as a struct in the native signature, not as a native HRESULT + 此類型會被視為原生簽章中的結構,而非原生 HRESULT diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.cs.xlf index 41ce7674876442..0911c52f6700e0 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.cs.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - Zdrojový generátor System.Text.Json není k dispozici v jazyce C#{0}. Použijte prosím jazykovou verzi {1} nebo vyšší. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.de.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.de.xlf index a0b49aa02c03f3..156d9972bb6799 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.de.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - Der System.Text.Json-Quellgenerator ist in C# „{0}“ nicht verfügbar. Verwenden Sie die Sprachversion {1} oder höher. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.es.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.es.xlf index bdd7876fa38cd3..d609f70c4f02fb 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.es.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - El generador de origen System.Text.Json no está disponible en C# '{0}'. Use la versión de idioma {1} o superior. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.fr.xlf index 4b93e17edd6eb6..796b0000fa0973 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.fr.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - Le générateur de source System.Text.Json n'est pas disponible en C# '{0}'. Veuillez utiliser la version linguistique {1} ou supérieure. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.it.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.it.xlf index cb163ff94ec4f9..5c5f6a6d079979 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.it.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - Il generatore di origine System.Text.Json non è disponibile in C# '{0}'. Usare la versione del linguaggio {1} o successiva. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ja.xlf index 9e3366a8bf09a2..b9b33f30c719c2 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ja.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - System.Text.Json ソース ジェネレーターは C# '{0}' では使用できません。言語バージョン {1} 以上を使用してください。 + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ko.xlf index 735e6d772f7c26..4247e794b564a7 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ko.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - System.Text.Json 원본 생성기는 C# '{0}'에서 사용할 수 없습니다. {1} 이상의 언어 버전을 사용하세요. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pl.xlf index 8282fa16aa908b..3ac0444fdee2a2 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pl.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - Generator źródła System.Text.Json nie jest dostępny w języku C# „{0}”. Użyj wersji językowej lub nowszej {1} . + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pt-BR.xlf index 030a3f3302e729..d351ab9fa8a9ab 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pt-BR.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - O gerador de fonte System.Text.Json não está disponível em C# '{0}'. Use a versão do idioma {1} ou superior. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ru.xlf index 556fa665267f30..35b0dfef2a6640 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.ru.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - Генератор исходного кода System.Text.Json не доступен в C# "{0}". Используйте языковую версию {1} или выше. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.tr.xlf index e74d8818167e3d..8f9d470847a1b8 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.tr.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - System.Text.Json kaynak oluşturucusu C# '{0}' içinde kullanılamıyor. Lütfen dil sürümü {1} veya üstü sürümü kullanın. + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hans.xlf index 3ac4929b2b76dd..fc6ddb4af529ef 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - System.Text.Json 源生成器在 C#“{0}”中不可用。请使用{1}或更高版本的语言版本。 + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hant.xlf index a194d8afc278d7..46c0ae9ab63087 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - C# '{0}' 中無法使用 System.Text.Json 來源產生器。請使用 {1} 或更新的語言版本。 + The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. From 2ed29ecfd1095220db73d17aec87a021ef39bac1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 24 Aug 2023 08:39:38 -0700 Subject: [PATCH 071/783] Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20230823.2 (#91057) Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23421.3 -> To Version 3.11.0-beta1.23423.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 77bab659bb6547..440d7a2fa84317 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -371,11 +371,11 @@ https://github.com/dotnet/roslyn 93ce610622875b8e843f348e96496abd7056360d - + https://github.com/dotnet/roslyn-analyzers 76d99c5f3e11f0600fae074270c0d89042c360f0 - + https://github.com/dotnet/roslyn-analyzers 76d99c5f3e11f0600fae074270c0d89042c360f0 diff --git a/eng/Versions.props b/eng/Versions.props index 8d8fb363926aed..d3c2fd7c97309a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,8 +34,8 @@ - 3.11.0-beta1.23421.3 - 8.0.0-preview.23421.3 + 3.11.0-beta1.23423.2 + 8.0.0-preview.23423.2 - 4.8.0-2.23422.14 - 4.8.0-2.23422.14 - 4.8.0-2.23422.14 + 4.8.0-2.23423.10 + 4.8.0-2.23423.10 + 4.8.0-2.23423.10 @@ -230,15 +230,6 @@ - - - <_MajorVersion>$([System.Version]::Parse('$(AssemblyVersion)').Major) - <_MinorVersion>$([System.Version]::Parse('$(AssemblyVersion)').Minor) - <_PatchVersion>$([System.Version]::Parse('$(AssemblyVersion)').Build) - <_BuildNumber>$([System.Version]::Parse('$(AssemblyVersion)').Revision) - - - 5 @@ -256,9 +247,9 @@ From f4120cc6972105809378f6800a75df6ea2a77aa9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 24 Aug 2023 15:36:51 -0700 Subject: [PATCH 074/783] [release/8.0] `PEImage` should not permit `m_path` field mutation (#91085) * Remove cases where PEImage::m_path was mutated. Create m_pathHash field and remove function. Remove FEATURE_CASE_SENSITIVE_FILESYSTEM. * Address contract violations * Remove try/catch and replace with assert --------- Co-authored-by: Aaron R Robinson --- src/coreclr/debug/daccess/request.cpp | 3 +-- src/coreclr/inc/sstring.h | 2 ++ src/coreclr/md/compiler/mdutil.cpp | 8 ------- src/coreclr/vm/dwbucketmanager.hpp | 8 +++---- src/coreclr/vm/excep.cpp | 5 +++-- src/coreclr/vm/peimage.cpp | 10 +++------ src/coreclr/vm/peimage.h | 3 +-- src/coreclr/vm/peimage.inl | 32 ++------------------------- src/coreclr/vm/peimagelayout.cpp | 15 ++++++++++--- src/coreclr/vm/readytoruninfo.cpp | 7 +++--- 10 files changed, 31 insertions(+), 62 deletions(-) diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp index 114900ffaf0365..e5cc22d8c708a5 100644 --- a/src/coreclr/debug/daccess/request.cpp +++ b/src/coreclr/debug/daccess/request.cpp @@ -2648,8 +2648,7 @@ ClrDataAccess::GetAssemblyLocation(CLRDATA_ADDRESS assembly, int count, _Inout_u // Turn from bytes to wide characters if (!pAssembly->GetPEAssembly()->GetPath().IsEmpty()) { - if (!pAssembly->GetPEAssembly()->GetPath(). - DacGetUnicode(count, location, pNeeded)) + if (!pAssembly->GetPEAssembly()->GetPath().DacGetUnicode(count, location, pNeeded)) { hr = E_FAIL; } diff --git a/src/coreclr/inc/sstring.h b/src/coreclr/inc/sstring.h index 00b826b23c3c54..6557ca0d43edb1 100644 --- a/src/coreclr/inc/sstring.h +++ b/src/coreclr/inc/sstring.h @@ -683,7 +683,9 @@ class EMPTY_BASES_DECL SString : private SBuffer BOOL IsASCIIScanned() const; void SetASCIIScanned() const; void SetNormalized() const; +public: BOOL IsNormalized() const; +private: void ClearNormalized() const; void EnsureWritable() const; diff --git a/src/coreclr/md/compiler/mdutil.cpp b/src/coreclr/md/compiler/mdutil.cpp index 8fb1551ef7ceea..05b56a25875bb0 100644 --- a/src/coreclr/md/compiler/mdutil.cpp +++ b/src/coreclr/md/compiler/mdutil.cpp @@ -265,11 +265,7 @@ HRESULT LOADEDMODULES::FindCachedReadOnlyEntry( { // If the name matches... LPCWSTR pszName = pRegMeta->GetNameOfDBFile(); - #ifdef FEATURE_CASE_SENSITIVE_FILESYSTEM - if (u16_strcmp(szName, pszName) == 0) - #else if (SString::_wcsicmp(szName, pszName) == 0) - #endif { ULONG cRefs; @@ -299,11 +295,7 @@ HRESULT LOADEDMODULES::FindCachedReadOnlyEntry( { // If the name matches... LPCWSTR pszName = pRegMeta->GetNameOfDBFile(); - #ifdef FEATURE_CASE_SENSITIVE_FILESYSTEM - if (u16_strcmp(szName, pszName) == 0) - #else if (SString::_wcsicmp(szName, pszName) == 0) - #endif { ULONG cRefs; diff --git a/src/coreclr/vm/dwbucketmanager.hpp b/src/coreclr/vm/dwbucketmanager.hpp index 167685f78a597c..82532aa5b42b4b 100644 --- a/src/coreclr/vm/dwbucketmanager.hpp +++ b/src/coreclr/vm/dwbucketmanager.hpp @@ -960,11 +960,9 @@ bool BaseBucketParamsManager::GetFileVersionInfoForModule(Module* pModule, USHOR // if we failed to get the version info from the native image then fall back to the IL image. if (!succeeded) { - LPCWSTR modulePath = pPEAssembly->GetPath().GetUnicode(); - if (modulePath != NULL && modulePath != SString::Empty() && SUCCEEDED(DwGetFileVersionInfo(modulePath, major, minor, build, revision))) - { - succeeded = true; - } + const SString& modulePath = pPEAssembly->GetPath(); + _ASSERTE(modulePath.IsNormalized()); + succeeded = !modulePath.IsEmpty() && SUCCEEDED(DwGetFileVersionInfo(modulePath.GetUnicode(), major, minor, build, revision)); } } diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index 5be645ad496d7d..ce8b325a5f41b8 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -11616,7 +11616,8 @@ VOID GetAssemblyDetailInfo(SString &sType, SString sAlcName; pPEAssembly->GetAssemblyBinder()->GetNameForDiagnostics(sAlcName); - if (pPEAssembly->GetPath().IsEmpty()) + SString assemblyPath{ pPEAssembly->GetPath() }; + if (assemblyPath.IsEmpty()) { detailsUtf8.Printf("Type %s originates from '%s' in the context '%s' in a byte array", sType.GetUTF8(), @@ -11629,7 +11630,7 @@ VOID GetAssemblyDetailInfo(SString &sType, sType.GetUTF8(), sAssemblyDisplayName.GetUTF8(), sAlcName.GetUTF8(), - pPEAssembly->GetPath().GetUTF8()); + assemblyPath.GetUTF8()); } sAssemblyDetailInfo.Append(detailsUtf8.GetUnicode()); diff --git a/src/coreclr/vm/peimage.cpp b/src/coreclr/vm/peimage.cpp index 55fc458c83762c..656b42b8111c70 100644 --- a/src/coreclr/vm/peimage.cpp +++ b/src/coreclr/vm/peimage.cpp @@ -141,11 +141,11 @@ ULONG PEImage::Release() result=InterlockedDecrement(&m_refCount); if (result == 0 ) { - LOG((LF_LOADER, LL_INFO100, "PEImage: Closing Image %s\n", m_path.GetUTF8())); + LOG((LF_LOADER, LL_INFO100, "PEImage: Closing %p\n", this)); if(m_bInHashMap) { PEImageLocator locator(this); - PEImage* deleted = (PEImage *)s_Images->DeleteValue(GetPathHash(), &locator); + PEImage* deleted = (PEImage *)s_Images->DeleteValue(m_pathHash, &locator); _ASSERTE(deleted == this); } } @@ -249,12 +249,7 @@ BOOL PEImage::CompareImage(UPTR u1, UPTR u2) EX_TRY { SString path(SString::Literal, pLocator->m_pPath); - -#ifdef FEATURE_CASE_SENSITIVE_FILESYSTEM - if (pImage->GetPath().Equals(path)) -#else if (pImage->GetPath().EqualsCaseInsensitive(path)) -#endif { ret = TRUE; } @@ -623,6 +618,7 @@ void PEImage::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) PEImage::PEImage(): m_path(), + m_pathHash(0), m_refCount(1), m_bInHashMap(FALSE), m_bundleFileLocation(), diff --git a/src/coreclr/vm/peimage.h b/src/coreclr/vm/peimage.h index d30e561890c79e..e7bfc11d319f12 100644 --- a/src/coreclr/vm/peimage.h +++ b/src/coreclr/vm/peimage.h @@ -132,8 +132,6 @@ class PEImage final PTR_PEImageLayout GetLoadedLayout(); PTR_PEImageLayout GetFlatLayout(); - BOOL HasPath(); - ULONG GetPathHash(); const SString& GetPath(); const SString& GetPathToLoad(); LPCWSTR GetPathForErrorMessages() { return GetPath(); } @@ -288,6 +286,7 @@ class PEImage final // ------------------------------------------------------------ SString m_path; + ULONG m_pathHash; LONG m_refCount; // means this is a unique (deduped) instance. diff --git a/src/coreclr/vm/peimage.inl b/src/coreclr/vm/peimage.inl index 6bb3c9320cb5f0..d17d5d9dd77387 100644 --- a/src/coreclr/vm/peimage.inl +++ b/src/coreclr/vm/peimage.inl @@ -288,6 +288,7 @@ inline void PEImage::Init(LPCWSTR pPath, BundleFileLocation bundleFileLocation) m_path = pPath; m_path.Normalize(); + m_pathHash = m_path.HashCaseInsensitive(); m_bundleFileLocation = bundleFileLocation; SetModuleFileNameHintForDAC(); } @@ -310,11 +311,7 @@ inline PTR_PEImage PEImage::FindByPath(LPCWSTR pPath, BOOL isInBundle /* = TRUE int CaseHashHelper(const WCHAR *buffer, COUNT_T count); PEImageLocator locator(pPath, isInBundle); -#ifdef FEATURE_CASE_SENSITIVE_FILESYSTEM - DWORD dwHash=path.Hash(); -#else DWORD dwHash = CaseHashHelper(pPath, (COUNT_T) u16_strlen(pPath)); -#endif return (PEImage *) s_Images->LookupValue(dwHash, &locator); } @@ -366,7 +363,7 @@ inline void PEImage::AddToHashMap() CONTRACTL_END; _ASSERTE(s_hashLock.OwnedByCurrentThread()); - s_Images->InsertValue(GetPathHash(),this); + s_Images->InsertValue(m_pathHash,this); m_bInHashMap=TRUE; } @@ -378,31 +375,6 @@ inline BOOL PEImage::Has32BitNTHeaders() return GetOrCreateLayout(PEImageLayout::LAYOUT_ANY)->Has32BitNTHeaders(); } -inline BOOL PEImage::HasPath() -{ - LIMITED_METHOD_CONTRACT; - - return !GetPath().IsEmpty(); -} - -inline ULONG PEImage::GetPathHash() -{ - CONTRACT(ULONG) - { - PRECONDITION(HasPath()); - MODE_ANY; - GC_NOTRIGGER; - THROWS; - } - CONTRACT_END; - -#ifdef FEATURE_CASE_SENSITIVE_FILESYSTEM - RETURN m_path.Hash(); -#else - RETURN m_path.HashCaseInsensitive(); -#endif -} - inline void PEImage::GetPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine) { CONTRACTL diff --git a/src/coreclr/vm/peimagelayout.cpp b/src/coreclr/vm/peimagelayout.cpp index c756c451649b34..0f0dde27618196 100644 --- a/src/coreclr/vm/peimagelayout.cpp +++ b/src/coreclr/vm/peimagelayout.cpp @@ -534,7 +534,10 @@ LoadedImageLayout::LoadedImageLayout(PEImage* pOwner, HRESULT* loadFailure) IfFailThrow(Init(m_Module, true)); - LOG((LF_LOADER, LL_INFO1000, "PEImage: Opened HMODULE %s\n", pOwner->GetPath().GetUTF8())); +#ifdef LOGGING + SString ownerPath{ pOwner->GetPath() }; + LOG((LF_LOADER, LL_INFO1000, "PEImage: Opened HMODULE %s\n", ownerPath.GetUTF8())); +#endif // LOGGING #else HANDLE hFile = pOwner->GetFileHandle(); @@ -548,8 +551,11 @@ LoadedImageLayout::LoadedImageLayout(PEImage* pOwner, HRESULT* loadFailure) return; } +#ifdef LOGGING + SString ownerPath{ pOwner->GetPath() }; LOG((LF_LOADER, LL_INFO1000, "PEImage: image %s (hFile %p) mapped @ %p\n", - pOwner->GetPath().GetUTF8(), hFile, (void*)m_LoadedFile)); + ownerPath.GetUTF8(), hFile, (void*)m_LoadedFile)); +#endif // LOGGING IfFailThrow(Init((void*)m_LoadedFile)); @@ -616,7 +622,10 @@ FlatImageLayout::FlatImageLayout(PEImage* pOwner) INT64 offset = pOwner->GetOffset(); INT64 size = pOwner->GetSize(); - LOG((LF_LOADER, LL_INFO100, "PEImage: Opening flat %s\n", pOwner->GetPath().GetUTF8())); +#ifdef LOGGING + SString ownerPath{ pOwner->GetPath() }; + LOG((LF_LOADER, LL_INFO100, "PEImage: Opening flat %s\n", ownerPath.GetUTF8())); +#endif // LOGGING // If a size is not specified, load the whole file if (size == 0) diff --git a/src/coreclr/vm/readytoruninfo.cpp b/src/coreclr/vm/readytoruninfo.cpp index 2c186cf7adeaff..e75373db8855aa 100644 --- a/src/coreclr/vm/readytoruninfo.cpp +++ b/src/coreclr/vm/readytoruninfo.cpp @@ -429,7 +429,8 @@ static void LogR2r(const char *msg, PEAssembly *pPEAssembly) if (r2rLogFile == NULL) return; - fprintf(r2rLogFile, "%s: \"%s\".\n", msg, pPEAssembly->GetPath().GetUTF8()); + SString assemblyPath{ pPEAssembly->GetPath() }; + fprintf(r2rLogFile, "%s: \"%s\".\n", msg, assemblyPath.GetUTF8()); fflush(r2rLogFile); } @@ -1904,7 +1905,7 @@ uint32_t ReadyToRun_TypeGenericInfoMap::GetGenericArgumentCount(mdTypeDef input, uint32_t count = ((uint8_t)typeGenericInfo & (uint8_t)ReadyToRunTypeGenericInfo::GenericCountMask); if (count > 2) foundResult = false; - + if (!foundResult) { HENUMInternalHolder hEnumTyPars(pImport); @@ -1922,7 +1923,7 @@ HRESULT ReadyToRun_TypeGenericInfoMap::GetGenericArgumentCountNoThrow(mdTypeDef uint32_t count = ((uint8_t)typeGenericInfo & (uint8_t)ReadyToRunTypeGenericInfo::GenericCountMask); if (count > 2) foundResult = false; - + if (!foundResult) { HENUMInternalHolder hEnumTyPars(pImport); From a1b75718cf9af2d48178676b587dc632d4a47579 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 24 Aug 2023 16:13:15 -0700 Subject: [PATCH 075/783] Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2251942 (#91082) * Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2251732 * Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2251732 --- .../gen/Resources/xlf/Strings.cs.xlf | 2 +- .../gen/Resources/xlf/Strings.de.xlf | 2 +- .../gen/Resources/xlf/Strings.es.xlf | 2 +- .../gen/Resources/xlf/Strings.fr.xlf | 2 +- .../gen/Resources/xlf/Strings.it.xlf | 2 +- .../gen/Resources/xlf/Strings.ja.xlf | 2 +- .../gen/Resources/xlf/Strings.ko.xlf | 2 +- .../gen/Resources/xlf/Strings.pl.xlf | 2 +- .../gen/Resources/xlf/Strings.pt-BR.xlf | 2 +- .../gen/Resources/xlf/Strings.ru.xlf | 2 +- .../gen/Resources/xlf/Strings.tr.xlf | 2 +- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 2 +- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 4 ++-- .../gen/Resources/xlf/Strings.cs.xlf | 2 +- .../gen/Resources/xlf/Strings.de.xlf | 2 +- .../gen/Resources/xlf/Strings.es.xlf | 2 +- .../gen/Resources/xlf/Strings.fr.xlf | 2 +- .../gen/Resources/xlf/Strings.it.xlf | 2 +- .../gen/Resources/xlf/Strings.ja.xlf | 2 +- .../gen/Resources/xlf/Strings.ko.xlf | 2 +- .../gen/Resources/xlf/Strings.pl.xlf | 2 +- .../gen/Resources/xlf/Strings.pt-BR.xlf | 2 +- .../gen/Resources/xlf/Strings.ru.xlf | 2 +- .../gen/Resources/xlf/Strings.tr.xlf | 2 +- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 2 +- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 4 ++-- .../System.Text.Json/gen/Resources/xlf/Strings.zh-Hant.xlf | 2 +- 27 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.cs.xlf index 00e8b1cc7d91a1..37788ebcb678e0 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.cs.xlf @@ -74,7 +74,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Zdrojový generátor nepodporuje jazykovou verzi jazyka C#. diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.de.xlf index 2e962cd97ac902..9ab54f800fbbca 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.de.xlf @@ -74,7 +74,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Die C#-Sprachversion wird vom Quellgenerator nicht unterstützt. diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.es.xlf index 46073f102868a1..338324b076f41d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.es.xlf @@ -74,7 +74,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + La versión del idioma C# no es compatible con el generador de origen. diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.fr.xlf index 2497ea11a88a04..13e61bd2e4a5e9 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.fr.xlf @@ -74,7 +74,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Version du langage C# non prise en charge par le générateur de source. diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.it.xlf index 06dadffd497939..8cf28e310dc03f 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.it.xlf @@ -74,7 +74,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Versione del linguaggio C# non supportata dal generatore di origine. diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ja.xlf index bd03905bfba997..6c9b4d737bbaea 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ja.xlf @@ -74,7 +74,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + ソース ジェネレーターでサポートされていない C# 言語バージョン。 diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ko.xlf index eea8ef2203ac1d..f38d678fa54e79 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ko.xlf @@ -74,7 +74,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + 원본 생성기에서 지원되지 않는 C# 언어 버전입니다. diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pl.xlf index 6dbecb86f7fc43..b7c27d6dc5a24b 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pl.xlf @@ -74,7 +74,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Wersja języka C# nie jest obsługiwana przez generator źródła. diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pt-BR.xlf index f7de3a39c5a055..bc05308fa051b9 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pt-BR.xlf @@ -74,7 +74,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Versão da linguagem C# não suportada pelo gerador de origem. diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ru.xlf index 9599e0f6b9b809..2136e696d079a3 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ru.xlf @@ -74,7 +74,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Версия языка C# не поддерживается генератором исходного кода. diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.tr.xlf index 529a109ef75304..357b981c7f4f90 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.tr.xlf @@ -74,7 +74,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + C# dil sürümü kaynak oluşturucu tarafından desteklenmiyor. diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hans.xlf index 879c6a773643a1..e9b74ddd39a10f 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -74,7 +74,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + 源生成器不支持 C# 语言版本。 diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hant.xlf index 42061caa455c27..cac7d73e8e5d6a 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -69,12 +69,12 @@ The Logging source generator is not available in C# {0}. Please use language version {1} or greater. - The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + C# {0} 無法使用記錄來源產生器。請使用 {1} 或更新的語言版本。 C# language version not supported by the source generator. - C# language version not supported by the source generator. + 來源產生器不支援 C# 語言版本。 diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf index cf1eaeedf07021..43818442898af7 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf @@ -129,7 +129,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Zdrojový generátor nepodporuje jazykovou verzi jazyka C#. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf index 507e5896457a51..bee47d77cb69b6 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf @@ -129,7 +129,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Die C#-Sprachversion wird vom Quellgenerator nicht unterstützt. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf index 4ee57aa7312aa0..1c99ae4dbe8287 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf @@ -129,7 +129,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + La versión del idioma C# no es compatible con el generador de origen. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf index 9e300eaed00812..ca8683e6a65f19 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf @@ -129,7 +129,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Version du langage C# non prise en charge par le générateur de source. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf index f59cc9dcbeeefb..fd07503323fbd1 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf @@ -129,7 +129,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Versione del linguaggio C# non supportata dal generatore di origine. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf index 72a828f97c5e29..c1e4e390fa59ce 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf @@ -129,7 +129,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + ソース ジェネレーターでサポートされていない C# 言語バージョン。 diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf index 9018aaf6993610..a93c8b1b555880 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf @@ -129,7 +129,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + 원본 생성기에서 지원되지 않는 C# 언어 버전입니다. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf index 126471f22a6c9e..5949f6a902609b 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf @@ -129,7 +129,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Wersja języka C# nie jest obsługiwana przez generator źródła. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf index dcc8db9dcbefe4..a2d117a7d285f8 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf @@ -129,7 +129,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Versão da linguagem C# não suportada pelo gerador de origem. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf index c1fd957bf6c53d..bd9e7c4ae55b00 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf @@ -129,7 +129,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + Версия языка C# не поддерживается генератором исходного кода. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf index 4adda20ccd1581..82a8e29cb42c31 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf @@ -129,7 +129,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + C# dil sürümü kaynak oluşturucu tarafından desteklenmiyor. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf index 4a6d79badc79f4..cedd65965409b6 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -129,7 +129,7 @@ C# language version not supported by the source generator. - C# language version not supported by the source generator. + 源生成器不支持 C# 语言版本。 diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf index f0d9a24cdfb1eb..0180ca96648f19 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -124,12 +124,12 @@ The options validation source generator is not available in C# {0}. Please use language version {1} or greater. - The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + C# {0} 無法使用選項驗證來源產生器。請使用 {1} 或更新的語言版本。 C# language version not supported by the source generator. - C# language version not supported by the source generator. + 來源產生器不支援 C# 語言版本。 diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hant.xlf index 46c0ae9ab63087..ed207add481d94 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + C# {0} 中無法使用 System.Text.Json 來源產生器。請使用 {1} 或更新的語言版本。 From 12c5dd7180c92bb59460f0d1eb7587e3d44ed5f2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 24 Aug 2023 16:14:26 -0700 Subject: [PATCH 076/783] Suppress credscan warnings in X.509 test files (#91080) Co-authored-by: Levi Broderick --- .../tests/X509Certificates/TestData.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs index 7110c78329778d..e3deb00b354d06 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs @@ -51,7 +51,8 @@ internal static class TestData // This pfx was generated by new X509Certificate(MsCertificate).Export(X509ContentType.Pfx) // and was choosen when the padding was 01 and caused a false-positive on decryption. - public static byte[] MsCertificateExportedToPfx_NullPassword = Convert.FromBase64String(@" + public static byte[] MsCertificateExportedToPfx_NullPassword = Convert.FromBase64String( + /* [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="This PKCS#12 blob only contains public info.")] */ @" MIIFxAIBAzCCBYoGCSqGSIb3DQEHAaCCBXsEggV3MIIFczCCBW8GCSqGSIb3DQEH BqCCBWAwggVcAgEAMIIFVQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIKpCU u5nlxAACAggAgIIFKG/SLlS1TJmxGUiXBPJ1r4yV+JMehwo6RYPMkCSnpKGaiLyA @@ -3057,7 +3058,8 @@ internal static DSAParameters GetDSA1024Params() "4D7314FCB4041469835268466D1390373566F7034C4736346CD17D020207D0").HexToByteArray(); internal static readonly byte[] Pkcs12NoPasswordRandomCounts = - Convert.FromBase64String(@" + Convert.FromBase64String( + /* [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Self-signed cert created specifically for inclusion in public-facing unit tests.")] */ @" MIIvdAIBAzCCLtQGCSqGSIb3DQEHAaCCLsUEgi7BMIIuvTCCLrkGCSqGSIb3DQEHAaCCLqoEgi6m MIIuojCCAvkGCyqGSIb3DQEMCgECoIIC6DCCAuQwXgYJKoZIhvcNAQUNMFEwMAYJKoZIhvcNAQUM MCMEELD+7LV5Y9tyUiJnNeZVLwQCASowDAYIKoZIhvcNAgsFADAdBglghkgBZQMEASoEEBzHfelA From 06c76d6f5f6d725a7e03e65da4db58191c8a8c1b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 24 Aug 2023 16:24:40 -0700 Subject: [PATCH 077/783] Fix JIT_ByRefWriteBarrier unwinding on macOS x64 (#91076) Local labels in the JIT_ByRefWriteBarrier were not wrapped in the LOCAL_LABEL macro. That causes incorrect unwinding in case an access violation occurs inside of this function. The closest label before the failure point is considered to be the actual function, but it obviously doesn't have the right unwind info. Close #89585 Co-authored-by: Jan Vorlicek --- src/coreclr/vm/amd64/jithelpers_fast.S | 98 +++++++++++++------------- src/tests/issues.targets | 4 +- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/coreclr/vm/amd64/jithelpers_fast.S b/src/coreclr/vm/amd64/jithelpers_fast.S index 32890b471b26c1..72f91a18061579 100644 --- a/src/coreclr/vm/amd64/jithelpers_fast.S +++ b/src/coreclr/vm/amd64/jithelpers_fast.S @@ -32,16 +32,16 @@ LEAF_ENTRY JIT_CheckedWriteBarrier, _TEXT // See if this is in GCHeap PREPARE_EXTERNAL_VAR g_lowest_address, rax cmp rdi, [rax] - // jb NotInHeap + // jb LOCAL_LABEL(NotInHeap) .byte 0x72, 0x12 PREPARE_EXTERNAL_VAR g_highest_address, rax cmp rdi, [rax] - // jnb NotInHeap + // jnb LOCAL_LABEL(NotInHeap) .byte 0x73, 0x06 jmp [rip + C_FUNC(JIT_WriteBarrier_Loc)] - NotInHeap: + LOCAL_LABEL(NotInHeap): // See comment above about possible AV mov [rdi], rsi ret @@ -85,16 +85,16 @@ LEAF_ENTRY JIT_WriteBarrier, _TEXT add rax, r10 cmp byte ptr [rax], 0x0 .byte 0x75, 0x06 - // jne CheckCardTable + // jne LOCAL_LABEL(CheckCardTable) mov byte ptr [rax], 0xFF NOP_3_BYTE // padding for alignment of constant // Check the lower and upper ephemeral region bounds - CheckCardTable: + LOCAL_LABEL(CheckCardTable): cmp rsi, r11 .byte 0x72,0x3D - // jb Exit + // jb LOCAL_LABEL(Exit) NOP_3_BYTE // padding for alignment of constant @@ -102,7 +102,7 @@ LEAF_ENTRY JIT_WriteBarrier, _TEXT cmp rsi, r10 .byte 0x73,0x2B - // jae Exit + // jae LOCAL_LABEL(Exit) nop // padding for alignment of constant @@ -112,10 +112,10 @@ LEAF_ENTRY JIT_WriteBarrier, _TEXT shr rdi, 0x0B cmp byte ptr [rdi + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardTable + // jne LOCAL_LABEL(UpdateCardTable) REPRET - UpdateCardTable: + LOCAL_LABEL(UpdateCardTable): mov byte ptr [rdi + rax], 0xFF #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES @@ -126,17 +126,17 @@ LEAF_ENTRY JIT_WriteBarrier, _TEXT cmp byte ptr [rdi + rax], 0xFF .byte 0x75, 0x02 - // jne UpdateCardBundle_WriteWatch_PostGrow64 + // jne LOCAL_LABEL(UpdateCardBundle_WriteWatch_PostGrow64) REPRET - UpdateCardBundle_WriteWatch_PostGrow64: + LOCAL_LABEL(UpdateCardBundle_WriteWatch_PostGrow64): mov byte ptr [rdi + rax], 0xFF #endif ret .balign 16 - Exit: + LOCAL_LABEL(Exit): REPRET NOP_3_BYTE @@ -184,7 +184,7 @@ LEAF_ENTRY JIT_WriteBarrier, _TEXT // Check the lower and upper ephemeral region bounds cmp rsi, rax - // jb Exit + // jb LOCAL_LABEL(Exit) .byte 0x72, 0x36 nop // padding for alignment of constant @@ -192,7 +192,7 @@ LEAF_ENTRY JIT_WriteBarrier, _TEXT movabs r8, 0xF0F0F0F0F0F0F0F0 cmp rsi, r8 - // jae Exit + // jae LOCAL_LABEL(Exit) .byte 0x73, 0x26 nop // padding for alignment of constant @@ -203,10 +203,10 @@ LEAF_ENTRY JIT_WriteBarrier, _TEXT shr rdi, 0Bh cmp byte ptr [rdi + rax], 0FFh .byte 0x75, 0x02 - // jne UpdateCardTable + // jne LOCAL_LABEL(UpdateCardTable) REPRET - UpdateCardTable: + LOCAL_LABEL(UpdateCardTable): mov byte ptr [rdi + rax], 0FFh #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES @@ -220,17 +220,17 @@ LEAF_ENTRY JIT_WriteBarrier, _TEXT cmp byte ptr [rdi + rax], 0FFh .byte 0x75, 0x02 - // jne UpdateCardBundle + // jne LOCAL_LABEL(UpdateCardBundle) REPRET - UpdateCardBundle: + LOCAL_LABEL(UpdateCardBundle): mov byte ptr [rdi + rax], 0FFh #endif ret .balign 16 - Exit: + LOCAL_LABEL(Exit): REPRET #endif @@ -277,30 +277,30 @@ LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT // See if this is in GCHeap PREPARE_EXTERNAL_VAR g_lowest_address, rax cmp rdi, [rax] - jb NotInHeap_ByRefWriteBarrier + jb LOCAL_LABEL(NotInHeap_ByRefWriteBarrier) PREPARE_EXTERNAL_VAR g_highest_address, rax cmp rdi, [rax] - jnb NotInHeap_ByRefWriteBarrier + jnb LOCAL_LABEL(NotInHeap_ByRefWriteBarrier) #ifdef WRITE_BARRIER_CHECK // **ALSO update the shadow GC heap if that is enabled** // Do not perform the work if g_GCShadow is 0 PREPARE_EXTERNAL_VAR g_GCShadow, rax cmp qword ptr [rax], 0 - je NoShadow_ByRefWriteBarrier + je LOCAL_LABEL(NoShadow_ByRefWriteBarrier) // If we end up outside of the heap don't corrupt random memory mov r10, rdi PREPARE_EXTERNAL_VAR g_lowest_address, rax sub r10, [rax] - jb NoShadow_ByRefWriteBarrier + jb LOCAL_LABEL(NoShadow_ByRefWriteBarrier) // Check that our adjusted destination is somewhere in the shadow gc PREPARE_EXTERNAL_VAR g_GCShadow, rax add r10, [rax] PREPARE_EXTERNAL_VAR g_GCShadowEnd, rax cmp r10, [rax] - jnb NoShadow_ByRefWriteBarrier + jnb LOCAL_LABEL(NoShadow_ByRefWriteBarrier) // Write ref into real GC mov [rdi], rcx @@ -315,73 +315,73 @@ LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT mov r11, [rdi] mov rax, [r10] cmp rax, r11 - je DoneShadow_ByRefWriteBarrier + je LOCAL_LABEL(DoneShadow_ByRefWriteBarrier) movabs r11, INVALIDGCVALUE mov [r10], r11 - jmp DoneShadow_ByRefWriteBarrier + jmp LOCAL_LABEL(DoneShadow_ByRefWriteBarrier) // If we don't have a shadow GC we won't have done the write yet - NoShadow_ByRefWriteBarrier: + LOCAL_LABEL(NoShadow_ByRefWriteBarrier): mov [rdi], rcx // If we had a shadow GC then we already wrote to the real GC at the same time // as the shadow GC so we want to jump over the real write immediately above. // Additionally we know for sure that we are inside the heap and therefore don't // need to replicate the above checks. - DoneShadow_ByRefWriteBarrier: + LOCAL_LABEL(DoneShadow_ByRefWriteBarrier): #endif #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP // Update the write watch table if necessary PREPARE_EXTERNAL_VAR g_sw_ww_enabled_for_gc_heap, rax cmp byte ptr [rax], 0x0 - je CheckCardTable_ByRefWriteBarrier + je LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier) mov rax, rdi shr rax, 0xC // SoftwareWriteWatch::AddressToTableByteIndexShift PREPARE_EXTERNAL_VAR g_sw_ww_table, r10 add rax, qword ptr [r10] cmp byte ptr [rax], 0x0 - jne CheckCardTable_ByRefWriteBarrier + jne LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier) mov byte ptr [rax], 0xFF #endif - CheckCardTable_ByRefWriteBarrier: + LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier): // See if we can just quick out PREPARE_EXTERNAL_VAR g_ephemeral_low, rax cmp rcx, [rax] - jb Exit_ByRefWriteBarrier + jb LOCAL_LABEL(Exit_ByRefWriteBarrier) PREPARE_EXTERNAL_VAR g_ephemeral_high, rax cmp rcx, [rax] - jnb Exit_ByRefWriteBarrier + jnb LOCAL_LABEL(Exit_ByRefWriteBarrier) mov rax, rcx PREPARE_EXTERNAL_VAR g_region_shr, rcx mov cl, [rcx] test cl, cl - je SkipCheck_ByRefWriteBarrier + je LOCAL_LABEL(SkipCheck_ByRefWriteBarrier) // check if the source is in gen 2 - then it's not an ephemeral pointer shr rax, cl PREPARE_EXTERNAL_VAR g_region_to_generation_table, r10 mov r10, [r10] cmp byte ptr [rax + r10], 0x82 - je Exit_ByRefWriteBarrier + je LOCAL_LABEL(Exit_ByRefWriteBarrier) // check if the destination happens to be in gen 0 mov rax, rdi shr rax, cl cmp byte ptr [rax + r10], 0 - je Exit_ByRefWriteBarrier - SkipCheck_ByRefWriteBarrier: + je LOCAL_LABEL(Exit_ByRefWriteBarrier) + LOCAL_LABEL(SkipCheck_ByRefWriteBarrier): PREPARE_EXTERNAL_VAR g_card_table, r10 mov r10, [r10] PREPARE_EXTERNAL_VAR g_region_use_bitwise_write_barrier, rax cmp byte ptr [rax], 0 - je CheckCardTableByte_ByRefWriteBarrier + je LOCAL_LABEL(CheckCardTableByte_ByRefWriteBarrier) // compute card table bit mov ecx, edi @@ -400,15 +400,15 @@ LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT shr rcx, 0xB // Check if this card table bit is already set test byte ptr [rcx + r10], al - je SetCardTableBit_ByRefWriteBarrier + je LOCAL_LABEL(SetCardTableBit_ByRefWriteBarrier) REPRET - SetCardTableBit_ByRefWriteBarrier: + LOCAL_LABEL(SetCardTableBit_ByRefWriteBarrier): lock or byte ptr [rcx + r10], al - jmp CheckCardBundle_ByRefWriteBarrier + jmp LOCAL_LABEL(CheckCardBundle_ByRefWriteBarrier) - CheckCardTableByte_ByRefWriteBarrier: + LOCAL_LABEL(CheckCardTableByte_ByRefWriteBarrier): // move current rdi value into rcx and then increment the pointers mov rcx, rdi add rsi, 0x8 @@ -416,12 +416,12 @@ LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT shr rcx, 0xB cmp byte ptr [rcx + r10], 0xFF - jne SetCardTableByte_ByRefWriteBarrier + jne LOCAL_LABEL(SetCardTableByte_ByRefWriteBarrier) REPRET - SetCardTableByte_ByRefWriteBarrier: + LOCAL_LABEL(SetCardTableByte_ByRefWriteBarrier): mov byte ptr [rcx + r10], 0xFF - CheckCardBundle_ByRefWriteBarrier: + LOCAL_LABEL(CheckCardBundle_ByRefWriteBarrier): #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES // Shift rcx by 0x0A more to get the card bundle byte (we shifted by 0x0B already) @@ -433,17 +433,17 @@ LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT // Check if this bundle byte is dirty cmp byte ptr [rcx], 0xFF - jne UpdateCardBundle_ByRefWriteBarrier + jne LOCAL_LABEL(UpdateCardBundle_ByRefWriteBarrier) REPRET - UpdateCardBundle_ByRefWriteBarrier: + LOCAL_LABEL(UpdateCardBundle_ByRefWriteBarrier): mov byte ptr [rcx], 0xFF #endif ret .balign 16 - NotInHeap_ByRefWriteBarrier: + LOCAL_LABEL(NotInHeap_ByRefWriteBarrier): // If WRITE_BARRIER_CHECK then we won't have already done the mov and should do it here // If !WRITE_BARRIER_CHECK we want _NotInHeap and _Leave to be the same and have both // 16 byte aligned. @@ -451,7 +451,7 @@ LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT // rcx is [rsi] mov [rdi], rcx #endif - Exit_ByRefWriteBarrier: + LOCAL_LABEL(Exit_ByRefWriteBarrier): // Increment the pointers before leaving add rdi, 0x8 add rsi, 0x8 diff --git a/src/tests/issues.targets b/src/tests/issues.targets index bdccec81ac1f49..b867b9134b5732 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -72,8 +72,8 @@ https://github.com/dotnet/runtime/issues/78899 - - https://github.com/dotnet/runtime/issues/89585 + + https://github.com/dotnet/runtime/issues/88586 From 562a16a22b79b9eaf15377f1a7c2d7b8a2339656 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 25 Aug 2023 15:09:46 -0700 Subject: [PATCH 078/783] [release/8.0] Fix calling existing ctor with MethodInvoker; share tests with invokers (#90968) * Fix calling existing ctor with MethodInvoker; share tests with invokers * Remove unnecessary semicolon (non functional) --------- Co-authored-by: Steve Harter --- .../System/Reflection/ConstructorInvoker.cs | 2 +- .../src/System/Reflection/MethodInvoker.cs | 9 +- .../System/Reflection/MethodInvokerCommon.cs | 19 +- .../tests/ConstructorCommonTests.cs | 167 ++++++++++ .../tests/ConstructorInfoTests.cs | 169 ++-------- .../tests/ConstructorInvokerTests.cs | 30 +- .../System.Reflection.InvokeEmit.Tests.csproj | 4 + ....Reflection.InvokeInterpreted.Tests.csproj | 4 + .../tests/MethodCommonTests.cs | 297 ++++++++++++++++++ .../tests/MethodInfoTests.cs | 292 +---------------- .../tests/MethodInvokerTests.cs | 18 +- .../tests/System.Reflection.Tests.csproj | 14 +- 12 files changed, 574 insertions(+), 451 deletions(-) create mode 100644 src/libraries/System.Reflection/tests/ConstructorCommonTests.cs create mode 100644 src/libraries/System.Reflection/tests/MethodCommonTests.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs index 7f3c1a227e3718..3fad9dc8dba85f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs @@ -155,7 +155,7 @@ public object Invoke(object? arg1, object? arg2, object? arg3, object? arg4) private object InvokeImpl(object? arg1, object? arg2, object? arg3, object? arg4) { - if ((_invocationFlags & (InvocationFlags.NoInvoke | InvocationFlags.ContainsStackPointers)) != 0) + if ((_invocationFlags & (InvocationFlags.NoInvoke | InvocationFlags.ContainsStackPointers | InvocationFlags.NoConstructorInvoke)) != 0) { _method.ThrowNoInvokeException(); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs index 66a35dbd39c74b..0c8d9c59580703 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs @@ -66,7 +66,12 @@ public static MethodInvoker Create(MethodBase method) { // This is useful for calling a constructor on an already-initialized object // such as created from RuntimeHelpers.GetUninitializedObject(Type). - return new MethodInvoker(rci); + MethodInvoker invoker = new MethodInvoker(rci); + + // Use the interpreted version to avoid having to generate a new method that doesn't allocate. + invoker._strategy = GetStrategyForUsingInterpreted(); + + return invoker; } throw new ArgumentException(SR.Argument_MustBeRuntimeMethod, nameof(method)); @@ -181,7 +186,7 @@ private MethodInvoker(MethodBase method, RuntimeType[] argumentTypes) private object? InvokeImpl(object? obj, object? arg1, object? arg2, object? arg3, object? arg4) { - if ((_invocationFlags & (InvocationFlags.NoInvoke | InvocationFlags.ContainsStackPointers)) != 0) + if ((_invocationFlags & (InvocationFlags.NoInvoke | InvocationFlags.ContainsStackPointers | InvocationFlags.NoConstructorInvoke)) != 0) { ThrowForBadInvocationFlags(); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvokerCommon.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvokerCommon.cs index 191228b688faa1..813e89f80f8349 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvokerCommon.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvokerCommon.cs @@ -18,13 +18,14 @@ internal static void Initialize( { if (LocalAppContextSwitches.ForceInterpretedInvoke && !LocalAppContextSwitches.ForceEmitInvoke) { - // Always use the native invoke; useful for testing. - strategy = InvokerStrategy.StrategyDetermined_Obj4Args | InvokerStrategy.StrategyDetermined_ObjSpanArgs | InvokerStrategy.StrategyDetermined_RefArgs; + // Always use the native interpreted invoke. + // Useful for testing, to avoid startup overhead of emit, or for calling a ctor on already initialized object. + strategy = GetStrategyForUsingInterpreted(); } else if (LocalAppContextSwitches.ForceEmitInvoke && !LocalAppContextSwitches.ForceInterpretedInvoke) { // Always use emit invoke (if IsDynamicCodeSupported == true); useful for testing. - strategy = InvokerStrategy.HasBeenInvoked_Obj4Args | InvokerStrategy.HasBeenInvoked_ObjSpanArgs | InvokerStrategy.HasBeenInvoked_RefArgs; + strategy = GetStrategyForUsingEmit(); } else { @@ -69,6 +70,18 @@ internal static void Initialize( } } + internal static InvokerStrategy GetStrategyForUsingInterpreted() + { + // This causes the default strategy, which is interpreted, to always be used. + return InvokerStrategy.StrategyDetermined_Obj4Args | InvokerStrategy.StrategyDetermined_ObjSpanArgs | InvokerStrategy.StrategyDetermined_RefArgs; + } + + private static InvokerStrategy GetStrategyForUsingEmit() + { + // This causes the emit strategy, if supported, to be used on the first call as well as subsequent calls. + return InvokerStrategy.HasBeenInvoked_Obj4Args | InvokerStrategy.HasBeenInvoked_ObjSpanArgs | InvokerStrategy.HasBeenInvoked_RefArgs; + } + /// /// Confirm member invocation has an instance and is of the correct type /// diff --git a/src/libraries/System.Reflection/tests/ConstructorCommonTests.cs b/src/libraries/System.Reflection/tests/ConstructorCommonTests.cs new file mode 100644 index 00000000000000..5c71f79da014c1 --- /dev/null +++ b/src/libraries/System.Reflection/tests/ConstructorCommonTests.cs @@ -0,0 +1,167 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Linq; +using Xunit; + +namespace System.Reflection.Tests +{ + /// + /// These tests are shared with ConstructorInfo.Invoke and ConstructorInvoker.Invoke by using + /// the abstract Invoke(...) methods below. + /// + public abstract class ConstructorCommonTests + { + public abstract object Invoke(ConstructorInfo constructorInfo, object?[]? parameters); + + protected abstract bool IsExceptionWrapped { get; } + + /// + /// Invoke constructor on an existing instance. Should return null. + /// + public abstract object? Invoke(ConstructorInfo constructorInfo, object obj, object?[]? parameters); + + public static ConstructorInfo[] GetConstructors(Type type) + { + return type.GetTypeInfo().DeclaredConstructors.ToArray(); + } + + [Fact] + public void SimpleInvoke() + { + ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); + Assert.Equal(3, constructors.Length); + ClassWith3Constructors obj = (ClassWith3Constructors)Invoke(constructors[0], null); + Assert.NotNull(obj); + } + + [Fact] + [ActiveIssue("https://github.com/mono/mono/issues/15024", TestRuntimes.Mono)] + public void Invoke_StaticConstructor_ThrowsMemberAccessException() + { + ConstructorInfo[] constructors = GetConstructors(typeof(ClassWithStaticConstructor)); + Assert.Equal(1, constructors.Length); + Assert.Throws(() => Invoke(constructors[0], new object[0])); + } + + [Fact] + public void Invoke_OneDimensionalArray() + { + ConstructorInfo[] constructors = GetConstructors(typeof(object[])); + int[] arraylength = { 1, 2, 99, 65535 }; + + // Try to invoke Array ctors with different lengths + foreach (int length in arraylength) + { + // Create big Array with elements + object[] arr = (object[])Invoke(constructors[0], new object[] { length }); + Assert.Equal(arr.Length, length); + } + } + + [Fact] + public void Invoke_OneDimensionalArray_NegativeLengths_ThrowsOverflowException() + { + ConstructorInfo[] constructors = GetConstructors(typeof(object[])); + int[] arraylength = new int[] { -1, -2, -99 }; + // Try to invoke Array ctors with different lengths + foreach (int length in arraylength) + { + // Create big Array with elements + if (IsExceptionWrapped) + { + Exception ex = Assert.Throws(() => Invoke(constructors[0], new object[] { length })); + Assert.IsType(ex.InnerException); + } + else + { + Assert.Throws(() => Invoke(constructors[0], new object[] { length })); + } + } + } + + [Fact] + public void Invoke_OneParameter() + { + ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); + ClassWith3Constructors obj = (ClassWith3Constructors)Invoke(constructors[1], new object[] { 100 }); + Assert.Equal(100, obj.intValue); + } + + [Fact] + public void Invoke_TwoParameters() + { + ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); + ClassWith3Constructors obj = (ClassWith3Constructors)Invoke(constructors[2], new object[] { 101, "hello" }); + Assert.Equal(101, obj.intValue); + Assert.Equal("hello", obj.stringValue); + } + + [Fact] + public void Invoke_NoParameters_ThowsTargetParameterCountException() + { + ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); + Assert.Throws(() => Invoke(constructors[2], new object[0])); + } + + [Fact] + public void Invoke_ParameterMismatch_ThrowsTargetParameterCountException() + { + ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); + Assert.Throws(() => (ClassWith3Constructors)Invoke(constructors[2], new object[] { 121 })); + } + + [Fact] + public void Invoke_ParameterWrongType_ThrowsArgumentException() + { + ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); + AssertExtensions.Throws(null, () => (ClassWith3Constructors)Invoke(constructors[1], new object[] { "hello" })); + } + + [Fact] + public void Invoke_ExistingInstance() + { + // Should not produce a second object. + ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); + ClassWith3Constructors obj1 = new ClassWith3Constructors(100, "hello"); + ClassWith3Constructors obj2 = (ClassWith3Constructors)Invoke(constructors[2], obj1, new object[] { 999, "initialized" }); + Assert.Null(obj2); + Assert.Equal(999, obj1.intValue); + Assert.Equal("initialized", obj1.stringValue); + } + + [Fact] + public void Invoke_NullForObj() + { + ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); + Assert.Throws(() => Invoke(constructors[2], obj: null, new object[] { 999, "initialized" })); + } + + [Fact] + [ActiveIssue("https://github.com/mono/mono/issues/15026", TestRuntimes.Mono)] + public void Invoke_AbstractClass_ThrowsMemberAccessException() + { + ConstructorInfo[] constructors = GetConstructors(typeof(ConstructorInfoAbstractBase)); + Assert.Throws(() => (ConstructorInfoAbstractBase)Invoke(constructors[0], new object[0])); + } + + [Fact] + public void Invoke_SubClass() + { + ConstructorInfo[] constructors = GetConstructors(typeof(ConstructorInfoDerived)); + ConstructorInfoDerived obj = null; + obj = (ConstructorInfoDerived)Invoke(constructors[0], new object[] { }); + Assert.NotNull(obj); + } + + [Fact] + public void Invoke_Struct() + { + ConstructorInfo[] constructors = GetConstructors(typeof(StructWith1Constructor)); + StructWith1Constructor obj; + obj = (StructWith1Constructor)Invoke(constructors[0], new object[] { 1, 2 }); + Assert.Equal(1, obj.x); + Assert.Equal(2, obj.y); + } + } +} diff --git a/src/libraries/System.Reflection/tests/ConstructorInfoTests.cs b/src/libraries/System.Reflection/tests/ConstructorInfoTests.cs index 34d04906a8055b..37498347ac48fe 100644 --- a/src/libraries/System.Reflection/tests/ConstructorInfoTests.cs +++ b/src/libraries/System.Reflection/tests/ConstructorInfoTests.cs @@ -2,15 +2,29 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Linq; using Xunit; #pragma warning disable 0414 namespace System.Reflection.Tests { - public class ConstructorInfoTests + /// + /// These tests use the shared tests from the base class with ConstructorInfo.Invoke. + /// + public sealed class ConstructorInfoTests : ConstructorCommonTests { + public override object Invoke(ConstructorInfo constructorInfo, object?[]? parameters) + { + return constructorInfo.Invoke(parameters); + } + + public override object? Invoke(ConstructorInfo constructorInfo, object obj, object?[]? parameters) + { + return constructorInfo.Invoke(obj, parameters); + } + + protected override bool IsExceptionWrapped => true; + [Fact] public void ConstructorName() { @@ -50,15 +64,6 @@ public void GetHashCodeTest() } } - [Fact] - public void Invoke() - { - ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); - Assert.Equal(3, constructors.Length); - ClassWith3Constructors obj = (ClassWith3Constructors)constructors[0].Invoke(null); - Assert.NotNull(obj); - } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsInvokingStaticConstructorsSupported))] public void Invoke_StaticConstructor_NullObject_NullParameters() { @@ -88,44 +93,6 @@ public void Invoke_StaticConstructorMultipleTimes() Assert.Equal(1, ClassWithStaticConstructorThatIsCalledMultipleTimesViaReflection.VisibleStatics.s_cctorCallCount); } - [Fact] - [ActiveIssue("https://github.com/mono/mono/issues/15024", TestRuntimes.Mono)] - public void Invoke_StaticConstructor_ThrowsMemberAccessException() - { - ConstructorInfo[] constructors = GetConstructors(typeof(ClassWithStaticConstructor)); - Assert.Equal(1, constructors.Length); - Assert.Throws(() => constructors[0].Invoke(new object[0])); - } - - [Fact] - public void Invoke_OneDimensionalArray() - { - ConstructorInfo[] constructors = GetConstructors(typeof(object[])); - int[] arraylength = { 1, 2, 99, 65535 }; - - // Try to invoke Array ctors with different lengths - foreach (int length in arraylength) - { - // Create big Array with elements - object[] arr = (object[])constructors[0].Invoke(new object[] { length }); - Assert.Equal(arr.Length, length); - } - } - - [Fact] - public void Invoke_OneDimensionalArray_NegativeLengths_ThrowsOverflowException() - { - ConstructorInfo[] constructors = GetConstructors(typeof(object[])); - int[] arraylength = new int[] { -1, -2, -99 }; - // Try to invoke Array ctors with different lengths - foreach (int length in arraylength) - { - // Create big Array with elements - Exception ex = Assert.Throws(() => constructors[0].Invoke(new object[] { length })); - Assert.IsType(ex.InnerException); - } - } - [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/67531", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public void Invoke_TwoDimensionalArray_CustomBinder_IncorrectTypeArguments() @@ -138,23 +105,6 @@ public void Invoke_TwoDimensionalArray_CustomBinder_IncorrectTypeArguments() Assert.True(args[1] is int); } - [Fact] - public void Invoke_OneParameter() - { - ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); - ClassWith3Constructors obj = (ClassWith3Constructors)constructors[1].Invoke(new object[] { 100 }); - Assert.Equal(100, obj.intValue); - } - - [Fact] - public void Invoke_TwoParameters() - { - ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); - ClassWith3Constructors obj = (ClassWith3Constructors)constructors[2].Invoke(new object[] { 101, "hello" }); - Assert.Equal(101, obj.intValue); - Assert.Equal("hello", obj.stringValue); - } - [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/67531", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public void Invoke_TwoParameters_CustomBinder_IncorrectTypeArgument() @@ -169,66 +119,6 @@ public void Invoke_TwoParameters_CustomBinder_IncorrectTypeArgument() Assert.True(args[1] is string); } - [Fact] - public void Invoke_NoParameters_ThowsTargetParameterCountException() - { - ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); - Assert.Throws(() => constructors[2].Invoke(new object[0])); - } - - [Fact] - public void Invoke_ParameterMismatch_ThrowsTargetParameterCountException() - { - ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); - Assert.Throws(() => (ClassWith3Constructors)constructors[2].Invoke(new object[] { 121 })); - } - - [Fact] - public void Invoke_ParameterWrongType_ThrowsArgumentException() - { - ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); - AssertExtensions.Throws(null, () => (ClassWith3Constructors)constructors[1].Invoke(new object[] { "hello" })); - } - - [Fact] - public void Invoke_ExistingInstance() - { - // Should not produce a second object. - ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); - ClassWith3Constructors obj1 = new ClassWith3Constructors(100, "hello"); - ClassWith3Constructors obj2 = (ClassWith3Constructors)constructors[2].Invoke(obj1, new object[] { 999, "initialized" }); - Assert.Null(obj2); - Assert.Equal(999, obj1.intValue); - Assert.Equal("initialized", obj1.stringValue); - } - - [Fact] - [ActiveIssue("https://github.com/mono/mono/issues/15026", TestRuntimes.Mono)] - public void Invoke_AbstractClass_ThrowsMemberAccessException() - { - ConstructorInfo[] constructors = GetConstructors(typeof(ConstructorInfoAbstractBase)); - Assert.Throws(() => (ConstructorInfoAbstractBase)constructors[0].Invoke(new object[0])); - } - - [Fact] - public void Invoke_SubClass() - { - ConstructorInfo[] constructors = GetConstructors(typeof(ConstructorInfoDerived)); - ConstructorInfoDerived obj = null; - obj = (ConstructorInfoDerived)constructors[0].Invoke(new object[] { }); - Assert.NotNull(obj); - } - - [Fact] - public void Invoke_Struct() - { - ConstructorInfo[] constructors = GetConstructors(typeof(StructWith1Constructor)); - StructWith1Constructor obj; - obj = (StructWith1Constructor)constructors[0].Invoke(new object[] { 1, 2 }); - Assert.Equal(1, obj.x); - Assert.Equal(2, obj.y); - } - [Fact] public void IsConstructor_ReturnsTrue() { @@ -243,9 +133,18 @@ public void IsPublic() Assert.True(constructors[0].IsPublic); } - public static ConstructorInfo[] GetConstructors(Type type) + // Use this class only from the Invoke_StaticConstructorMultipleTimes method + public static class ClassWithStaticConstructorThatIsCalledMultipleTimesViaReflection { - return type.GetTypeInfo().DeclaredConstructors.ToArray(); + public static class VisibleStatics + { + public static int s_cctorCallCount; + } + + static ClassWithStaticConstructorThatIsCalledMultipleTimesViaReflection() + { + VisibleStatics.s_cctorCallCount++; + } } } @@ -281,20 +180,6 @@ public static class ClassWithStaticConstructor static ClassWithStaticConstructor() { } } - // Use this class only from the Invoke_StaticConstructorMultipleTimes method - public static class ClassWithStaticConstructorThatIsCalledMultipleTimesViaReflection - { - public static class VisibleStatics - { - public static int s_cctorCallCount; - } - - static ClassWithStaticConstructorThatIsCalledMultipleTimesViaReflection() - { - VisibleStatics.s_cctorCallCount++; - } - } - public struct StructWith1Constructor { public int x; diff --git a/src/libraries/System.Reflection/tests/ConstructorInvokerTests.cs b/src/libraries/System.Reflection/tests/ConstructorInvokerTests.cs index 86fa1c4012c270..f5313bde579844 100644 --- a/src/libraries/System.Reflection/tests/ConstructorInvokerTests.cs +++ b/src/libraries/System.Reflection/tests/ConstructorInvokerTests.cs @@ -1,13 +1,26 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.CompilerServices; using Xunit; namespace System.Reflection.Tests { - public class ConstructorInvokerTests + /// + /// These tests use the shared tests from the base class with ConstructorInvoker.Invoke. + /// + public sealed class ConstructorInvokerTests : ConstructorCommonTests { + public override object Invoke(ConstructorInfo constructorInfo, object?[]? parameters) + { + return ConstructorInvoker.Create(constructorInfo).Invoke(new Span(parameters)); + } + + public override object? Invoke(ConstructorInfo constructorInfo, object obj, object?[]? parameters) + { + return MethodInvoker.Create(constructorInfo).Invoke(obj, new Span(parameters)); + } + + protected override bool IsExceptionWrapped => false; [Fact] public void Args_0() @@ -162,16 +175,13 @@ public void ThrowsNonWrappedException_5() } [Fact] - public void ExistingInstance() + public void Invoke_StaticConstructor_NullObject_NullParameters() { - ConstructorInfo ci = typeof(TestClass).GetConstructor(BindingFlags.Public | BindingFlags.Instance, Type.EmptyTypes); - TestClass tc = (TestClass)RuntimeHelpers.GetUninitializedObject(typeof(TestClass)); - Assert.Null(tc._args); + ConstructorInfo[] constructors = GetConstructors(typeof(ClassWithStaticConstructor)); + Assert.Equal(1, constructors.Length); - MethodInvoker invoker = MethodInvoker.Create(ci); - object? obj = invoker.Invoke(tc); - Assert.Equal("0", tc._args); - Assert.Null(obj); + // Invoker classes do not support calling class constructors; use standard reflection for that. + Assert.Throws(() => Invoke(constructors[0], null, new object[] { })); } private class TestClass diff --git a/src/libraries/System.Reflection/tests/InvokeEmit/System.Reflection.InvokeEmit.Tests.csproj b/src/libraries/System.Reflection/tests/InvokeEmit/System.Reflection.InvokeEmit.Tests.csproj index 7b1e61038ccb5d..757b631140f2d6 100644 --- a/src/libraries/System.Reflection/tests/InvokeEmit/System.Reflection.InvokeEmit.Tests.csproj +++ b/src/libraries/System.Reflection/tests/InvokeEmit/System.Reflection.InvokeEmit.Tests.csproj @@ -7,8 +7,12 @@ + + + + diff --git a/src/libraries/System.Reflection/tests/InvokeInterpreted/System.Reflection.InvokeInterpreted.Tests.csproj b/src/libraries/System.Reflection/tests/InvokeInterpreted/System.Reflection.InvokeInterpreted.Tests.csproj index 64dc87d71c0864..5d71379e2d5ca9 100644 --- a/src/libraries/System.Reflection/tests/InvokeInterpreted/System.Reflection.InvokeInterpreted.Tests.csproj +++ b/src/libraries/System.Reflection/tests/InvokeInterpreted/System.Reflection.InvokeInterpreted.Tests.csproj @@ -7,8 +7,12 @@ + + + + diff --git a/src/libraries/System.Reflection/tests/MethodCommonTests.cs b/src/libraries/System.Reflection/tests/MethodCommonTests.cs new file mode 100644 index 00000000000000..b2e8e2f84fbc27 --- /dev/null +++ b/src/libraries/System.Reflection/tests/MethodCommonTests.cs @@ -0,0 +1,297 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Linq; +using Xunit; + +namespace System.Reflection.Tests +{ + /// + /// These tests are shared with MethodInfo.Invoke and MethodInvoker.Invoke by using + /// the abstract Invoke(...) method below. + /// + public abstract class MethodCommonTests + { + public abstract object? Invoke(MethodInfo methodInfo, object? obj, object?[]? parameters); + + protected abstract bool SupportsMissing { get; } + + protected static MethodInfo GetMethod(Type type, string name) + { + return type.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).First(method => method.Name.Equals(name)); + } + + [Fact] + public void InvokeNullableRefs() + { + object?[] args; + + int? iNull = null; + args = new object[] { iNull }; + Assert.True((bool)Invoke(GetMethod(nameof(NullableRefMethods.Null)), null, args)); + Assert.Null(args[0]); + Assert.False(((int?)args[0]).HasValue); + + args = new object[] { iNull }; + Assert.True((bool)Invoke(GetMethod(nameof(NullableRefMethods.NullBoxed)), null, args)); + Assert.Null(args[0]); + + args = new object[] { iNull, 10 }; + Assert.True((bool)Invoke(GetMethod(nameof(NullableRefMethods.NullToValue)), null, args)); + Assert.IsType(args[0]); + Assert.Equal(10, (int)args[0]); + + iNull = 42; + args = new object[] { iNull, 42 }; + Assert.True((bool)Invoke(GetMethod(nameof(NullableRefMethods.ValueToNull)), null, args)); + Assert.Null(args[0]); + + iNull = null; + args = new object[] { iNull, 10 }; + Assert.True((bool)Invoke(GetMethod(nameof(NullableRefMethods.NullToValueBoxed)), null, args)); + Assert.IsType(args[0]); + Assert.Equal(10, (int)args[0]); + + static MethodInfo GetMethod(string name) => typeof(NullableRefMethods).GetMethod( + name, BindingFlags.Public | BindingFlags.Static)!; + } + + [Fact] + public void InvokeBoxedNullableRefs() + { + object?[] args; + + object? iNull = null; + args = new object[] { iNull }; + Assert.True((bool)Invoke(GetMethod(nameof(NullableRefMethods.Null)), null, args)); + Assert.Null(args[0]); + + args = new object[] { iNull }; + Assert.True((bool)Invoke(GetMethod(nameof(NullableRefMethods.NullBoxed)), null, args)); + Assert.Null(args[0]); + + args = new object[] { iNull, 10 }; + Assert.True((bool)Invoke(GetMethod(nameof(NullableRefMethods.NullToValue)), null, args)); + Assert.IsType(args[0]); + Assert.Equal(10, (int)args[0]); + + iNull = 42; + args = new object[] { iNull, 42 }; + Assert.True((bool)Invoke(GetMethod(nameof(NullableRefMethods.ValueToNull)), null, args)); + Assert.Null(args[0]); + + iNull = null; + args = new object[] { iNull, 10 }; + Assert.True((bool)Invoke(GetMethod(nameof(NullableRefMethods.NullToValueBoxed)), null, args)); + Assert.IsType(args[0]); + Assert.Equal(10, (int)args[0]); + + static MethodInfo GetMethod(string name) => typeof(NullableRefMethods).GetMethod( + name, BindingFlags.Public | BindingFlags.Static)!; + } + + [Fact] + public void InvokeEnum() + { + // Enums only need to match by primitive type. + Assert.True((bool)GetMethod(nameof(EnumMethods.PassColorsInt)). + Invoke(null, new object[] { OtherColorsInt.Red })); + + // Widening allowed + Assert.True((bool)GetMethod(nameof(EnumMethods.PassColorsInt)). + Invoke(null, new object[] { ColorsShort.Red })); + + // Narrowing not allowed + Assert.Throws(() => GetMethod(nameof(EnumMethods.PassColorsShort)). + Invoke(null, new object[] { OtherColorsInt.Red })); + + static MethodInfo GetMethod(string name) => typeof(EnumMethods).GetMethod( + name, BindingFlags.Public | BindingFlags.Static)!; + } + + [Fact] + public void InvokeNullableEnumParameterDefaultNo() + { + MethodInfo method = typeof(EnumMethods).GetMethod("NullableEnumDefaultNo", BindingFlags.Static | BindingFlags.NonPublic); + + Assert.Null(Invoke(method, null, new object?[] { default(object) })); + Assert.Equal(YesNo.No, Invoke(method, null, new object?[] { YesNo.No })); + Assert.Equal(YesNo.Yes, Invoke(method, null, new object?[] { YesNo.Yes })); + + if (SupportsMissing) + { + Assert.Equal(YesNo.No, Invoke(method, null, new object?[] { Type.Missing })); + } + } + + [Fact] + public void InvokeNullableEnumParameterDefaultYes() + { + MethodInfo method = typeof(EnumMethods).GetMethod("NullableEnumDefaultYes", BindingFlags.Static | BindingFlags.NonPublic); + + Assert.Null(Invoke(method, null, new object?[] { default(object) })); + Assert.Equal(YesNo.No, Invoke(method, null, new object?[] { YesNo.No })); + Assert.Equal(YesNo.Yes, Invoke(method, null, new object?[] { YesNo.Yes })); + + if (SupportsMissing) + { + Assert.Equal(YesNo.Yes, Invoke(method, null, new object?[] { Type.Missing })); + } + } + + [Fact] + public void InvokeNonNullableEnumParameterDefaultYes() + { + MethodInfo method = typeof(EnumMethods).GetMethod("NonNullableEnumDefaultYes", BindingFlags.Static | BindingFlags.NonPublic); + + Assert.Equal(YesNo.No, Invoke(method, null, new object[] { default(object) })); + Assert.Equal(YesNo.No, Invoke(method, null, new object[] { YesNo.No })); + Assert.Equal(YesNo.Yes, Invoke(method, null, new object[] { YesNo.Yes })); + + if (SupportsMissing) + { + Assert.Equal(YesNo.Yes, Invoke(method, null, new object[] { Type.Missing })); + } + } + + [Fact] + public void InvokeNullableEnumParameterDefaultNull() + { + MethodInfo method = typeof(EnumMethods).GetMethod("NullableEnumDefaultNull", BindingFlags.Static | BindingFlags.NonPublic); + + Assert.Null(Invoke(method, null, new object?[] { default(object) })); + Assert.Equal(YesNo.No, Invoke(method, null, new object?[] { YesNo.No })); + Assert.Equal(YesNo.Yes, Invoke(method, null, new object?[] { YesNo.Yes })); + + if (SupportsMissing) + { + Assert.Null(Invoke(method, null, new object?[] { Type.Missing })); + } + } + + [Fact] + public void ValueTypeMembers_WithOverrides() + { + ValueTypeWithOverrides obj = new() { Id = 1 }; + + // ToString is overridden. + Assert.Equal("Hello", (string)Invoke(GetMethod(typeof(ValueTypeWithOverrides), nameof(ValueTypeWithOverrides.ToString)), + obj, null)); + + // Ensure a normal method works. + Assert.Equal(1, (int)Invoke(GetMethod(typeof(ValueTypeWithOverrides), nameof(ValueTypeWithOverrides.GetId)), + obj, null)); + } + + [Fact] + public void ValueTypeMembers_WithoutOverrides() + { + ValueTypeWithoutOverrides obj = new() { Id = 1 }; + + // ToString is not overridden. + Assert.Equal(typeof(ValueTypeWithoutOverrides).ToString(), (string) Invoke(GetMethod(typeof(ValueTypeWithoutOverrides), nameof(ValueTypeWithoutOverrides.ToString)), + obj, null)); + + // Ensure a normal method works. + Assert.Equal(1, (int)Invoke(GetMethod(typeof(ValueTypeWithoutOverrides), nameof(ValueTypeWithoutOverrides.GetId)), + obj, null)); + } + + [Fact] + public void NullableOfTMembers() + { + // Ensure calling a method on Nullable works. + MethodInfo mi = GetMethod(typeof(int?), nameof(Nullable.GetValueOrDefault)); + Assert.Equal(42, Invoke(mi, 42, null)); + } + + [Fact] + public void CopyBackWithByRefArgs() + { + object i = 42; + object[] args = new object[] { i }; + Invoke(GetMethod(typeof(CopyBackMethods), nameof(CopyBackMethods.IncrementByRef)), null, args); + Assert.Equal(43, (int)args[0]); + Assert.NotSame(i, args[0]); // A copy should be made; a boxed instance should never be directly updated. + + i = 42; + args = new object[] { i }; + Invoke(GetMethod(typeof(CopyBackMethods), nameof(CopyBackMethods.IncrementByNullableRef)), null, args); + Assert.Equal(43, (int)args[0]); + Assert.NotSame(i, args[0]); + + object o = null; + args = new object[] { o }; + Invoke(GetMethod(typeof(CopyBackMethods), nameof(CopyBackMethods.SetToNonNullByRef)), null, args); + Assert.NotNull(args[0]); + + o = new object(); + args = new object[] { o }; + Invoke(GetMethod(typeof(CopyBackMethods), nameof(CopyBackMethods.SetToNullByRef)), null, args); + Assert.Null(args[0]); + } + + [Fact] + public unsafe void TestFunctionPointerDirect() + { + // Sanity checks for direct invocation. + void* fn = FunctionPointerMethods.GetFunctionPointer(); + Assert.True(FunctionPointerMethods.GetFunctionPointer()(42)); + Assert.True(FunctionPointerMethods.CallFcnPtr_IntPtr((IntPtr)fn, 42)); + Assert.True(FunctionPointerMethods.CallFcnPtr_Void(fn, 42)); + Assert.False(FunctionPointerMethods.GetFunctionPointer()(41)); + Assert.False(FunctionPointerMethods.CallFcnPtr_IntPtr((IntPtr)fn, 41)); + Assert.False(FunctionPointerMethods.CallFcnPtr_Void(fn, 41)); + } + + [Fact] + public unsafe void TestFunctionPointerAsIntPtrArgType() + { + void* fn = FunctionPointerMethods.GetFunctionPointer(); + + MethodInfo m; + + m = GetMethod(typeof(FunctionPointerMethods), nameof(FunctionPointerMethods.CallFcnPtr_IntPtr)); + Assert.True((bool)Invoke(m, null, new object[] { (IntPtr)fn, 42 })); + Assert.False((bool)Invoke(m, null, new object[] { (IntPtr)fn, 41 })); + + m = GetMethod(typeof(FunctionPointerMethods), nameof(FunctionPointerMethods.CallFcnPtr_Void)); + Assert.True((bool)Invoke(m, null, new object[] { (IntPtr)fn, 42 })); + Assert.False((bool)Invoke(m, null, new object[] { (IntPtr)fn, 41 })); + } + + [Fact] + public unsafe void TestFunctionPointerAsUIntPtrArgType() + { + void* fn = FunctionPointerMethods.GetFunctionPointer(); + + MethodInfo m; + + m = GetMethod(typeof(FunctionPointerMethods), nameof(FunctionPointerMethods.CallFcnPtr_UIntPtr)); + Assert.True((bool)Invoke(m, null, new object[] { (UIntPtr)fn, 42 })); + Assert.False((bool)Invoke(m, null, new object[] { (UIntPtr)fn, 41 })); + + m = GetMethod(typeof(FunctionPointerMethods), nameof(FunctionPointerMethods.CallFcnPtr_Void)); + Assert.True((bool)Invoke(m, null, new object[] { (UIntPtr)fn, 42 })); + Assert.False((bool)Invoke(m, null, new object[] { (UIntPtr)fn, 41 })); + } + + [Fact] + public unsafe void TestFunctionPointerAsArgType() + { + void* fn = FunctionPointerMethods.GetFunctionPointer(); + MethodInfo m = GetMethod(typeof(FunctionPointerMethods), nameof(FunctionPointerMethods.CallFcnPtr_FP)); + Assert.True((bool)Invoke(m, null, new object[] { (IntPtr)fn, 42 })); + Assert.False((bool)Invoke(m, null, new object[] { (IntPtr)fn, 41 })); + } + + [Fact] + public unsafe void TestFunctionPointerAsReturnType() + { + MethodInfo m = GetMethod(typeof(FunctionPointerMethods), nameof(FunctionPointerMethods.GetFunctionPointer)); + object ret = Invoke(m, null, null); + Assert.IsType(ret); + Assert.True((IntPtr)ret != 0); + } + } +} diff --git a/src/libraries/System.Reflection/tests/MethodInfoTests.cs b/src/libraries/System.Reflection/tests/MethodInfoTests.cs index 769fc94266a083..341fb7fcb9de11 100644 --- a/src/libraries/System.Reflection/tests/MethodInfoTests.cs +++ b/src/libraries/System.Reflection/tests/MethodInfoTests.cs @@ -6,12 +6,21 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Xunit; -using Xunit.Sdk; namespace System.Reflection.Tests { - public class MethodInfoTests + /// + /// These tests use the shared tests from the base class with MethodInfo.Invoke. + /// + public sealed class MethodInfoTests : MethodCommonTests { + public override object? Invoke(MethodInfo methodInfo, object? obj, object?[]? parameters) + { + return methodInfo.Invoke(obj, parameters); + } + + protected override bool SupportsMissing => false; + [Fact] public void CreateDelegate_PublicMethod() { @@ -361,7 +370,7 @@ public static IEnumerable Invoke_TestData() [Theory] [MemberData(nameof(Invoke_TestData))] - public void Invoke(Type methodDeclaringType, string methodName, object obj, object[] parameters, object result) + public void InvokeWithTestData(Type methodDeclaringType, string methodName, object obj, object[] parameters, object result) { MethodInfo method = GetMethod(methodDeclaringType, methodName); Assert.Equal(result, method.Invoke(obj, parameters)); @@ -370,8 +379,8 @@ public void Invoke(Type methodDeclaringType, string methodName, object obj, obje [Fact] public void Invoke_ParameterSpecification_ArrayOfMissing() { - Invoke(typeof(MethodInfoDefaultParameters), "OptionalObjectParameter", new MethodInfoDefaultParameters(), new object[] { Type.Missing }, Type.Missing); - Invoke(typeof(MethodInfoDefaultParameters), "OptionalObjectParameter", new MethodInfoDefaultParameters(), new Missing[] { Missing.Value }, Missing.Value); + InvokeWithTestData(typeof(MethodInfoDefaultParameters), "OptionalObjectParameter", new MethodInfoDefaultParameters(), new object[] { Type.Missing }, Type.Missing); + InvokeWithTestData(typeof(MethodInfoDefaultParameters), "OptionalObjectParameter", new MethodInfoDefaultParameters(), new Missing[] { Missing.Value }, Missing.Value); } [Fact] @@ -620,149 +629,6 @@ public void ToStringTest_ByMethodInfo(MethodInfo methodInfo, string expected) Assert.Equal(expected, methodInfo.ToString()); } - [Fact] - public void InvokeNullableRefs() - { - object?[] args; - - int? iNull = null; - args = new object[] { iNull }; - Assert.True((bool)GetMethod(nameof(NullableRefMethods.Null)).Invoke(null, args)); - Assert.Null(args[0]); - Assert.False(((int?)args[0]).HasValue); - - args = new object[] { iNull }; - Assert.True((bool)GetMethod(nameof(NullableRefMethods.NullBoxed)).Invoke(null, args)); - Assert.Null(args[0]); - - args = new object[] { iNull, 10 }; - Assert.True((bool)GetMethod(nameof(NullableRefMethods.NullToValue)).Invoke(null, args)); - Assert.IsType(args[0]); - Assert.Equal(10, (int)args[0]); - - iNull = 42; - args = new object[] { iNull, 42 }; - Assert.True((bool)GetMethod(nameof(NullableRefMethods.ValueToNull)).Invoke(null, args)); - Assert.Null(args[0]); - - iNull = null; - args = new object[] { iNull, 10 }; - Assert.True((bool)GetMethod(nameof(NullableRefMethods.NullToValueBoxed)).Invoke(null, args)); - Assert.IsType(args[0]); - Assert.Equal(10, (int)args[0]); - - static MethodInfo GetMethod(string name) => typeof(NullableRefMethods).GetMethod( - name, BindingFlags.Public | BindingFlags.Static)!; - } - - [Fact] - public void InvokeBoxedNullableRefs() - { - object?[] args; - - object? iNull = null; - args = new object[] { iNull }; - Assert.True((bool)GetMethod(nameof(NullableRefMethods.Null)).Invoke(null, args)); - Assert.Null(args[0]); - - args = new object[] { iNull }; - Assert.True((bool)GetMethod(nameof(NullableRefMethods.NullBoxed)).Invoke(null, args)); - Assert.Null(args[0]); - - args = new object[] { iNull, 10 }; - Assert.True((bool)GetMethod(nameof(NullableRefMethods.NullToValue)).Invoke(null, args)); - Assert.IsType(args[0]); - Assert.Equal(10, (int)args[0]); - - iNull = 42; - args = new object[] { iNull, 42 }; - Assert.True((bool)GetMethod(nameof(NullableRefMethods.ValueToNull)).Invoke(null, args)); - Assert.Null(args[0]); - - iNull = null; - args = new object[] { iNull, 10 }; - Assert.True((bool)GetMethod(nameof(NullableRefMethods.NullToValueBoxed)).Invoke(null, args)); - Assert.IsType(args[0]); - Assert.Equal(10, (int)args[0]); - - static MethodInfo GetMethod(string name) => typeof(NullableRefMethods).GetMethod( - name, BindingFlags.Public | BindingFlags.Static)!; - } - - [Fact] - public void InvokeEnum() - { - // Enums only need to match by primitive type. - Assert.True((bool)GetMethod(nameof(EnumMethods.PassColorsInt)). - Invoke(null, new object[] { OtherColorsInt.Red })); - - // Widening allowed - Assert.True((bool)GetMethod(nameof(EnumMethods.PassColorsInt)). - Invoke(null, new object[] { ColorsShort.Red })); - - // Narrowing not allowed - Assert.Throws(() => GetMethod(nameof(EnumMethods.PassColorsShort)). - Invoke(null, new object[] { OtherColorsInt.Red })); - - static MethodInfo GetMethod(string name) => typeof(EnumMethods).GetMethod( - name, BindingFlags.Public | BindingFlags.Static)!; - } - - [Fact] - public static void InvokeNullableEnumParameterDefaultNo() - { - MethodInfo method = typeof(EnumMethods).GetMethod("NullableEnumDefaultNo", BindingFlags.Static | BindingFlags.NonPublic); - - Assert.Null(method.Invoke(null, new object?[] { default(object) })); - Assert.Equal(YesNo.No, method.Invoke(null, new object?[] { YesNo.No })); - Assert.Equal(YesNo.Yes, method.Invoke(null, new object?[] { YesNo.Yes })); - Assert.Equal(YesNo.No, method.Invoke(null, new object?[] { Type.Missing })); - } - - [Fact] - public static void InvokeNullableEnumParameterDefaultYes() - { - MethodInfo method = typeof(EnumMethods).GetMethod("NullableEnumDefaultYes", BindingFlags.Static | BindingFlags.NonPublic); - - Assert.Null(method.Invoke(null, new object?[] { default(object) })); - Assert.Equal(YesNo.No, method.Invoke(null, new object?[] { YesNo.No })); - Assert.Equal(YesNo.Yes, method.Invoke(null, new object?[] { YesNo.Yes })); - Assert.Equal(YesNo.Yes, method.Invoke(null, new object?[] { Type.Missing })); - } - - [Fact] - public static void InvokeNonNullableEnumParameterDefaultYes() - { - MethodInfo method = typeof(EnumMethods).GetMethod("NonNullableEnumDefaultYes", BindingFlags.Static | BindingFlags.NonPublic); - - Assert.Equal(YesNo.No, method.Invoke(null, new object[] { default(object) })); - Assert.Equal(YesNo.No, method.Invoke(null, new object[] { YesNo.No })); - Assert.Equal(YesNo.Yes, method.Invoke(null, new object[] { YesNo.Yes })); - Assert.Equal(YesNo.Yes, method.Invoke(null, new object[] { Type.Missing })); - } - - [Fact] - public static void InvokeNullableEnumParameterDefaultNull() - { - MethodInfo method = typeof(EnumMethods).GetMethod("NullableEnumDefaultNull", BindingFlags.Static | BindingFlags.NonPublic); - - Assert.Null(method.Invoke(null, new object?[] { default(object) })); - Assert.Equal(YesNo.No, method.Invoke(null, new object?[] { YesNo.No })); - Assert.Equal(YesNo.Yes, method.Invoke(null, new object?[] { YesNo.Yes })); - Assert.Null(method.Invoke(null, new object?[] { Type.Missing })); - } - - [Fact] - public static void InvokeNullableEnumParameterNoDefault() - { - MethodInfo method = typeof(EnumMethods).GetMethod("NullableEnumNoDefault", BindingFlags.Static | BindingFlags.NonPublic); - - Assert.Null(method.Invoke(null, new object?[] { default(object) })); - Assert.Equal(YesNo.No, method.Invoke(null, new object?[] { YesNo.No })); - Assert.Equal(YesNo.Yes, method.Invoke(null, new object?[] { YesNo.Yes })); - Assert.Throws(() => method.Invoke(null, new object?[] { Type.Missing })); - } - public static IEnumerable MethodNameAndArguments() { yield return new object[] { nameof(Sample.DefaultString), "Hello", "Hi" }; @@ -805,68 +671,6 @@ public static void InvokeCopiesBackMissingParameterAndArgument() Assert.Null(args[0]); } - [Fact] - public void ValueTypeMembers_WithOverrides() - { - ValueTypeWithOverrides obj = new() { Id = 1 }; - - // ToString is overridden. - Assert.Equal("Hello", (string)GetMethod(typeof(ValueTypeWithOverrides), nameof(ValueTypeWithOverrides.ToString)). - Invoke(obj, null)); - - // Ensure a normal method works. - Assert.Equal(1, (int)GetMethod(typeof(ValueTypeWithOverrides), nameof(ValueTypeWithOverrides.GetId)). - Invoke(obj, null)); - } - - [Fact] - public void ValueTypeMembers_WithoutOverrides() - { - ValueTypeWithoutOverrides obj = new() { Id = 1 }; - - // ToString is not overridden. - Assert.Equal(typeof(ValueTypeWithoutOverrides).ToString(), (string)GetMethod(typeof(ValueTypeWithoutOverrides), nameof(ValueTypeWithoutOverrides.ToString)). - Invoke(obj, null)); - - // Ensure a normal method works. - Assert.Equal(1, (int)GetMethod(typeof(ValueTypeWithoutOverrides), nameof(ValueTypeWithoutOverrides.GetId)). - Invoke(obj, null)); - } - - [Fact] - public void NullableOfTMembers() - { - // Ensure calling a method on Nullable works. - MethodInfo mi = GetMethod(typeof(int?), nameof(Nullable.GetValueOrDefault)); - Assert.Equal(42, mi.Invoke(42, null)); - } - - [Fact] - public void CopyBackWithByRefArgs() - { - object i = 42; - object[] args = new object[] { i }; - GetMethod(typeof(CopyBackMethods), nameof(CopyBackMethods.IncrementByRef)).Invoke(null, args); - Assert.Equal(43, (int)args[0]); - Assert.NotSame(i, args[0]); // A copy should be made; a boxed instance should never be directly updated. - - i = 42; - args = new object[] { i }; - GetMethod(typeof(CopyBackMethods), nameof(CopyBackMethods.IncrementByNullableRef)).Invoke(null, args); - Assert.Equal(43, (int)args[0]); - Assert.NotSame(i, args[0]); - - object o = null; - args = new object[] { o }; - GetMethod(typeof(CopyBackMethods), nameof(CopyBackMethods.SetToNonNullByRef)).Invoke(null, args); - Assert.NotNull(args[0]); - - o = new object(); - args = new object[] { o }; - GetMethod(typeof(CopyBackMethods), nameof(CopyBackMethods.SetToNullByRef)).Invoke(null, args); - Assert.Null(args[0]); - } - [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/50957", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoInterpreter))] [ActiveIssue("https://github.com/dotnet/runtime/issues/69919", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] @@ -894,69 +698,6 @@ private static void SecondCall(MethodInfo mi) Assert.Contains("TestAssembly", asm.ToString()); } - [Fact] - private static unsafe void TestFunctionPointerDirect() - { - // Sanity checks for direct invocation. - void* fn = FunctionPointerMethods.GetFunctionPointer(); - Assert.True(FunctionPointerMethods.GetFunctionPointer()(42)); - Assert.True(FunctionPointerMethods.CallFcnPtr_IntPtr((IntPtr)fn, 42)); - Assert.True(FunctionPointerMethods.CallFcnPtr_Void(fn, 42)); - Assert.False(FunctionPointerMethods.GetFunctionPointer()(41)); - Assert.False(FunctionPointerMethods.CallFcnPtr_IntPtr((IntPtr)fn, 41)); - Assert.False(FunctionPointerMethods.CallFcnPtr_Void(fn, 41)); - } - - [Fact] - private static unsafe void TestFunctionPointerAsIntPtrArgType() - { - void* fn = FunctionPointerMethods.GetFunctionPointer(); - - MethodInfo m; - - m = GetMethod(typeof(FunctionPointerMethods), nameof(FunctionPointerMethods.CallFcnPtr_IntPtr)); - Assert.True((bool)m.Invoke(null, new object[] { (IntPtr)fn, 42 })); - Assert.False((bool)m.Invoke(null, new object[] { (IntPtr)fn, 41 })); - - m = GetMethod(typeof(FunctionPointerMethods), nameof(FunctionPointerMethods.CallFcnPtr_Void)); - Assert.True((bool)m.Invoke(null, new object[] { (IntPtr)fn, 42 })); - Assert.False((bool)m.Invoke(null, new object[] { (IntPtr)fn, 41 })); - } - - [Fact] - private static unsafe void TestFunctionPointerAsUIntPtrArgType() - { - void* fn = FunctionPointerMethods.GetFunctionPointer(); - - MethodInfo m; - - m = GetMethod(typeof(FunctionPointerMethods), nameof(FunctionPointerMethods.CallFcnPtr_UIntPtr)); - Assert.True((bool)m.Invoke(null, new object[] { (UIntPtr)fn, 42 })); - Assert.False((bool)m.Invoke(null, new object[] { (UIntPtr)fn, 41 })); - - m = GetMethod(typeof(FunctionPointerMethods), nameof(FunctionPointerMethods.CallFcnPtr_Void)); - Assert.True((bool)m.Invoke(null, new object[] { (UIntPtr)fn, 42 })); - Assert.False((bool)m.Invoke(null, new object[] { (UIntPtr)fn, 41 })); - } - - [Fact] - private static unsafe void TestFunctionPointerAsArgType() - { - void* fn = FunctionPointerMethods.GetFunctionPointer(); - MethodInfo m = GetMethod(typeof(FunctionPointerMethods), nameof(FunctionPointerMethods.CallFcnPtr_FP)); - Assert.True((bool)m.Invoke(null, new object[] { (IntPtr)fn, 42 })); - Assert.False((bool)m.Invoke(null, new object[] { (IntPtr)fn, 41 })); - } - - [Fact] - private static unsafe void TestFunctionPointerAsReturnType() - { - MethodInfo m = GetMethod(typeof(FunctionPointerMethods), nameof(FunctionPointerMethods.GetFunctionPointer)); - object ret = m.Invoke(null, null); - Assert.IsType(ret); - Assert.True((IntPtr)ret != 0); - } - //Methods for Reflection Metadata private void DummyMethod1(string str, int iValue, long lValue) { @@ -965,11 +706,6 @@ private void DummyMethod1(string str, int iValue, long lValue) private void DummyMethod2() { } - - private static MethodInfo GetMethod(Type type, string name) - { - return type.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).First(method => method.Name.Equals(name)); - } } #pragma warning disable 0414 diff --git a/src/libraries/System.Reflection/tests/MethodInvokerTests.cs b/src/libraries/System.Reflection/tests/MethodInvokerTests.cs index 97c9865a64fdaf..94d701507eac1d 100644 --- a/src/libraries/System.Reflection/tests/MethodInvokerTests.cs +++ b/src/libraries/System.Reflection/tests/MethodInvokerTests.cs @@ -2,13 +2,22 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Linq; using Xunit; namespace System.Reflection.Tests { - public class MethodInvokerTests + /// + /// These tests use the shared tests from the base class with MethodInvoker.Invoke. + /// + public class MethodInvokerTests : MethodCommonTests { + public override object? Invoke(MethodInfo methodInfo, object? obj, object?[]? parameters) + { + return MethodInvoker.Create(methodInfo).Invoke(obj, new Span(parameters)); + } + + protected override bool SupportsMissing => false; + [Fact] public void NullTypeValidation() { @@ -286,11 +295,6 @@ public void VerifyThisObj_Null() Assert.Throws(() => invoker.Invoke(obj: null)); } - private static MethodInfo GetMethod(Type type, string name) - { - return type.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).First(method => method.Name.Equals(name)); - } - public static IEnumerable Invoke_TestData() => MethodInfoTests.Invoke_TestData(); private class TestClass diff --git a/src/libraries/System.Reflection/tests/System.Reflection.Tests.csproj b/src/libraries/System.Reflection/tests/System.Reflection.Tests.csproj index e6adafcbaac1d5..9553a7dacc4828 100644 --- a/src/libraries/System.Reflection/tests/System.Reflection.Tests.csproj +++ b/src/libraries/System.Reflection/tests/System.Reflection.Tests.csproj @@ -14,14 +14,12 @@ - - - + + + + @@ -31,6 +29,7 @@ + @@ -42,8 +41,7 @@ - + From 2d5b3b3727d1cbec30a31643f8f0335e7a3c3a4d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 25 Aug 2023 15:10:54 -0700 Subject: [PATCH 079/783] JIT: Skip Create(ToScalar(Dot(...))) transformation on mismatched types (#91089) Fix #91062 Co-authored-by: Jakob Botsch Nielsen --- src/coreclr/jit/morph.cpp | 6 +++++ .../JitBlue/Runtime_91062/Runtime_91062.cs | 22 +++++++++++++++++++ .../Runtime_91062/Runtime_91062.csproj | 8 +++++++ 3 files changed, 36 insertions(+) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91062/Runtime_91062.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91062/Runtime_91062.csproj diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index f29d6a57148136..52454b0c8b7316 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -10770,6 +10770,12 @@ GenTree* Compiler::fgOptimizeHWIntrinsic(GenTreeHWIntrinsic* node) break; } + // Must be working with the same types of vectors. + if (hwop1->TypeGet() != node->TypeGet()) + { + break; + } + if (toScalar != nullptr) { DEBUG_DESTROY_NODE(toScalar); diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91062/Runtime_91062.cs b/src/tests/JIT/Regression/JitBlue/Runtime_91062/Runtime_91062.cs new file mode 100644 index 00000000000000..8886bd2044ab04 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91062/Runtime_91062.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license.aa + +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Numerics; +using Xunit; + +public class Runtime_91062 +{ + [Fact] + public static void TestEntryPoint() + { + Foo(default, default); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Vector2 Foo(Vector128 v1, Vector128 v2) + { + return Vector2.Lerp(default, default, Vector128.Dot(v1, v2)); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91062/Runtime_91062.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_91062/Runtime_91062.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91062/Runtime_91062.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From d379e3a1fe89d463ae55b86525fbd7713e983d9e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 25 Aug 2023 15:11:09 -0700 Subject: [PATCH 080/783] Use RuntimeIdentifierGraphPath if available in runtime copy of Microsoft.NET.CrossGen.targets (#91090) Co-authored-by: Elinor Fung --- src/tasks/Crossgen2Tasks/Microsoft.NET.CrossGen.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tasks/Crossgen2Tasks/Microsoft.NET.CrossGen.targets b/src/tasks/Crossgen2Tasks/Microsoft.NET.CrossGen.targets index a2912cc0822849..c539d330e8add8 100644 --- a/src/tasks/Crossgen2Tasks/Microsoft.NET.CrossGen.targets +++ b/src/tasks/Crossgen2Tasks/Microsoft.NET.CrossGen.targets @@ -443,7 +443,7 @@ Copyright (c) .NET Foundation. All rights reserved. Date: Fri, 25 Aug 2023 15:17:09 -0700 Subject: [PATCH 081/783] [release/8.0] Update dependencies from dotnet/roslyn (#91093) * Update dependencies from https://github.com/dotnet/roslyn build 20230824.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23423.10 -> To Version 4.8.0-2.23424.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230824.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23423.10 -> To Version 4.8.0-2.23424.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230824.7 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23423.10 -> To Version 4.8.0-1.23424.7 * Update dependencies from https://github.com/dotnet/roslyn build 20230824.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23423.10 -> To Version 4.8.0-2.23424.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230824.8 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23423.10 -> To Version 4.8.0-2.23424.8 * Update dependencies from https://github.com/dotnet/roslyn build 20230824.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23423.10 -> To Version 4.8.0-2.23424.5 * Update dependencies from https://github.com/dotnet/roslyn build 20230824.9 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23423.10 -> To Version 4.8.0-2.23424.9 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e487aa87355a5c..90f5ad8cb33409 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - d83f0cc401672efe5afd5e9db4be43e9e06c5935 + d7e010bbe5b1d37837417fc5e79ecb2fd9b7b487 - + https://github.com/dotnet/roslyn - d83f0cc401672efe5afd5e9db4be43e9e06c5935 + d7e010bbe5b1d37837417fc5e79ecb2fd9b7b487 - + https://github.com/dotnet/roslyn - d83f0cc401672efe5afd5e9db4be43e9e06c5935 + d7e010bbe5b1d37837417fc5e79ecb2fd9b7b487 https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index 931464d372cb3c..e6526116aa3a83 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -42,9 +42,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-2.23423.10 - 4.8.0-2.23423.10 - 4.8.0-2.23423.10 + 4.8.0-2.23424.9 + 4.8.0-2.23424.9 + 4.8.0-2.23424.9 + true True diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91056/Runtime_91056.cs b/src/tests/JIT/Regression/JitBlue/Runtime_91056/Runtime_91056.cs new file mode 100644 index 00000000000000..a0c78804a7ee52 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91056/Runtime_91056.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; +using System.Runtime.CompilerServices; + +public class Runtime_91056 +{ + [Fact] + public static void TestEntryPoint() + { + S s = default; + if (False()) + { + s.A = 1234; + } + + Foo(0, 0, s, s); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool False() => false; + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Foo(int a, int b, S s1, S s2) + { + } + + public struct S + { + public int A; + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91056/Runtime_91056.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_91056/Runtime_91056.csproj new file mode 100644 index 00000000000000..444d119c04fe97 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91056/Runtime_91056.csproj @@ -0,0 +1,12 @@ + + + + true + True + + + + + + + \ No newline at end of file From ab22bc767e5a8cc7cfba3e529cb96d968082518b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 25 Aug 2023 17:15:41 -0700 Subject: [PATCH 085/783] [release/8.0] Update dependencies from dotnet/roslyn-analyzers dotnet/source-build-reference-packages (#91114) * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20230824.2 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23423.2 -> To Version 3.11.0-beta1.23424.2 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20230824.1 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23421.1 -> To Version 8.0.0-alpha.1.23424.1 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 90f5ad8cb33409..47f9d1ce3af669 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -95,9 +95,9 @@ 66dbaefff04250dc72849f0172e0c53bcfb3ab38 - + https://github.com/dotnet/source-build-reference-packages - f4903e46459e0348e3793055dd8b68b8b0264034 + 93c23409e630c4f267234540b0e3557b76a53ef4 @@ -371,13 +371,13 @@ https://github.com/dotnet/roslyn d7e010bbe5b1d37837417fc5e79ecb2fd9b7b487 - + https://github.com/dotnet/roslyn-analyzers - 76d99c5f3e11f0600fae074270c0d89042c360f0 + e1da9c89ca09a43ebac06a5e9ef0798407bc555b - + https://github.com/dotnet/roslyn-analyzers - 76d99c5f3e11f0600fae074270c0d89042c360f0 + e1da9c89ca09a43ebac06a5e9ef0798407bc555b https://github.com/dotnet/sdk diff --git a/eng/Versions.props b/eng/Versions.props index e6526116aa3a83..b8994b05237157 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,8 +34,8 @@ - 3.11.0-beta1.23423.2 - 8.0.0-preview.23423.2 + 3.11.0-beta1.23424.2 + 8.0.0-preview.23424.2 - 4.8.0-2.23424.9 - 4.8.0-2.23424.9 - 4.8.0-2.23424.9 + 4.8.0-2.23426.1 + 4.8.0-2.23426.1 + 4.8.0-2.23426.1 diff --git a/eng/Versions.props b/eng/Versions.props index 72896a31452521..f49e17b28a4a34 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -156,12 +156,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23362.5 - 1.0.0-prerelease.23362.5 - 1.0.0-prerelease.23362.5 - 1.0.0-prerelease.23362.5 - 1.0.0-prerelease.23362.5 - 1.0.0-prerelease.23362.5 + 1.0.0-prerelease.23427.2 + 1.0.0-prerelease.23427.2 + 1.0.0-prerelease.23427.2 + 1.0.0-prerelease.23427.2 + 1.0.0-prerelease.23427.2 + 1.0.0-prerelease.23427.2 16.11.27-beta1.23180.1 2.0.0-beta4.23307.1 From 77f36e7f609bcafc8f312959b8a5d851a5b13d8a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 12:06:08 -0600 Subject: [PATCH 094/783] Enable System.IO.Hashing tests on ios and disable tvos (#91195) Co-authored-by: Ivan Povazan --- src/libraries/tests.proj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 7ef3d7b0235ebb..a550e9cf9cc827 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -266,6 +266,7 @@ + + From 259a8a45cf6e7b907a55c489708fdcf6e36c7c94 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 14:54:57 -0600 Subject: [PATCH 095/783] [release/8.0] Update dependencies from dotnet/roslyn-analyzers dotnet/arcade (#91154) * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20230825.3 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23424.2 -> To Version 3.11.0-beta1.23425.3 * Update dependencies from https://github.com/dotnet/arcade build 20230825.2 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23422.1 -> To Version 8.0.0-beta.23425.2 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23418.1 -> To Version 1.0.0-beta.23423.1 (parent: Microsoft.DotNet.Arcade.Sdk * Update testPackages.proj --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Viktor Hofer --- eng/Version.Details.xml | 84 ++++++++++---------- eng/Versions.props | 34 ++++---- global.json | 6 +- src/libraries/testPackages/testPackages.proj | 16 +++- 4 files changed, 76 insertions(+), 64 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 79c4d9d853825a..aad708a98fcdce 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -107,79 +107,79 @@ - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/xliff-tasks - bb654cd4736e7e8cb99f1c355ce2b8f0a686ba74 + ed9a83526483c094fb51e7000b6f816ce6cb0325 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 https://github.com/dotnet/runtime-assets @@ -330,9 +330,9 @@ https://github.com/dotnet/xharness 480b9159eb7e69b182a87581d5a336e97e0b6dae - + https://github.com/dotnet/arcade - 4d9945d230fdd8324ce16a31c7dbd74e27a0fc9b + 90c167d5c57de4a8bced566379dbd893556c94e8 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization @@ -371,13 +371,13 @@ https://github.com/dotnet/roslyn 34268d1bb9370c7b01c742303a895a99daf10d6a - + https://github.com/dotnet/roslyn-analyzers - e1da9c89ca09a43ebac06a5e9ef0798407bc555b + 546d9ed731872c72279735c55f140ab8967f5656 - + https://github.com/dotnet/roslyn-analyzers - e1da9c89ca09a43ebac06a5e9ef0798407bc555b + 546d9ed731872c72279735c55f140ab8967f5656 https://github.com/dotnet/sdk diff --git a/eng/Versions.props b/eng/Versions.props index f49e17b28a4a34..6414c8e37f55d0 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,8 +34,8 @@ - 3.11.0-beta1.23424.2 - 8.0.0-preview.23424.2 + 3.11.0-beta1.23425.3 + 8.0.0-preview.23425.3 8.0.100-preview.7.23329.3 - 8.0.0-beta.23422.1 - 8.0.0-beta.23422.1 - 8.0.0-beta.23422.1 - 8.0.0-beta.23422.1 - 8.0.0-beta.23422.1 - 2.5.1-beta.23422.1 - 8.0.0-beta.23422.1 - 8.0.0-beta.23422.1 - 8.0.0-beta.23422.1 - 8.0.0-beta.23422.1 - 8.0.0-beta.23422.1 - 8.0.0-beta.23422.1 - 8.0.0-beta.23422.1 - 8.0.0-beta.23422.1 - 8.0.0-beta.23422.1 + 8.0.0-beta.23425.2 + 8.0.0-beta.23425.2 + 8.0.0-beta.23425.2 + 8.0.0-beta.23425.2 + 8.0.0-beta.23425.2 + 2.5.1-beta.23425.2 + 8.0.0-beta.23425.2 + 8.0.0-beta.23425.2 + 8.0.0-beta.23425.2 + 8.0.0-beta.23425.2 + 8.0.0-beta.23425.2 + 8.0.0-beta.23425.2 + 8.0.0-beta.23425.2 + 8.0.0-beta.23425.2 + 8.0.0-beta.23425.2 6.0.0-preview.1.102 diff --git a/global.json b/global.json index 95e75305ea00be..ffe9ed56766f48 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.100-preview.7.23376.3" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23422.1", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23422.1", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23422.1", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23425.2", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23425.2", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23425.2", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" diff --git a/src/libraries/testPackages/testPackages.proj b/src/libraries/testPackages/testPackages.proj index 6480f5fc5928bf..9d60aeb8e6e64b 100644 --- a/src/libraries/testPackages/testPackages.proj +++ b/src/libraries/testPackages/testPackages.proj @@ -63,12 +63,24 @@ - + + + + + + + + + + + + + + From 22a50ac0d6fee725c79845e5b73fce7e10363861 Mon Sep 17 00:00:00 2001 From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com> Date: Mon, 28 Aug 2023 16:01:52 -0700 Subject: [PATCH 096/783] [ComInterfaceGenerator] Recommend [In] and [Out] attributes on array parameters (#91094) (#91231) Recommend that methods with array parameters use [In] or [Out] attributes if there are none already, and the parameter is not in, ref, or out. --- docs/project/list-of-diagnostics.md | 2 +- .../DiagnosticDescriptorProvider.cs | 1 + .../GeneratorDiagnostics.cs | 11 + .../gen/Common/Resources/Strings.resx | 25 +- .../gen/Common/Resources/xlf/Strings.cs.xlf | 41 ++- .../gen/Common/Resources/xlf/Strings.de.xlf | 41 ++- .../gen/Common/Resources/xlf/Strings.es.xlf | 41 ++- .../gen/Common/Resources/xlf/Strings.fr.xlf | 39 ++- .../gen/Common/Resources/xlf/Strings.it.xlf | 39 ++- .../gen/Common/Resources/xlf/Strings.ja.xlf | 41 ++- .../gen/Common/Resources/xlf/Strings.ko.xlf | 41 ++- .../gen/Common/Resources/xlf/Strings.pl.xlf | 39 ++- .../Common/Resources/xlf/Strings.pt-BR.xlf | 41 ++- .../gen/Common/Resources/xlf/Strings.ru.xlf | 39 ++- .../gen/Common/Resources/xlf/Strings.tr.xlf | 39 ++- .../Common/Resources/xlf/Strings.zh-Hans.xlf | 41 ++- .../Common/Resources/xlf/Strings.zh-Hant.xlf | 39 ++- .../DiagnosticDescriptorProvider.cs | 1 + .../GeneratorDiagnostics.cs | 10 + .../IncrementalValuesProviderExtensions.cs | 2 +- ...ributedMarshallingModelGeneratorFactory.cs | 11 +- .../ByValueContentsMarshalKindValidator.cs | 3 +- .../ByValueMarshalKindSupportDescriptor.cs | 166 +++++----- .../Marshalling/GeneratorDiagnostic.cs | 13 + .../Marshalling/MarshallingGenerator.cs | 4 + .../StaticPinnableManagedValueMarshaller.cs | 2 +- .../ByValueContentsMarshalling.cs | 301 ++++++++++++++++++ .../CodeSnippets.cs | 60 ++++ .../ComInterfaceGenerator.Unit.Tests.csproj | 1 + .../CompileFails.cs | 294 +---------------- .../tests/Common/TestUtils.cs | 14 +- .../ByValueContentsMarshalling.cs | 135 ++++++++ .../CodeSnippets.cs | 16 + .../CompileFails.cs | 57 ---- .../Compiles.cs | 24 -- .../TestAssets/SharedTypes/SharedTypes.csproj | 2 + 36 files changed, 1160 insertions(+), 516 deletions(-) create mode 100644 src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/ByValueContentsMarshalling.cs create mode 100644 src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/ByValueContentsMarshalling.cs diff --git a/docs/project/list-of-diagnostics.md b/docs/project/list-of-diagnostics.md index 3c9a9afb9c4199..4b46d49f5813f0 100644 --- a/docs/project/list-of-diagnostics.md +++ b/docs/project/list-of-diagnostics.md @@ -208,7 +208,7 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL | __`SYSLIB1089`__ | _`SYSLIB1070`-`SYSLIB1089` reserved for System.Runtime.InteropServices.JavaScript.JSImportGenerator._ | | __`SYSLIB1090`__ | Invalid 'GeneratedComInterfaceAttribute' usage | | __`SYSLIB1091`__ | Method is declared in different partial declaration than the 'GeneratedComInterface' attribute. | -| __`SYSLIB1092`__ | 'GenerateComInterfaceAttribute' usage not recommended. See aka.ms/GeneratedComInterfaceUsage for recommended usage. | +| __`SYSLIB1092`__ | Usage of '[LibraryImport|GeneratedComInterface]' does not follow recommendation. See aka.ms/[LibraryImport|GeneratedComInterface]Usage for best practices. | | __`SYSLIB1093`__ | Analysis for COM interface generation has failed | | __`SYSLIB1094`__ | The base COM interface failed to generate source. Code will not be generated for this interface. | | __`SYSLIB1095`__ | Invalid 'GeneratedComClassAttribute' usage | diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/DiagnosticDescriptorProvider.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/DiagnosticDescriptorProvider.cs index c676f27cb9f401..fab2d39182c8b7 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/DiagnosticDescriptorProvider.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/DiagnosticDescriptorProvider.cs @@ -26,6 +26,7 @@ internal sealed class DiagnosticDescriptorProvider : IDiagnosticDescriptorProvid GeneratorDiagnostic.NotSupported { NotSupportedDetails: not null, TypePositionInfo.IsManagedReturnPosition: false } => GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails, GeneratorDiagnostic.UnnecessaryData { TypePositionInfo.IsManagedReturnPosition: false } => GeneratorDiagnostics.UnnecessaryParameterMarshallingInfo, GeneratorDiagnostic.UnnecessaryData { TypePositionInfo.IsManagedReturnPosition: true } => GeneratorDiagnostics.UnnecessaryReturnMarshallingInfo, + GeneratorDiagnostic.NotRecommended => GeneratorDiagnostics.GeneratedComInterfaceUsageDoesNotFollowBestPractices, { IsFatal: false } => null, { TypePositionInfo.IsManagedReturnPosition: true } => GeneratorDiagnostics.ReturnTypeNotSupported, { TypePositionInfo.IsManagedReturnPosition: false } => GeneratorDiagnostics.ParameterTypeNotSupported, diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratorDiagnostics.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratorDiagnostics.cs index b213e3a9704f29..1e1849592f7ba4 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratorDiagnostics.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratorDiagnostics.cs @@ -485,6 +485,17 @@ public class Ids DiagnosticSeverity.Info, isEnabledByDefault: true); + /// + public static readonly DiagnosticDescriptor GeneratedComInterfaceUsageDoesNotFollowBestPractices = + new DiagnosticDescriptor( + Ids.NotRecommendedGeneratedComInterfaceUsage, + GetResourceString(nameof(SR.ComInterfaceUsageDoesNotFollowBestPracticesTitle)), + GetResourceString(nameof(SR.ComInterfaceUsageDoesNotFollowBestPracticesMessageWithDetails)), + Category, + DiagnosticSeverity.Info, + isEnabledByDefault: true, + helpLinkUri: "aka.ms/GeneratedComInterfaceUsage"); + /// /// Report diagnostic for invalid configuration for string marshalling. /// diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/Strings.resx b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/Strings.resx index ebf0170e328752..2da298e8a7b0df 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/Strings.resx +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/Strings.resx @@ -875,7 +875,13 @@ [In] and [Out] attributes - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. @@ -889,4 +895,19 @@ This type will be treated as a struct in the native signature, not as a native HRESULT - \ No newline at end of file + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf index e1b25c7690ffa4..829de99735954b 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf @@ -147,6 +147,16 @@ Hostování .NET COM s EnableComHosting nepodporuje rozhraní s generatedComInterfaceAttribute + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. Vrácená hodnota ve spravované definici se při volání nespravované metody COM převede na parametr out. Pokud má být návratovou hodnotou kód HRESULT vrácený nespravovanou metodou COM, použijte u metody [PreserveSig]. @@ -447,6 +457,11 @@ Tento typ bude v nativním podpisu považován za strukturu, nikoli za nativní HRESULT. + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + The '[In]' attribute is not supported unless the '[Out]' attribute is also used. Blittable arrays cannot be marshalled as '[In]' only. Atribut [In] není podporován, pokud není použit také atribut [Out]. Blittable arrays nelze zařadit pouze jako [In]. @@ -467,6 +482,11 @@ Poskytnuté atributy „[In]“ a „[Out]“ u tohoto parametru se na tomto parametru nepodporují. + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + + [In] and [Out] attributes atributy [In] a [Out] @@ -702,6 +722,16 @@ Neplatné použití atributu VirtualMethodIndexAttribute + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + The usage of 'LibraryImportAttribute' does not follow recommendations. + + The element type of the 'ReadOnlySpan' returned by 'GetManagedValuesSource' must be the same as the element type returned by 'GetManagedValuesDestination'. Typ prvku ReadOnlySpan vrácený GetManagedValuesSource musí být stejný, jako typ prvku vrácený GetManagedValuesDestination. @@ -903,8 +933,8 @@ - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - Atribut „[Out]“ se podporuje pouze u parametrů pole. Zvažte použití klíčových slov „out“ nebo „ref“, aby se parametr dalo měnit. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. @@ -917,6 +947,11 @@ Typ {0}určuje, že podporuje zařazování ve směru „Out“, ale neposkytuje metodu ToManaged, která vrací spravovaný typ + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + 'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. GeneratedComInterfaceAttribute a GeneratedComClassAttribute vyžadují nebezpečný kód. Projekt se musí aktualizovat na <AllowUnsafeBlocks>true</AllowUnsafeBlocks>. @@ -1276,4 +1311,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf index 1b056b0cb4118e..1f959d763c7ba7 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf @@ -147,6 +147,16 @@ Das .NET COM-Hosting mit "EnableComHosting" unterstützt keine Schnittstellen mit "GeneratedComInterfaceAttribute". + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. Der Rückgabewert in der verwalteten Definition wird beim Aufrufen der nicht verwalteten COM-Methode in einen out-Parameter konvertiert. Wenn als Rückgabewert der von der nicht verwalteten COM-Methode zurückgegebene HRESULT-Code eingesetzt werden soll, verwenden Sie "[PreserveSig]" für die Methode. @@ -447,6 +457,11 @@ Dieser Typ wird als Struktur in der nativen Signatur und nicht als natives HRESULT behandelt + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + The '[In]' attribute is not supported unless the '[Out]' attribute is also used. Blittable arrays cannot be marshalled as '[In]' only. Das [In]-Attribut wird nur unterstützt, wenn auch das [Out]-Attribut verwendet wird. Blittable-Arrays können nicht nur als "[In]" gemarshallt werden. @@ -467,6 +482,11 @@ Die angegebenen Attribute \"[In]\" und \"[Out]\" für diesen Parameter werden für diesen Parameter nicht unterstützt. + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + + [In] and [Out] attributes [In]- und [Out]-Attribute @@ -702,6 +722,16 @@ Ungültige Verwendung von "VirtualMethodIndexAttribute" + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + The usage of 'LibraryImportAttribute' does not follow recommendations. + + The element type of the 'ReadOnlySpan' returned by 'GetManagedValuesSource' must be the same as the element type returned by 'GetManagedValuesDestination'. Der von \"GetManagedValuesSource\" zurückgegebene Elementtyp \"ReadOnlySpan\" muss mit dem Elementtyp identisch sein, der von \"GetManagedValuesDestination\" zurückgegeben wird. @@ -903,8 +933,8 @@ - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - Das [Out]-Attribut wird nur für Arrayparameter gemarshallt werden. Erwägen Sie die Verwendung der Schlüsselwörter "out" oder "ref", um den Parameter änderbar zu machen. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. @@ -917,6 +947,11 @@ Der Typ \"{0}\" gibt an, dass das Marshalling in der Out-Richtung unterstützt wird. Er stellt jedoch keine ToManaged-Methode bereit, die den verwalteten Typ zurückgibt. + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + 'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. 'GeneratedComInterfaceAttribute' und 'GeneratedComClassAttribute' erfordern unsicheren Code. Das Projekt muss mit '<AllowUnsafeBlocks>wahr</AllowUnsafeBlocks>' aktualisiert werden. @@ -1276,4 +1311,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf index 7d67b06c68960e..fab077ea6bac23 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf @@ -147,6 +147,16 @@ El hospedaje COM de .NET con “EnableComHosting” no admite interfaces con “GeneratedComInterfaceAttribute” + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. El valor devuelto en la definición administrada se convertirá en un parámetro “out” al llamar al método COM no administrado. Si el valor devuelto debe ser el código HRESULT devuelto por el método COM no administrado, use “[PreserveSig]” en el método. @@ -447,6 +457,11 @@ Este tipo se tratará como una estructura en la firma nativa, no como un HRESULT nativo. + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + The '[In]' attribute is not supported unless the '[Out]' attribute is also used. Blittable arrays cannot be marshalled as '[In]' only. El atributo '[In]' no se admite a menos que también se use el atributo '[Out]'. Las matrices que se pueden transferir en bloque de bits no se pueden serializar solo como '[In]'. @@ -467,6 +482,11 @@ En este parámetro, los atributos “[In]” y “[Out]” proporcionados no se admiten. + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + + [In] and [Out] attributes Atributos [In] y [Out] @@ -702,6 +722,16 @@ Uso de ”VirtualMethodIndexAttribute” no válido + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + The usage of 'LibraryImportAttribute' does not follow recommendations. + + The element type of the 'ReadOnlySpan' returned by 'GetManagedValuesSource' must be the same as the element type returned by 'GetManagedValuesDestination'. El tipo de elemento del “ReadOnlySpan” devuelto por “GetManagedValuesSource” debe ser el mismo que el tipo de elemento devuelto por “GetManagedValuesDestination”. @@ -903,8 +933,8 @@ - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - El atributo "[Out]" solo se admite en parámetros de matriz. Considere la posibilidad de usar palabras clave "out" o "ref" para hacer que el parámetro sea mutable. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. @@ -917,6 +947,11 @@ El tipo “{0}” especifica que admite la serialización en la dirección “Out”, pero no proporciona un método “ToManaged” que devuelva el tipo administrado + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + 'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. "GeneratedComInterfaceAttribute" y "GeneratedComClassAttribute" requieren código no seguro. El proyecto debe actualizarse con "<AllowUnsafeBlocks>true</AllowUnsafeBlocks>". @@ -1276,4 +1311,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf index e4a153641da409..3f8638ef4ee7f8 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf @@ -147,6 +147,16 @@ L'hébergement .NET COM avec 'EnableComHosting' ne prend pas en charge les interfaces avec 'GeneratedComInterfaceAttribute' + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. La valeur de retour dans la définition managée est convertie en paramètre 'out' lors de l’appel de la méthode COM non managée. Si la valeur de retour doit être le code HRESULT retourné par la méthode COM non managée, utilisez '[PreserveSig]' sur la méthode. @@ -447,6 +457,11 @@ Ce type sera traité en tant que struct dans la signature native, et non en tant que HRESULT natif + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + The '[In]' attribute is not supported unless the '[Out]' attribute is also used. Blittable arrays cannot be marshalled as '[In]' only. L’attribut '[In]' n’est pas pris en charge, sauf si l’attribut '[Out]' est également utilisé. Les tableaux blittables ne peuvent pas être marshalés en tant que « [In] » uniquement. @@ -467,6 +482,11 @@ Les attributs « [In] » et « [Out] » fournis sur ce paramètre ne sont pas pris en charge sur ce paramètre. + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + + [In] and [Out] attributes Attributs [In] et [Out] @@ -702,6 +722,16 @@ Utilisation de « VirtualMethodIndexAttribute » non valide + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + The usage of 'LibraryImportAttribute' does not follow recommendations. + + The element type of the 'ReadOnlySpan' returned by 'GetManagedValuesSource' must be the same as the element type returned by 'GetManagedValuesDestination'. Le type d’élément de « ReadOnlySpan » retourné par « GetManagedValuesSource » doit être identique au type d’élément retourné par « GetManagedValuesDestination ». @@ -903,8 +933,8 @@ - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - L’attribut '[Out]' est uniquement pris en charge sur les paramètres de tableau. Envisagez d’utiliser des mots clés 'out' ou 'ref' pour rendre le paramètre mutable. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + L’attribut '[Out]' est uniquement pris en charge sur les paramètres de tableau. Envisagez d’utiliser des mots clés 'out' ou 'ref' pour rendre le paramètre mutable. @@ -917,6 +947,11 @@ Le type « {0} » spécifie qu’il prend en charge le marshaling dans la direction « Out », mais il ne fournit pas de méthode « ToManaged » qui retourne le type managé + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + 'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. « GeneratedComInterfaceAttribute » et « GeneratedComClassAttribute » nécessitent du code non sécurisé. Le projet doit être mis à jour avec « <AllowUnsafeBlocks>true</AllowUnsafeBlocks> ». diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf index acc74fc43e9ed5..d6ed0fd8fc3b35 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf @@ -147,6 +147,16 @@ L'hosting COM .NET con 'EnableComHosting' non supporta le interfacce con 'GeneratedComInterfaceAttribute'. + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. Il valore restituito nella definizione gestita verrà convertito in un parametro 'out' quando si chiama il metodo COM non gestito. Se il valore restituito deve essere il codice HRESULT restituito dal metodo COM non gestito, utilizzare '[PreserveSig]' sul metodo. @@ -447,6 +457,11 @@ Questo tipo verrà considerato come uno struct nella firma nativa, non come HRESULT nativo + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + The '[In]' attribute is not supported unless the '[Out]' attribute is also used. Blittable arrays cannot be marshalled as '[In]' only. L'attributo '[In]' non è supportato a meno che non venga usato anche l'attributo '[Out]'. Le matrici copiabili da BLT non possono essere sottoposte a marshalling solo come '[In]'. @@ -467,6 +482,11 @@ Gli attributi '[In]' e '[Out]' specificati per questo parametro non sono supportati in questo parametro. + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + + [In] and [Out] attributes Attributi [In] e [Out] @@ -702,6 +722,16 @@ Utilizzo di 'VirtualMethodIndexAttribute' non valido + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + The usage of 'LibraryImportAttribute' does not follow recommendations. + + The element type of the 'ReadOnlySpan' returned by 'GetManagedValuesSource' must be the same as the element type returned by 'GetManagedValuesDestination'. Il tipo di elemento di 'ReadOnlySpan' restituito da 'GetManagedValuesSource' deve essere uguale al tipo di elemento restituito da 'GetManagedValuesDestination'. @@ -903,8 +933,8 @@ - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - L'attributo '[Out]' è supportato solo nei parametri di matrice. Provare a usare le parole chiave 'out' o 'ref' per rendere modificabile il parametro. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + L'attributo '[Out]' è supportato solo nei parametri di matrice. Provare a usare le parole chiave 'out' o 'ref' per rendere modificabile il parametro. @@ -917,6 +947,11 @@ Il tipo '{0}' specifica che supporta il marshalling nella direzione 'Out', ma non fornisce un metodo 'ToManaged' che restituisce il tipo gestito + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + 'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. GeneratedComInterfaceAttribute e 'GeneratedComClassAttribute' richiedono codice non gestito. Il progetto deve essere aggiornato con '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf index 946718bd8962ed..0963a7a2aa5267 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf @@ -147,6 +147,16 @@ 'EnableComHosting' を使用した .NET COM ホスティングでは、'GeneratedComInterfaceAttribute' のインターフェイスはサポートされていません + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. マネージド定義の戻り値は、アンマネージド COM メソッドを呼び出すときに 'out' パラメーターに変換されます。戻り値を、アンマネージド COM メソッドによって返される HRESULT コードにする場合は、メソッドで '[PreserveSig]' を使用してください。 @@ -447,6 +457,11 @@ この型はネイティブの HRESULT ではなく、ネイティブ シグネチャの構造体として扱われます + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + The '[In]' attribute is not supported unless the '[Out]' attribute is also used. Blittable arrays cannot be marshalled as '[In]' only. '[In]'属性は、'[Out]'属性も使用しない限りサポートされません。Blittable 配列は、'[In]'としてのみマーシャリングできません。 @@ -467,6 +482,11 @@ このパラメーターに指定された '[In]' 属性と '[Out]' 属性は、このパラメーターではサポートされていません。 + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + + [In] and [Out] attributes 属性の[In]と[Out] @@ -702,6 +722,16 @@ 'VirtualMethodIndexAttribute' の使用法が無効です + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + The usage of 'LibraryImportAttribute' does not follow recommendations. + + The element type of the 'ReadOnlySpan' returned by 'GetManagedValuesSource' must be the same as the element type returned by 'GetManagedValuesDestination'. 'GetManagedValuesSource' によって返される 'ReadOnlySpan' の要素型は、'GetManagedValuesDestination' によって返される要素型と同じである必要があります。 @@ -903,8 +933,8 @@ - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - '[Out]' 属性は、配列パラメーターでのみサポートされます。パラメーターを変更可能にするには、'out' または 'ref' キーワードを使用することを検討してください。 + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. @@ -917,6 +947,11 @@ 型 '{0}' は、'Out' 方向のマーシャリングをサポートしますが、マネージド型を返す 'ToManaged' メソッドは指定されません + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + 'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. 'GeneratedComInterfaceAttribute' および 'GeneratedComClassAttribute' にはアンセーフ コードが必要です。プロジェクトは '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>' で更新する必要があります。 @@ -1277,4 +1312,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf index baa3e6381b26d7..1cbdc68ed114d5 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf @@ -147,6 +147,16 @@ 'EnableComHosting'을 사용한 .NET COM 호스팅은 'GeneratedComInterfaceAttribute'를 사용한 인터페이스를 지원하지 않습니다. + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. 관리 정의의 반환 값은 관리되지 않는 COM 메서드를 호출할 때 'out' 매개 변수로 변환됩니다. 반환 값이 관리되지 않는 COM 메서드에서 반환된 HRESULT 코드인 경우 메서드에서 '[PreserveSig]'를 사용하세요. @@ -447,6 +457,11 @@ 이 형식은 네이티브 HRESULT가 아니라 네이티브 서명의 구조체로 처리됩니다. + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + The '[In]' attribute is not supported unless the '[Out]' attribute is also used. Blittable arrays cannot be marshalled as '[In]' only. '[Out]' 특성도 사용되지 않는 한 '[In]' 특성은 지원되지 않습니다. Blittable 배열은 '[In]'으로만 마샬링할 수 없습니다. @@ -467,6 +482,11 @@ 이 매개 변수에 제공된 '[In]' 및 '[Out]' 특성은 이 매개 변수에서 지원되지 않습니다. + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + + [In] and [Out] attributes [In] 및 [Out] 속성 @@ -702,6 +722,16 @@ 잘못된 'VirtualMethodIndexAttribute' 사용 + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + The usage of 'LibraryImportAttribute' does not follow recommendations. + + The element type of the 'ReadOnlySpan' returned by 'GetManagedValuesSource' must be the same as the element type returned by 'GetManagedValuesDestination'. 'GetManagedValuesSource'에서 반환된 'ReadOnlySpan'의 요소 형식은 'GetManagedValuesDestination'에서 반환된 요소 형식과 동일해야 합니다. @@ -903,8 +933,8 @@ - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - '[Out]' 특성은 배열 매개 변수에서만 지원됩니다. 매개 변수를 변경할 수 있도록 'out' 또는 'ref' 키워드를 사용하는 것이 좋습니다. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. @@ -917,6 +947,11 @@ 형식 '{0}'은(는) 'Out' 방향으로 마샬링을 지원하도록 지정하지만 관리 형식을 반환하는 'ToManaged' 메서드를 제공하지 않습니다. + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + 'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. 'GeneratedComInterfaceAttribute' 및 'GeneratedComClassAttribute'에는 안전하지 않은 코드가 필요합니다. 프로젝트를 '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'로 업데이트해야 합니다. @@ -1276,4 +1311,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf index 5f5447d2cd1ec5..05433b6de67407 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf @@ -147,6 +147,16 @@ Hosting modelu COM platformy .NET z elementem „EnableComHosting” nie obsługuje interfejsów z atrybutem „GeneratedComInterfaceAttribute” + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. Wartość zwracana w definicji zarządzanej zostanie przekonwertowana na parametr „out” podczas wywoływania niezarządzanej metody COM. Jeśli wartość zwracana ma być kodem HRESULT zwracanym przez niezarządzaną metodę COM, należy użyć „[PreserveSig]” w metodzie. @@ -447,6 +457,11 @@ Ten typ będzie traktowany jako struktura w podpisie natywnym, a nie jako natywny wynik HRESULT + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + The '[In]' attribute is not supported unless the '[Out]' attribute is also used. Blittable arrays cannot be marshalled as '[In]' only. Atrybut „[In]” nie jest obsługiwany, chyba że używany jest również atrybut „[Out]”. Tablice kopiowalne nie mogą być kierowane tylko jako „[In]”. @@ -467,6 +482,11 @@ Podane atrybuty „[In]” i „[Out]” w tym parametrze nie są obsługiwane w tym parametrze. + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + + [In] and [Out] attributes Atrybuty [In] i [Out] @@ -702,6 +722,16 @@ Nieprawidłowe użycie atrybutu „VirtualMethodIndexAttribute” + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + The usage of 'LibraryImportAttribute' does not follow recommendations. + + The element type of the 'ReadOnlySpan' returned by 'GetManagedValuesSource' must be the same as the element type returned by 'GetManagedValuesDestination'. Typ elementu „ReadOnlySpan” zwracany przez element „GetManagedValuesSource” musi być taki sam jak typ elementu zwracany przez element „GetManagedValuesDestination”. @@ -903,8 +933,8 @@ - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - Atrybut „[Out]” jest obsługiwany tylko w przypadku parametrów tablicy. Rozważ użycie słów kluczowych „out” lub „ref”, aby umożliwić modyfikowanie parametru. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + Atrybut „[Out]” jest obsługiwany tylko w przypadku parametrów tablicy. Rozważ użycie słów kluczowych „out” lub „ref”, aby umożliwić modyfikowanie parametru. @@ -917,6 +947,11 @@ Typ „{0}” określa, że obsługuje skierowanie w kierunku „Out”, ale nie zapewnia metody „ToManaged”, która zwraca typ zarządzany + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + 'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. Atrybut „GeneratedComInterfaceAttribute” i „GeneratedComClassAttribute” wymagają niebezpiecznego kodu. Projekt musi zostać zaktualizowany za pomocą polecenia „<AllowUnsafeBlocks>true</AllowUnsafeBlocks>”. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf index 5eac2e488d6ee1..c608ba0d78a585 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf @@ -147,6 +147,16 @@ A hospedagem .NET COM com 'EnableComHosting' não dá suporte a interfaces com 'GeneratedComInterfaceAttribute' + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. O valor de retorno na definição gerenciada será convertido em um parâmetro 'out' ao chamar o método COM não gerenciado. Se o valor de retorno for o código HRESULT retornado pelo método COM não gerenciado, use '[PreserveSig]' no método. @@ -447,6 +457,11 @@ Este tipo será tratado como uma estrutura na assinatura nativa, não como um HRESULT nativo + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + The '[In]' attribute is not supported unless the '[Out]' attribute is also used. Blittable arrays cannot be marshalled as '[In]' only. O atributo '[In]' não é suportado, a menos que o atributo '[Out]' também seja usado. Matrizes Blittable não podem ser empacotadas apenas como '[In]'. @@ -467,6 +482,11 @@ Os atributos '[In]' e '[Out]' neste parâmetro não têm suporte neste parâmetro. + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + + [In] and [Out] attributes Atributos [In] e [Out] @@ -702,6 +722,16 @@ Uso de 'VirtualMethodIndexAttribute' inválido + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + The usage of 'LibraryImportAttribute' does not follow recommendations. + + The element type of the 'ReadOnlySpan' returned by 'GetManagedValuesSource' must be the same as the element type returned by 'GetManagedValuesDestination'. O tipo de elemento de 'ReadOnlySpan' retornado por 'GetManagedValuesSource' deve ser igual ao tipo de elemento retornado por 'GetManagedValuesDestination'. @@ -903,8 +933,8 @@ - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - O atributo "[Out]" só tem suporte em parâmetros de matriz. Considere usar palavras-chave "out" ou "ref" para tornar o parâmetro mutável. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. @@ -917,6 +947,11 @@ O tipo '{0}' especifica que ele dá suporte a marshalling na direção 'Out', mas não fornece um método 'ToManaged' que retorna o tipo gerenciado + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + 'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. "GeneratedComInterfaceAttribute" e "GeneratedComClassAttribute" exigem código não seguro. O projeto deve ser atualizado com "<AllowUnsafeBlocks>true</AllowUnsafeBlocks>". @@ -1276,4 +1311,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf index 3c763338f053c4..bee98c1d72e1f8 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf @@ -147,6 +147,16 @@ Размещение .NET COM с "EnableComHosting" не поддерживает интерфейсы с "GeneratedComInterfaceAttribute" + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. Возвращаемое значение в управляемом определении будет преобразовано в параметр "out" при вызове неуправляемого метода COM. Если возвращаемое значение должно быть кодом HRESULT, возвращаемым неуправляемым COM-методом, используйте "[PreserveSig]" в методе. @@ -447,6 +457,11 @@ Этот тип будет рассматриваться как структура в собственной подписи, а не как собственный HRESULT. + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + The '[In]' attribute is not supported unless the '[Out]' attribute is also used. Blittable arrays cannot be marshalled as '[In]' only. Атрибут "[In]" не поддерживается, если также не используется атрибут "[Out]". Преобразуемые массивы нельзя сортировать только как "[In]". @@ -467,6 +482,11 @@ Указанные атрибуты \"[In]\" и \"[Out]\" для этого параметра не поддерживаются. + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + + [In] and [Out] attributes Атрибуты [In] и [Out] @@ -702,6 +722,16 @@ Недопустимое использование VirtualMethodIndexAttribute + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + The usage of 'LibraryImportAttribute' does not follow recommendations. + + The element type of the 'ReadOnlySpan' returned by 'GetManagedValuesSource' must be the same as the element type returned by 'GetManagedValuesDestination'. Тип элемента \"ReadOnlySpan\", возвращенный методом \"GetManagedValuesSource\", должен совпадать с типом элемента, возвращаемым методом \"GetManagedValuesDestination\". @@ -903,8 +933,8 @@ - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - Атрибут "[Out]" поддерживается только для параметров массива. Рассмотрите возможность использования ключевых слов "out" или "ref", чтобы сделать параметр изменяемым. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + Атрибут "[Out]" поддерживается только для параметров массива. Рассмотрите возможность использования ключевых слов "out" или "ref", чтобы сделать параметр изменяемым. @@ -917,6 +947,11 @@ Тип \"{0}\" указывает, что поддерживает маршализацию в направлении \"наружу\", но не предоставляет метод \"ToManaged\", который возвращает управляемый тип + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + 'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. Для "GeneratedComInterfaceAttribute" и "GeneratedComClassAttribute" требуется небезопасный код. Проект необходимо обновить с использованием значения "<AllowUnsafeBlocks>true</AllowUnsafeBlocks>". diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf index b3551845a81494..ba0b8468207011 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf @@ -147,6 +147,16 @@ 'EnableComHosting' ile barındırma .NET COM, 'GeneratedComInterfaceAttribute' ile arabirimleri desteklemez + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. Yönetilen tanımdaki dönüş değeri, yönetilmeyen COM yöntemi çağrılırken 'out' parametresine dönüştürülür. Dönüş değerinin yönetilmeyen COM yöntemi tarafından döndürülen HRESULT kodu olması amaçlanmışsa, yöntemde '[PreserveSig]' kullanın. @@ -447,6 +457,11 @@ Bu tür, yerel HRESULT olarak değil, yerel imzada bir yapı olarak değerlendirilir + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + The '[In]' attribute is not supported unless the '[Out]' attribute is also used. Blittable arrays cannot be marshalled as '[In]' only. '[Out]' özniteliği de kullanılmadığı sürece '[In]' özniteliği desteklenmez. Blittable dizileri yalnızca '[In]' olarak hazırlanamaz. @@ -467,6 +482,11 @@ Bu parametrede sağlanan '[In]' ve '[Out]' öznitelikleri bu parametrede desteklenmiyor. + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + + [In] and [Out] attributes [In] ve [Out] öznitelikleri @@ -702,6 +722,16 @@ Geçersiz 'VirtualMethodIndexAttribute' kullanımı + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + The usage of 'LibraryImportAttribute' does not follow recommendations. + + The element type of the 'ReadOnlySpan' returned by 'GetManagedValuesSource' must be the same as the element type returned by 'GetManagedValuesDestination'. 'GetManagedValuesSource' tarafından döndürülen 'ReadOnlySpan' öğe türü, 'GetManagedValuesDestination' tarafından döndürülen öğe türüyle aynı olmalıdır. @@ -903,8 +933,8 @@ - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - '[Out]' özniteliği yalnızca dizi parametrelerinde desteklenir. Parametreyi değiştirilebilir yapmak için 'out' veya 'ref' anahtar sözcükleri kullanmayı düşünün. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + '[Out]' özniteliği yalnızca dizi parametrelerinde desteklenir. Parametreyi değiştirilebilir yapmak için 'out' veya 'ref' anahtar sözcükleri kullanmayı düşünün. @@ -917,6 +947,11 @@ '{0}' türü, 'Out' yönünde sıralamayı desteklediğini belirtiyor, ancak yönetilen türü döndüren bir 'ToManaged' metodu sağlamıyor + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + 'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. 'GeneratedComInterfaceAttribute' ve 'GeneratedComClassAttribute' güvenli olmayan kod gerektiriyor. Projenin '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>' ile güncelleştirilmiş olması gerekiyor. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf index 5f77e5d137a900..fd82f97082b4d8 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf @@ -147,6 +147,16 @@ 具有“EnableComHosting”的 .NET COM 托管不支持具有“GeneratedComInterfaceAttribute”的接口 + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. 调用非托管 COM 方法时,托管定义中的返回值将转换为 "out" 参数。如果返回值是非托管 COM 方法返回的 HRESULT 代码,请对方法使用 "[PreserveSig]"。 @@ -447,6 +457,11 @@ 此类型将被视为本机签名中的结构,而不是本机 HRESULT + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + The '[In]' attribute is not supported unless the '[Out]' attribute is also used. Blittable arrays cannot be marshalled as '[In]' only. 不支持“[In]”属性,除非也使用“[Out]”属性。不能仅将 Blittable 数组封送为“[In]”。 @@ -467,6 +482,11 @@ 此参数上提供的 “[In]” 和 “[Out]” 属性在此参数上不受支持。 + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + + [In] and [Out] attributes [In] 和 [Out] 属性 @@ -702,6 +722,16 @@ “VirtualMethodIndexAttribute” 使用情况无效 + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + The usage of 'LibraryImportAttribute' does not follow recommendations. + + The element type of the 'ReadOnlySpan' returned by 'GetManagedValuesSource' must be the same as the element type returned by 'GetManagedValuesDestination'. “GetManagedValuesSource” 返回的 “ReadOnlySpan” 的元素类型必须与 “GetManagedValuesDestination” 返回的元素类型相同。 @@ -903,8 +933,8 @@ - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - `[Out]` 属性仅在数组参数上受支持。请考虑使用“out”或“ref”关键字使参数可变。 + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. @@ -917,6 +947,11 @@ 类型“{0}”指定它支持按 “Out” 方向进行封送,但不提供返回托管类型的 “ToManaged” 方法 + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + 'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. “GeneratedComInterfaceAttribute”和“GeneratedComClassAttribute”需要不安全代码。必须将项目更新为“<AllowUnsafeBlocks>true</AllowUnsafeBlocks>”。 @@ -1276,4 +1311,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf index 30be4f574082e7..a1998a248b2fdf 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf @@ -147,6 +147,16 @@ 以 'EnableComHosting' 裝載的 .NET COM 不支援具有 'GeneratedComInterfaceAttribute' 的介面 + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + + + + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + + The return value in the managed definition will be converted to an 'out' parameter when calling the unmanaged COM method. If the return value is intended to be the HRESULT code returned by the unmanaged COM method, use '[PreserveSig]' on the method. 呼叫未受控 COM 方法時,受控定義中的傳回值將轉換為 'out' 參數。如果傳回值預期是未受控 COM 方法傳回的 HRESULT 代碼,請在方法上使用 '[PreserveSig]'。 @@ -447,6 +457,11 @@ 此類型會被視為原生簽章中的結構,而非原生 HRESULT + + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + + The '[In]' attribute is not supported unless the '[Out]' attribute is also used. Blittable arrays cannot be marshalled as '[In]' only. 除非也使用 '[Out]' 屬性,否則不支援 '[In]' 屬性。無法只將 Blittable 陣列整理為 '[In]'。 @@ -467,6 +482,11 @@ 此參數不支援在此參數上提供的 '[In]' 和 '[Out]' 屬性。 + + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + + [In] and [Out] attributes [In] 與 [Out] 屬性 @@ -702,6 +722,16 @@ 'VirtualMethodIndexAttribute' 使用方式無效 + + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + + + + The usage of 'LibraryImportAttribute' does not follow recommendations. + The usage of 'LibraryImportAttribute' does not follow recommendations. + + The element type of the 'ReadOnlySpan' returned by 'GetManagedValuesSource' must be the same as the element type returned by 'GetManagedValuesDestination'. 'GetManagedValuesSource' 傳回的 'ReadOnlySpan' 元素類型必須與 'GetManagedValuesDestination' 傳回的元素類型相同。 @@ -903,8 +933,8 @@ - The `[Out]` attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - 只有陣列參數才支援 '[Out]' 屬性。請考慮使用 'out' 或 'ref' 關鍵字將參數設為可變。 + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + 只有陣列參數才支援 '[Out]' 屬性。請考慮使用 'out' 或 'ref' 關鍵字將參數設為可變。 @@ -917,6 +947,11 @@ 類型 '{0}' 指定它支援以 'Out' 方向排列,但未提供傳回受管理類型的 'ToManaged' 方法 + + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + + 'GeneratedComInterfaceAttribute' and 'GeneratedComClassAttribute' require unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. 'GeneratedComInterfaceAttribute' 和 'GeneratedComClassAttribute' 需要不安全的程式碼。專案必須以 '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>' 更新。 diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/DiagnosticDescriptorProvider.cs b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/DiagnosticDescriptorProvider.cs index 2bef64490f9a4e..eb9a0237307bc3 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/DiagnosticDescriptorProvider.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/DiagnosticDescriptorProvider.cs @@ -24,6 +24,7 @@ internal sealed class DiagnosticDescriptorProvider : IDiagnosticDescriptorProvid GeneratorDiagnostic.NotSupported { NotSupportedDetails: not null, TypePositionInfo.IsManagedReturnPosition: false } => GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails, GeneratorDiagnostic.UnnecessaryData { TypePositionInfo.IsManagedReturnPosition: false } => GeneratorDiagnostics.UnnecessaryParameterMarshallingInfo, GeneratorDiagnostic.UnnecessaryData { TypePositionInfo.IsManagedReturnPosition: true } => GeneratorDiagnostics.UnnecessaryReturnMarshallingInfo, + GeneratorDiagnostic.NotRecommended => GeneratorDiagnostics.LibraryImportUsageDoesNotFollowBestPractices, { IsFatal: false } => null, { TypePositionInfo.IsManagedReturnPosition: true } => GeneratorDiagnostics.ReturnTypeNotSupported, { TypePositionInfo.IsManagedReturnPosition: false } => GeneratorDiagnostics.ParameterTypeNotSupported, diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/GeneratorDiagnostics.cs b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/GeneratorDiagnostics.cs index 2af2abadcdd607..f5fd78d48e587c 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/GeneratorDiagnostics.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/GeneratorDiagnostics.cs @@ -254,6 +254,16 @@ public class Ids DiagnosticSeverity.Warning, isEnabledByDefault: true); + /// + public static readonly DiagnosticDescriptor LibraryImportUsageDoesNotFollowBestPractices = + new DiagnosticDescriptor( + Ids.NotRecommendedGeneratedComInterfaceUsage, + GetResourceString(nameof(SR.LibraryImportUsageDoesNotFollowBestPracticesTitle)), + GetResourceString(nameof(SR.LibraryImportUsageDoesNotFollowBestPracticesMessageWithDetails)), + Category, + DiagnosticSeverity.Info, + isEnabledByDefault: true); + /// /// Report diagnostic for invalid configuration for string marshalling. /// diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/IncrementalValuesProviderExtensions.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/IncrementalValuesProviderExtensions.cs index 123d649c913cd5..5455510ac356c0 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/IncrementalValuesProviderExtensions.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/IncrementalValuesProviderExtensions.cs @@ -47,7 +47,7 @@ public static IncrementalValuesProvider SelectNormalized(this Incr return provider.Select((node, ct) => node.NormalizeWhitespace()); } - public static (IncrementalValuesProvider, IncrementalValuesProvider) Split(this IncrementalValuesProvider<(T, T2)> provider) + public static (IncrementalValuesProvider, IncrementalValuesProvider) Split(this IncrementalValuesProvider<(T, T2)> provider) { return (provider.Select(static (data, ct) => data.Item1), provider.Select(static (data, ct) => data.Item2)); } diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs index 73b8cd8eb901a9..69180eca11c190 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs @@ -431,17 +431,10 @@ private ResolvedGenerator CreateNativeCollectionMarshaller( { byValueMarshalKindSupport = ByValueMarshalKindSupportDescriptor.Default; } - else if (!elementIsBlittable || ElementTypeIsSometimesNonBlittable(elementInfo)) - { - // If the type is not blittable or is sometimes not blittable, we will generate different code when the attributes are provided. - byValueMarshalKindSupport = ByValueMarshalKindSupportDescriptor.ArrayParameter; - } else { - // If the type is always blittable, we'll generate the same code regardless of the attributes, - // but we'll allow them to make it easier to transition to source-generated code and allow users to be clear about expectations - // for values in pre-allocated buffers. - byValueMarshalKindSupport = ByValueMarshalKindSupportDescriptor.PinnedParameter; + // If we have an array, we will use the Array [In, Out] support descriptor + byValueMarshalKindSupport = ByValueMarshalKindSupportDescriptor.ArrayParameter; } // Elements in the collection must be blittable to use the pinnable marshaller. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ByValueContentsMarshalKindValidator.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ByValueContentsMarshalKindValidator.cs index 5cc2a8f9a9b261..dd7a40fb8c90e2 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ByValueContentsMarshalKindValidator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ByValueContentsMarshalKindValidator.cs @@ -27,7 +27,7 @@ public ResolvedGenerator Create(TypePositionInfo info, StubCodeContext context) private static ResolvedGenerator ValidateByValueMarshalKind(TypePositionInfo info, StubCodeContext context, ResolvedGenerator generator) { - if (generator.Generator is Forwarder || info.ByValueContentsMarshalKind == ByValueContentsMarshalKind.Default) + if (generator.Generator is Forwarder) { // Forwarder allows everything since it just forwards to a P/Invoke. // The Default marshal kind is always valid. @@ -41,6 +41,7 @@ private static ResolvedGenerator ValidateByValueMarshalKind(TypePositionInfo inf ByValueMarshalKindSupport.Supported => generator, ByValueMarshalKindSupport.NotSupported => ResolvedGenerator.ResolvedWithDiagnostics(s_forwarder, generator.Diagnostics.Add(diagnostic!)), ByValueMarshalKindSupport.Unnecessary => generator with { Diagnostics = generator.Diagnostics.Add(diagnostic!) }, + ByValueMarshalKindSupport.NotRecommended => generator with { Diagnostics = generator.Diagnostics.Add(diagnostic!) }, _ => throw new UnreachableException() }; } diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ByValueMarshalKindSupportDescriptor.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ByValueMarshalKindSupportDescriptor.cs index 1f859d34ff919b..7754e177d66063 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ByValueMarshalKindSupportDescriptor.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ByValueMarshalKindSupportDescriptor.cs @@ -3,127 +3,105 @@ using System; using System.Collections.Immutable; +using System.Diagnostics; namespace Microsoft.Interop { + public record struct ByValueMarshalKindSupportInfo(ByValueMarshalKindSupport Support, string? details) + { + public ByValueMarshalKindSupport GetSupport(TypePositionInfo info, StubCodeContext context, out GeneratorDiagnostic? diagnostic) + { + diagnostic = Support switch + { + ByValueMarshalKindSupport.Supported => null, + ByValueMarshalKindSupport.NotRecommended => + new GeneratorDiagnostic.NotRecommended(info, context) + { + Details = details + }, + ByValueMarshalKindSupport.Unnecessary => + new GeneratorDiagnostic.UnnecessaryData( + info, + context, + ImmutableArray.Create(info.ByValueMarshalAttributeLocations.OutLocation)) + { + UnnecessaryDataName = SR.InOutAttributes, + UnnecessaryDataDetails = details + }, + ByValueMarshalKindSupport.NotSupported => + new GeneratorDiagnostic.NotSupported(info, context) + { + NotSupportedDetails = details + }, + _ => throw new UnreachableException() + }; + return Support; + } + } + /// /// Provides an implementation of through /// public record ByValueMarshalKindSupportDescriptor( - ByValueMarshalKindSupport InSupport, string? InSupportDetails, - ByValueMarshalKindSupport OutSupport, string? OutSupportDetails, - ByValueMarshalKindSupport InOutSupport, string? InOutSupportDetails) + ByValueMarshalKindSupportInfo DefaultSupport, + ByValueMarshalKindSupportInfo InSupport, + ByValueMarshalKindSupportInfo OutSupport, + ByValueMarshalKindSupportInfo InOutSupport) { /// /// A default for by value parameters. [In] is allowed, but unnecessary. Out is not allowed. /// public static readonly ByValueMarshalKindSupportDescriptor Default = new ByValueMarshalKindSupportDescriptor( - InSupport: ByValueMarshalKindSupport.Unnecessary, InSupportDetails: SR.InAttributeOnlyIsDefault, - OutSupport: ByValueMarshalKindSupport.NotSupported, OutSupportDetails: SR.OutAttributeNotSupportedOnByValueParameters, - InOutSupport: ByValueMarshalKindSupport.NotSupported, InOutSupportDetails: SR.OutAttributeNotSupportedOnByValueParameters); + DefaultSupport: new(ByValueMarshalKindSupport.Supported, null), + InSupport: new(ByValueMarshalKindSupport.NotSupported, SR.InAttributeNotSupportedOnByValueParameters), + OutSupport: new(ByValueMarshalKindSupport.NotSupported, SR.OutAttributeNotSupportedOnByValueParameters), + InOutSupport: new(ByValueMarshalKindSupport.NotSupported, SR.InOutAttributeNotSupportedOnByValueParameters)); /// - /// A default for by value array parameters. [In] is allowed, but unnecessary. Out is allowed. + /// A default for by value array parameters. Default is allowed, but Not Recommended. [In], [Out], and [In, Out] are allowed /// public static readonly ByValueMarshalKindSupportDescriptor ArrayParameter = new ByValueMarshalKindSupportDescriptor( - InSupport: ByValueMarshalKindSupport.Unnecessary, InSupportDetails: SR.InAttributeOnlyIsDefault, - OutSupport: ByValueMarshalKindSupport.Supported, OutSupportDetails: null, - InOutSupport: ByValueMarshalKindSupport.Supported, InOutSupportDetails: null); - - /// - /// A default for pinned parameters. [In] is allowed, but unnecessary. Out is allowed. - /// - public static readonly ByValueMarshalKindSupportDescriptor PinnedParameter = new ByValueMarshalKindSupportDescriptor( - InSupport: ByValueMarshalKindSupport.Unnecessary, InSupportDetails: SR.InAttributeOnlyIsDefault, - OutSupport: ByValueMarshalKindSupport.Supported, OutSupportDetails: null, - InOutSupport: ByValueMarshalKindSupport.Supported, InOutSupportDetails: null); + DefaultSupport: new(ByValueMarshalKindSupport.NotRecommended, SR.PreferExplicitInOutAttributesOnArrays), + InSupport: new(ByValueMarshalKindSupport.Supported, null), + OutSupport: new(ByValueMarshalKindSupport.Supported, null), + InOutSupport: new(ByValueMarshalKindSupport.Supported, null)); /// /// Returns the support for the ByValueContentsMarshalKind, and if it is not , diagnostic is not null /// public ByValueMarshalKindSupport GetSupport(ByValueContentsMarshalKind marshalKind, TypePositionInfo info, StubCodeContext context, out GeneratorDiagnostic? diagnostic) { - if (info.IsByRef && marshalKind != ByValueContentsMarshalKind.Default) + if (info.IsByRef) { - diagnostic = new GeneratorDiagnostic.NotSupported(info, context) + // ByRef with ByValue attributes is not allowed + if (marshalKind != ByValueContentsMarshalKind.Default) { - NotSupportedDetails = SR.InOutAttributeByRefNotSupported - }; - return ByValueMarshalKindSupport.NotSupported; - } - switch (marshalKind) - { - case ByValueContentsMarshalKind.Default: - diagnostic = null; - return ByValueMarshalKindSupport.Supported; - case ByValueContentsMarshalKind.Out: - diagnostic = OutSupport switch + diagnostic = new GeneratorDiagnostic.NotSupported(info, context) { - ByValueMarshalKindSupport.Supported => null, - ByValueMarshalKindSupport.Unnecessary - => new GeneratorDiagnostic.UnnecessaryData( - info, - context, - ImmutableArray.Create(info.ByValueMarshalAttributeLocations.OutLocation)) - { - UnnecessaryDataName = SR.InOutAttributes, - UnnecessaryDataDetails = OutSupportDetails - }, - ByValueMarshalKindSupport.NotSupported - => new GeneratorDiagnostic.NotSupported( - info, - context) - { NotSupportedDetails = OutSupportDetails }, - _ => throw new UnreachableException($"Unexpected {nameof(ByValueMarshalKindSupport)} Variant: {InOutSupport}") + NotSupportedDetails = SR.InOutAttributeByRefNotSupported }; - return OutSupport; - case ByValueContentsMarshalKind.In: - diagnostic = InSupport switch - { - ByValueMarshalKindSupport.Supported => null, - ByValueMarshalKindSupport.Unnecessary - => new GeneratorDiagnostic.UnnecessaryData( - info, - context, - ImmutableArray.Create(info.ByValueMarshalAttributeLocations.InLocation)) - { - UnnecessaryDataName = SR.InOutAttributes, - UnnecessaryDataDetails = InSupportDetails - }, - ByValueMarshalKindSupport.NotSupported - => new GeneratorDiagnostic.NotSupported( - info, - context) - { NotSupportedDetails = InSupportDetails }, - _ => throw new UnreachableException($"Unexpected {nameof(ByValueMarshalKindSupport)} Variant: {InOutSupport}") - }; - return InSupport; - case ByValueContentsMarshalKind.InOut: - diagnostic = InOutSupport switch - { - ByValueMarshalKindSupport.Supported => null, - ByValueMarshalKindSupport.Unnecessary - => new GeneratorDiagnostic.UnnecessaryData( - info, - context, - ImmutableArray.Create( - info.ByValueMarshalAttributeLocations.InLocation, - info.ByValueMarshalAttributeLocations.OutLocation)) - { - UnnecessaryDataName = SR.InOutAttributes, - UnnecessaryDataDetails = InOutSupportDetails - }, - ByValueMarshalKindSupport.NotSupported - => new GeneratorDiagnostic.NotSupported( - info, - context) - { NotSupportedDetails = InOutSupportDetails }, - _ => throw new UnreachableException($"Unexpected {nameof(ByValueMarshalKindSupport)} Variant: {InOutSupport}") - }; - return InOutSupport; - default: - throw new UnreachableException($"Unexpected {nameof(ByValueContentsMarshalKind)} variant: {marshalKind}"); + return ByValueMarshalKindSupport.NotSupported; + } + // ByRef with no ByValue attributes is supported + diagnostic = null; + return ByValueMarshalKindSupport.Supported; + } + // Return can never have In or Out attributes, so can assume valid ByValue attributes + if (info.ManagedIndex < 0) + { + Debug.Assert(marshalKind is ByValueContentsMarshalKind.Default); + diagnostic = null; + return ByValueMarshalKindSupport.Supported; } + + return marshalKind switch + { + ByValueContentsMarshalKind.Default => DefaultSupport.GetSupport(info, context, out diagnostic), + ByValueContentsMarshalKind.In => InSupport.GetSupport(info, context, out diagnostic), + ByValueContentsMarshalKind.Out => OutSupport.GetSupport(info, context, out diagnostic), + ByValueContentsMarshalKind.InOut => InOutSupport.GetSupport(info, context, out diagnostic), + _ => throw new UnreachableException() + }; } } } diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/GeneratorDiagnostic.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/GeneratorDiagnostic.cs index 22444e79824c9b..02820335ec176e 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/GeneratorDiagnostic.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/GeneratorDiagnostic.cs @@ -62,5 +62,18 @@ public override DiagnosticInfo ToDiagnosticInfo(DiagnosticDescriptor descriptor, UnnecessaryDataDetails ?? ""); } } + + public sealed record NotRecommended(TypePositionInfo TypePositionInfo, StubCodeContext StubCodeContext) : GeneratorDiagnostic(TypePositionInfo, StubCodeContext, isFatal: false) + { + public string? Details { get; init; } + + public override DiagnosticInfo ToDiagnosticInfo(DiagnosticDescriptor descriptor, Location location, string elementName) + { + return DiagnosticInfo.Create( + descriptor, + location, + Details); + } + } } } diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGenerator.cs index f5e8aacdaa3c15..598ba380028946 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallingGenerator.cs @@ -83,6 +83,10 @@ public enum ByValueMarshalKindSupport /// The provided is supported but does not change behavior from the default in this scenario. /// Unnecessary, + /// + /// The provided is supported but does not follow best practices. + /// + NotRecommended, } /// diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/StaticPinnableManagedValueMarshaller.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/StaticPinnableManagedValueMarshaller.cs index 45ef61f85dbc58..039d78ed350068 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/StaticPinnableManagedValueMarshaller.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/StaticPinnableManagedValueMarshaller.cs @@ -105,7 +105,7 @@ private IEnumerable GeneratePinningPath(TypePositionInfo info, public ByValueMarshalKindSupport SupportsByValueMarshalKind(ByValueContentsMarshalKind marshalKind, TypePositionInfo info, StubCodeContext context, out GeneratorDiagnostic? diagnostic) { - return ByValueMarshalKindSupportDescriptor.PinnedParameter.GetSupport(marshalKind, info, context, out diagnostic); + return _innerMarshallingGenerator.SupportsByValueMarshalKind(marshalKind, info, context, out diagnostic); } } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/ByValueContentsMarshalling.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/ByValueContentsMarshalling.cs new file mode 100644 index 00000000000000..fdd2d33d6e7d27 --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/ByValueContentsMarshalling.cs @@ -0,0 +1,301 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Testing; +using Microsoft.Interop; +using Xunit; +using static Microsoft.Interop.UnitTests.TestUtils; +using StringMarshalling = System.Runtime.InteropServices.StringMarshalling; +using VerifyComInterfaceGenerator = Microsoft.Interop.UnitTests.Verifiers.CSharpSourceGeneratorVerifier; + +namespace ComInterfaceGenerator.Unit.Tests +{ + public class ByValueContentsMarshalling + { + private static IComInterfaceAttributeProvider GetAttributeProvider(GeneratorKind generator) + => generator switch + { + GeneratorKind.VTableIndexStubGenerator => new VirtualMethodIndexAttributeProvider(), + GeneratorKind.ComInterfaceGeneratorManagedObjectWrapper => new GeneratedComInterfaceAttributeProvider(System.Runtime.InteropServices.Marshalling.ComInterfaceOptions.ManagedObjectWrapper), + GeneratorKind.ComInterfaceGeneratorComObjectWrapper => new GeneratedComInterfaceAttributeProvider(System.Runtime.InteropServices.Marshalling.ComInterfaceOptions.ComObjectWrapper), + GeneratorKind.ComInterfaceGenerator => new GeneratedComInterfaceAttributeProvider(), + _ => throw new UnreachableException(), + }; + + public static IEnumerable ByValueMarshalAttributeOnValueTypes() + { + var codeSnippets = new CodeSnippets(GetAttributeProvider(GeneratorKind.ComInterfaceGenerator)); + const string In = "[{|#1:InAttribute|}]"; + const string Out = "[{|#2:OutAttribute|}]"; + const string paramName = "p"; + const string MarshalAsU4 = "[MarshalAs(UnmanagedType.U4)]"; + const string MarshalAsU2 = "[MarshalAs(UnmanagedType.U2)]"; + + string p = $$"""{|#0:{{paramName}}|}"""; + var diagnostic = new DiagnosticResult(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails); + var outAttributeNotSupported = diagnostic + .WithLocation(0) + .WithArguments(SR.OutAttributeNotSupportedOnByValueParameters, paramName); + var inAttributeIsNotSupported = diagnostic + .WithLocation(0) + .WithArguments(SR.InAttributeNotSupportedOnByValueParameters, paramName); + var inOutAttributeNotSupported = diagnostic + .WithLocation(0) + .WithArguments(SR.InOutAttributeNotSupportedOnByValueParameters, paramName); + + DiagnosticResult[] InIsNotSupported = [inAttributeIsNotSupported]; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In, "int", p), InIsNotSupported }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In, "byte", p), InIsNotSupported }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + MarshalAsU4, "bool", p), InIsNotSupported }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + MarshalAsU2, "char", p), InIsNotSupported }; + + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In, "string", p, (StringMarshalling.Utf8, null)), InIsNotSupported }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In, "IntClass", p) + CodeSnippets.IntClassAndMarshaller, InIsNotSupported }; + + DiagnosticResult[] OutIsNotSupported = [outAttributeNotSupported]; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out, "int", p), OutIsNotSupported }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out, "IntStruct", p) + CodeSnippets.IntStructAndMarshaller, OutIsNotSupported }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out + MarshalAsU4, "bool", p), OutIsNotSupported }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out + MarshalAsU2, "char", p), OutIsNotSupported }; + + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out, "string", p, (StringMarshalling.Utf8, null)), OutIsNotSupported }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out, "IntClass", p) + CodeSnippets.IntClassAndMarshaller, OutIsNotSupported }; + + DiagnosticResult[] InOutIsNotSupported = [inOutAttributeNotSupported]; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out, "int", p), InOutIsNotSupported }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out, "IntStruct", p) + CodeSnippets.IntStructAndMarshaller, InOutIsNotSupported }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out + MarshalAsU4, "bool", p), InOutIsNotSupported }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out + MarshalAsU2, "char", p), InOutIsNotSupported }; + + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out, "string", p, (StringMarshalling.Utf8, null)), InOutIsNotSupported }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out, "IntClass", p) + CodeSnippets.IntClassAndMarshaller, InOutIsNotSupported }; + + // Any ref keyword is okay for non-collection types + DiagnosticResult[] None = []; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType("out", "IntStruct", p) + CodeSnippets.IntStructAndMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType("out", "byte", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalAsU4 + "out", "bool", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalAsU2 + "out", "char", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType("out", "string", p, (StringMarshalling.Utf8, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType("out", "IntClass", p) + CodeSnippets.IntClassAndMarshaller, None }; + + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType("in", "IntStruct", p) + CodeSnippets.IntStructAndMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType("in", "byte", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalAsU4 + "in", "bool", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalAsU2 + "in", "char", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType("in", "string", p, (StringMarshalling.Utf8, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType("in", "IntClass", p) + CodeSnippets.IntClassAndMarshaller, None }; + + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType("ref", "IntStruct", p) + CodeSnippets.IntStructAndMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType("ref", "byte", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalAsU4 + "ref", "bool", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalAsU2 + "ref", "char", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType("ref", "string", p, (StringMarshalling.Utf8, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType("ref", "IntClass", p) + CodeSnippets.IntClassAndMarshaller, None }; + } + + public static IEnumerable ByValueMarshalAttributeOnPinnedMarshalledTypes() + { + var codeSnippets = new CodeSnippets(GetAttributeProvider(GeneratorKind.ComInterfaceGenerator)); + const string In = "[{|#1:InAttribute|}]"; + const string Out = "[{|#2:OutAttribute|}]"; + const string paramName = "p"; + string p = $$"""{|#0:{{paramName}}|}"""; + const string Count = @"[MarshalUsing(ConstantElementCount = 10)]"; + const string MarshalAsBoolArray = "[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeConst = 10)]"; + const string MarshalUsingIntMarshaller = "[MarshalUsing(typeof(IntMarshaller), ElementIndirectionDepth = 1)]"; + const string MarshalUsingIntStructMarshaller = "[MarshalUsing(typeof(IntStructMarshaller), ElementIndirectionDepth = 1)]"; + const string MarshalUsingIntClassMarshaller = "[MarshalUsing(typeof(IntClassMarshaller), ElementIndirectionDepth = 1)]"; + + // Any explicit [In] or [Out] on an array is preferred and should not warn + DiagnosticResult[] None = []; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Count, "int[]", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Count, "char[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + MarshalAsBoolArray, "bool[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + MarshalUsingIntMarshaller + Count, "int[]", p) + CodeSnippets.IntMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Count, "string[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Count, "string[]", p, (StringMarshalling.Utf8, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Count + MarshalUsingIntStructMarshaller, "IntStruct[]", p) + CodeSnippets.IntStructAndMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Count + MarshalUsingIntClassMarshaller, "IntClass[]", p) + CodeSnippets.IntClassAndMarshaller, None }; + + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out + Count, "int[]", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out + Count, "char[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out + MarshalAsBoolArray, "bool[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out + MarshalUsingIntMarshaller + Count, "int[]", p) + CodeSnippets.IntMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out + Count, "string[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out + Count, "string[]", p, (StringMarshalling.Utf8, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out + Count + MarshalUsingIntStructMarshaller, "IntStruct[]", p) + CodeSnippets.IntStructAndMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(In + Out + Count + MarshalUsingIntClassMarshaller, "IntClass[]", p) + CodeSnippets.IntClassAndMarshaller, None }; + + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out + Count, "int[]", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out + Count, "char[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out + MarshalAsBoolArray, "bool[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out + MarshalUsingIntMarshaller + Count, "int[]", p) + CodeSnippets.IntMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out + Count, "string[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out + Count, "string[]", p, (StringMarshalling.Utf8, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out + Count + MarshalUsingIntStructMarshaller, "IntStruct[]", p) + CodeSnippets.IntStructAndMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Out + Count + MarshalUsingIntClassMarshaller, "IntClass[]", p) + CodeSnippets.IntClassAndMarshaller, None }; + + // Array parameters without [In] or [Out] should provide an Info diagnostic + var preferExplicitAttributesDiagnostic = new DiagnosticResult(GeneratorDiagnostics.GeneratedComInterfaceUsageDoesNotFollowBestPractices) + .WithLocation(0) + .WithArguments(SR.PreferExplicitInOutAttributesOnArrays); + DiagnosticResult[] PreferInOutAttributes = [preferExplicitAttributesDiagnostic]; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "int[]", p), PreferInOutAttributes }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "char[]", p, (StringMarshalling.Utf16, null)), PreferInOutAttributes }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalAsBoolArray, "bool[]", p, (StringMarshalling.Utf16, null)), PreferInOutAttributes }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalUsingIntMarshaller + Count, "int[]", p) + CodeSnippets.IntMarshaller, PreferInOutAttributes }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "string[]", p, (StringMarshalling.Utf16, null)), PreferInOutAttributes }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "string[]", p, (StringMarshalling.Utf8, null)), PreferInOutAttributes }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count + MarshalUsingIntStructMarshaller, "IntStruct[]", p) + CodeSnippets.IntStructAndMarshaller, PreferInOutAttributes }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count + MarshalUsingIntClassMarshaller, "IntClass[]", p) + CodeSnippets.IntClassAndMarshaller, PreferInOutAttributes }; + + // Ref Kinds shouldn't warn + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "in int[]", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "in char[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalAsBoolArray, "in bool[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalUsingIntMarshaller + Count, "in int[]", p) + CodeSnippets.IntMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "in string[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "in string[]", p, (StringMarshalling.Utf8, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count + MarshalUsingIntStructMarshaller, "in IntStruct[]", p) + CodeSnippets.IntStructAndMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count + MarshalUsingIntClassMarshaller, "in IntClass[]", p) + CodeSnippets.IntClassAndMarshaller, None }; + + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "out int[]", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "out char[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalAsBoolArray, "out bool[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalUsingIntMarshaller + Count, "out int[]", p) + CodeSnippets.IntMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "out string[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "out string[]", p, (StringMarshalling.Utf8, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count + MarshalUsingIntStructMarshaller, "out IntStruct[]", p) + CodeSnippets.IntStructAndMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count + MarshalUsingIntClassMarshaller, "out IntClass[]", p) + CodeSnippets.IntClassAndMarshaller, None }; + + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "ref int[]", p), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "ref char[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalAsBoolArray, "ref bool[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(MarshalUsingIntMarshaller + Count, "ref int[]", p) + CodeSnippets.IntMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "ref string[]", p, (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count, "ref string[]", p, (StringMarshalling.Utf8, null)), None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count + MarshalUsingIntStructMarshaller, "ref IntStruct[]", p) + CodeSnippets.IntStructAndMarshaller, None }; + yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(Count + MarshalUsingIntClassMarshaller, "ref IntClass[]", p) + CodeSnippets.IntClassAndMarshaller, None }; + } + + public static IEnumerable ByValueMarshalAttributeOnCustomCollections() + { + var codeSnippets = new CodeSnippets(GetAttributeProvider(GeneratorKind.ComInterfaceGenerator)); + const string In = "[{|#1:InAttribute|}]"; + const string Out = "[{|#2:OutAttribute|}]"; + const string paramName = "p"; + string p = $$"""{|#0:{{paramName}}|}"""; + const string CollectionMarshaller = "StatelessCollectionAllShapesMarshaller<,>"; + + var diagnostic = new DiagnosticResult(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails); + var outAttributeNotSupported = diagnostic + .WithLocation(0) + .WithArguments(SR.OutAttributeNotSupportedOnByValueParameters, paramName); + var inAttributeIsNotSupported = diagnostic + .WithLocation(0) + .WithArguments(SR.InAttributeNotSupportedOnByValueParameters, paramName); + var inOutAttributeNotSupported = diagnostic + .WithLocation(0) + .WithArguments(SR.InOutAttributeNotSupportedOnByValueParameters, paramName); + + DiagnosticResult[] InIsNotSupported = [inAttributeIsNotSupported]; + DiagnosticResult[] OutIsNotSupported = [outAttributeNotSupported]; + DiagnosticResult[] InOutIsNotSupported = [inOutAttributeNotSupported]; + DiagnosticResult[] None = []; + + yield return new object[] { ID(), Source("", "int"), None }; + yield return new object[] { ID(), Source("", "byte"), None }; + yield return new object[] { ID(), Source(MarshalUsing("IntClassMarshaller", 1), "IntClass") + CodeSnippets.IntClassAndMarshaller, None }; + yield return new object[] { ID(), Source(MarshalUsing("IntStructMarshaller", 1), "IntStruct") + CodeSnippets.IntStructAndMarshaller, None }; + yield return new object[] { ID(), Source("", "string", (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), Source("", "string", (StringMarshalling.Utf8, null)), None }; + yield return new object[] { ID(), Source(MarshalCollection(1), CodeSnippets.GetCustomCollectionType("int")), None }; + + // [In] and [Out] are not allowed on custom collections + yield return new object[] { ID(), Source(In, "int"), InIsNotSupported }; + yield return new object[] { ID(), Source(In, "byte"), InIsNotSupported }; + yield return new object[] { ID(), Source(In + MarshalUsing("IntClassMarshaller", 1), "IntClass") + CodeSnippets.IntClassAndMarshaller, InIsNotSupported }; + yield return new object[] { ID(), Source(In + MarshalUsing("IntStructMarshaller", 1), "IntStruct") + CodeSnippets.IntStructAndMarshaller, InIsNotSupported }; + yield return new object[] { ID(), Source(In, "string", (StringMarshalling.Utf16, null)), InIsNotSupported }; + yield return new object[] { ID(), Source(In, "string", (StringMarshalling.Utf8, null)), InIsNotSupported }; + yield return new object[] { ID(), Source(In + MarshalCollection(1), CodeSnippets.GetCustomCollectionType("int")), InIsNotSupported }; + + yield return new object[] { ID(), Source(Out, "int"), OutIsNotSupported }; + yield return new object[] { ID(), Source(Out, "byte"), OutIsNotSupported }; + yield return new object[] { ID(), Source(Out + MarshalUsing("IntClassMarshaller", 1), "IntClass") + CodeSnippets.IntClassAndMarshaller, OutIsNotSupported }; + yield return new object[] { ID(), Source(Out + MarshalUsing("IntStructMarshaller", 1), "IntStruct") + CodeSnippets.IntStructAndMarshaller, OutIsNotSupported }; + yield return new object[] { ID(), Source(Out, "string", (StringMarshalling.Utf16, null)), OutIsNotSupported }; + yield return new object[] { ID(), Source(Out, "string", (StringMarshalling.Utf8, null)), OutIsNotSupported }; + yield return new object[] { ID(), Source(Out + MarshalCollection(1), CodeSnippets.GetCustomCollectionType("int")), OutIsNotSupported }; + + yield return new object[] { ID(), Source(In + Out, "int"), InOutIsNotSupported }; + yield return new object[] { ID(), Source(In + Out, "byte"), InOutIsNotSupported }; + yield return new object[] { ID(), Source(In + Out + MarshalUsing("IntClassMarshaller", 1), "IntClass") + CodeSnippets.IntClassAndMarshaller, InOutIsNotSupported }; + yield return new object[] { ID(), Source(In + Out + MarshalUsing("IntStructMarshaller", 1), "IntStruct") + CodeSnippets.IntStructAndMarshaller, InOutIsNotSupported }; + yield return new object[] { ID(), Source(In + Out, "string", (StringMarshalling.Utf16, null)), InOutIsNotSupported }; + yield return new object[] { ID(), Source(In + Out, "string", (StringMarshalling.Utf8, null)), InOutIsNotSupported }; + yield return new object[] { ID(), Source(In + Out + MarshalCollection(1), CodeSnippets.GetCustomCollectionType("int")), InOutIsNotSupported }; + + // RefKind modifiers are okay + yield return new object[] { ID(), SourceWithRefKind("in", "", "int"), None }; + yield return new object[] { ID(), SourceWithRefKind("in", "", "byte"), None }; + yield return new object[] { ID(), SourceWithRefKind("in", MarshalUsing("IntClassMarshaller", 1), "IntClass") + CodeSnippets.IntClassAndMarshaller, None }; + yield return new object[] { ID(), SourceWithRefKind("in", MarshalUsing("IntStructMarshaller", 1), "IntStruct") + CodeSnippets.IntStructAndMarshaller, None }; + yield return new object[] { ID(), SourceWithRefKind("in", "", "string", (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), SourceWithRefKind("in", "", "string", (StringMarshalling.Utf8, null)), None }; + yield return new object[] { ID(), SourceWithRefKind("in", MarshalCollection(1), CodeSnippets.GetCustomCollectionType("int")), None }; + + yield return new object[] { ID(), SourceWithRefKind("out", "", "int"), None }; + yield return new object[] { ID(), SourceWithRefKind("out", "", "byte"), None }; + yield return new object[] { ID(), SourceWithRefKind("out", MarshalUsing("IntClassMarshaller", 1), "IntClass") + CodeSnippets.IntClassAndMarshaller, None }; + yield return new object[] { ID(), SourceWithRefKind("out", MarshalUsing("IntStructMarshaller", 1), "IntStruct") + CodeSnippets.IntStructAndMarshaller, None }; + yield return new object[] { ID(), SourceWithRefKind("out", "", "string", (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), SourceWithRefKind("out", "", "string", (StringMarshalling.Utf8, null)), None }; + yield return new object[] { ID(), SourceWithRefKind("out", MarshalCollection(1), CodeSnippets.GetCustomCollectionType("int")), None }; + + yield return new object[] { ID(), SourceWithRefKind("ref", "", "int"), None }; + yield return new object[] { ID(), SourceWithRefKind("ref", "", "byte"), None }; + yield return new object[] { ID(), SourceWithRefKind("ref", MarshalUsing("IntClassMarshaller", 1), "IntClass") + CodeSnippets.IntClassAndMarshaller, None }; + yield return new object[] { ID(), SourceWithRefKind("ref", MarshalUsing("IntStructMarshaller", 1), "IntStruct") + CodeSnippets.IntStructAndMarshaller, None }; + yield return new object[] { ID(), SourceWithRefKind("ref", "", "string", (StringMarshalling.Utf16, null)), None }; + yield return new object[] { ID(), SourceWithRefKind("ref", "", "string", (StringMarshalling.Utf8, null)), None }; + yield return new object[] { ID(), SourceWithRefKind("ref", MarshalCollection(1), CodeSnippets.GetCustomCollectionType("int")), None }; + + string Source(string Attributes, string type, (StringMarshalling StringMarshalling, Type? StringMarshallingCustomType)? stringMarshalling = null) + => SourceWithRefKind("", Attributes, type, stringMarshalling); + + string SourceWithRefKind(string refKind, string Attributes, string type, (StringMarshalling StringMarshalling, Type? StringMarshallingCustomType)? stringMarshalling = null) + { + return codeSnippets.ByValueMarshallingOfType(Attributes + MarshalCollection(), CodeSnippets.GetCustomCollectionType(type), p, stringMarshalling) + CodeSnippets.CustomCollectionAndMarshaller; + } + static string MarshalUsing(string marshaller = CollectionMarshaller, int depth = 0) + => $"[MarshalUsing(typeof({marshaller}), ElementIndirectionDepth = {depth})]"; + static string MarshalCollection(int depth = 0) + => $"[MarshalUsing(typeof({CollectionMarshaller}), ElementIndirectionDepth = {depth}, ConstantElementCount = 10)]"; + } + + + + [Theory] + [MemberData(nameof(ByValueMarshalAttributeOnPinnedMarshalledTypes))] + [MemberData(nameof(ByValueMarshalAttributeOnValueTypes))] + [MemberData(nameof(ByValueMarshalAttributeOnCustomCollections))] + public async Task VerifyByValueMarshallingAttributeUsageInfoMessages(string id, string source, DiagnosticResult[] diagnostics) + { + _ = id; + VerifyComInterfaceGenerator.Test test = new(referenceAncillaryInterop: false) + { + TestCode = source, + TestBehaviors = TestBehaviors.SkipGeneratedSourcesCheck, + }; + test.DisabledDiagnostics.Remove(GeneratorDiagnostics.Ids.NotRecommendedGeneratedComInterfaceUsage); + test.ExpectedDiagnostics.AddRange(diagnostics); + await test.RunAsync(); + } + } +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CodeSnippets.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CodeSnippets.cs index b013d8c26c4599..700797fcb3e888 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CodeSnippets.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CodeSnippets.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -12,12 +13,26 @@ namespace ComInterfaceGenerator.Unit.Tests { internal partial class CodeSnippets { + internal static IComInterfaceAttributeProvider GetAttributeProvider(GeneratorKind generator) + => generator switch + { + GeneratorKind.VTableIndexStubGenerator => new VirtualMethodIndexAttributeProvider(), + GeneratorKind.ComInterfaceGeneratorManagedObjectWrapper => new GeneratedComInterfaceAttributeProvider(System.Runtime.InteropServices.Marshalling.ComInterfaceOptions.ManagedObjectWrapper), + GeneratorKind.ComInterfaceGeneratorComObjectWrapper => new GeneratedComInterfaceAttributeProvider(System.Runtime.InteropServices.Marshalling.ComInterfaceOptions.ComObjectWrapper), + GeneratorKind.ComInterfaceGenerator => new GeneratedComInterfaceAttributeProvider(), + _ => throw new UnreachableException(), + }; + private readonly IComInterfaceAttributeProvider _attributeProvider; public CodeSnippets(IComInterfaceAttributeProvider attributeProvider) { _attributeProvider = attributeProvider; } + public CodeSnippets(GeneratorKind generator) : this(GetAttributeProvider(generator)) + { + } + private string VirtualMethodIndex( int index, bool? ImplicitThisParameter = null, @@ -49,6 +64,51 @@ private string UnmanagedCallConv(Type[]? CallConvs = null) + arguments + "]"; } + public static string GetCustomCollectionType(string elementName) => $"StatelessCollectionAllShapes<{elementName}>"; + + public const string CustomCollectionAndMarshaller = CustomCollectionDefinition + CustomCollectionAllShapesMarshaller; + public const string CustomCollectionDefinition = """ + internal class StatelessCollectionAllShapes + { + public T _field; + } + """; + public const string CustomCollectionAllShapesMarshaller = """ + [ContiguousCollectionMarshaller] + [CustomMarshaller(typeof(StatelessCollectionAllShapes<>), MarshalMode.Default, typeof(StatelessCollectionAllShapesMarshaller<,>))] + internal unsafe static class StatelessCollectionAllShapesMarshaller where TUnmanagedElement : unmanaged + { + public static void Free(TUnmanagedElement* unmanaged) { } + + // ToUnmanaged + public static TUnmanagedElement* AllocateContainerForUnmanagedElements(StatelessCollectionAllShapes managed, out int numElements) + => throw null; + public static System.ReadOnlySpan GetManagedValuesSource(StatelessCollectionAllShapes managed) // Can throw exceptions + => throw null; + public static System.Span GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements) // Can throw exceptions + => throw null; + public static ref TUnmanagedElement* GetPinnableReference(StatelessCollectionAllShapes managed) + => throw null; + + // Caller Allocated buffer ToUnmanaged + public static int BufferSize { get; } = 10; + public static TUnmanagedElement* AllocateContainerForUnmanagedElements(StatelessCollectionAllShapes managed, System.Span buffer, out int numElements) + => throw null; + + // ToManaged + public static StatelessCollectionAllShapes AllocateContainerForManagedElements(TUnmanagedElement* unmanaged, int numElements) + => throw null; + public static System.Span GetManagedValuesDestination(StatelessCollectionAllShapes managed) + => throw null; + public static System.ReadOnlySpan GetUnmanagedValuesSource(TUnmanagedElement* unmanaged, int numElements) + => throw null; + + //ToManaged Guaranteed marshalling + public static StatelessCollectionAllShapes AllocateContainerForManagedElementsFinally(TUnmanagedElement* unmanaged, int numElements) + => throw null; + } + """; + public static readonly string DisableRuntimeMarshalling = "[assembly:System.Runtime.CompilerServices.DisableRuntimeMarshalling]"; public static readonly string UsingSystemRuntimeInteropServicesMarshalling = "using System.Runtime.InteropServices.Marshalling;"; public const string IntMarshaller = """ diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/ComInterfaceGenerator.Unit.Tests.csproj b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/ComInterfaceGenerator.Unit.Tests.csproj index 08ca1a56fa43c8..beda4af3a72283 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/ComInterfaceGenerator.Unit.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/ComInterfaceGenerator.Unit.Tests.csproj @@ -33,6 +33,7 @@ + diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CompileFails.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CompileFails.cs index 2e4d25da3837e5..331fa54117fb04 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CompileFails.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CompileFails.cs @@ -3,9 +3,7 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices.Marshalling; using System.Threading.Tasks; using Microsoft.CodeAnalysis; @@ -14,6 +12,7 @@ using Microsoft.Interop; using Microsoft.Interop.UnitTests; using Xunit; +using static Microsoft.Interop.UnitTests.TestUtils; using StringMarshalling = System.Runtime.InteropServices.StringMarshalling; using VerifyComInterfaceGenerator = Microsoft.Interop.UnitTests.Verifiers.CSharpSourceGeneratorVerifier; @@ -21,11 +20,6 @@ namespace ComInterfaceGenerator.Unit.Tests { public class CompileFails { - private static string ID( - [CallerLineNumber] int lineNumber = 0, - [CallerFilePath] string? filePath = null) - => TestUtils.GetFileLineName(lineNumber, filePath); - public static IEnumerable ComInterfaceGeneratorSnippetsToCompile() { CodeSnippets codeSnippets = new(new GeneratedComInterfaceAttributeProvider()); @@ -54,19 +48,9 @@ public async Task ValidateComInterfaceGeneratorSnippets(string id, string source await VerifyComInterfaceGenerator.VerifySourceGeneratorAsync(source, expectedDiagnostics); } - private static IComInterfaceAttributeProvider GetAttributeProvider(GeneratorKind generator) - => generator switch - { - GeneratorKind.VTableIndexStubGenerator => new VirtualMethodIndexAttributeProvider(), - GeneratorKind.ComInterfaceGeneratorManagedObjectWrapper => new GeneratedComInterfaceAttributeProvider(System.Runtime.InteropServices.Marshalling.ComInterfaceOptions.ManagedObjectWrapper), - GeneratorKind.ComInterfaceGeneratorComObjectWrapper => new GeneratedComInterfaceAttributeProvider(System.Runtime.InteropServices.Marshalling.ComInterfaceOptions.ComObjectWrapper), - GeneratorKind.ComInterfaceGenerator => new GeneratedComInterfaceAttributeProvider(), - _ => throw new UnreachableException(), - }; - public static IEnumerable InvalidUnmanagedToManagedCodeSnippetsToCompile(GeneratorKind generator) { - CodeSnippets codeSnippets = new(GetAttributeProvider(generator)); + CodeSnippets codeSnippets = new(generator); string safeHandleMarshallerDoesNotSupportManagedToUnmanaged = string.Format(SR.ManagedToUnmanagedMissingRequiredMarshaller, "global::System.Runtime.InteropServices.Marshalling.SafeHandleMarshaller"); string safeHandleMarshallerDoesNotSupportUnmanagedToManaged = string.Format(SR.UnmanagedToManagedMissingRequiredMarshaller, "global::System.Runtime.InteropServices.Marshalling.SafeHandleMarshaller"); @@ -98,7 +82,7 @@ public static IEnumerable InvalidUnmanagedToManagedCodeSnippetsToCompi DiagnosticResult invalidReturnTypeDiagnostic = VerifyComInterfaceGenerator.Diagnostic(GeneratorDiagnostics.ReturnTypeNotSupportedWithDetails) .WithLocation(0) .WithArguments(marshallerDoesNotSupportManagedToUnmanaged, "Method"); - CustomStructMarshallingCodeSnippets customStructMarshallingCodeSnippets = new(new CodeSnippets.Bidirectional(GetAttributeProvider(generator))); + CustomStructMarshallingCodeSnippets customStructMarshallingCodeSnippets = new(new CodeSnippets.Bidirectional(CodeSnippets.GetAttributeProvider(generator))); yield return new object[] { ID(), customStructMarshallingCodeSnippets.Stateless.NativeToManagedOnlyOutParameter, new[] { invalidManagedToUnmanagedParameterDiagnostic } }; yield return new object[] { ID(), customStructMarshallingCodeSnippets.Stateless.NativeToManagedOnlyReturnValue, new[] { invalidReturnTypeDiagnostic } }; yield return new object[] { ID(), customStructMarshallingCodeSnippets.Stateless.ByValueInParameter, new[] { invalidUnmanagedToManagedParameterDiagnostic } }; @@ -113,7 +97,7 @@ public static IEnumerable StringMarshallingCodeSnippets(GeneratorKind string CustomTypeSpecifiedWithNoStringMarshallingCustom = SR.InvalidStringMarshallingConfigurationNotCustom; string StringMarshallingMustMatchBase = SR.GeneratedComInterfaceStringMarshallingMustMatchBase; - CodeSnippets codeSnippets = new(GetAttributeProvider(generator)); + CodeSnippets codeSnippets = new(generator); (StringMarshalling, Type?) utf8Marshalling = (StringMarshalling.Utf8, null); (StringMarshalling, Type?) utf16Marshalling = (StringMarshalling.Utf16, null); (StringMarshalling, Type?) customUtf16Marshalling = (StringMarshalling.Custom, typeof(Utf16StringMarshaller)); @@ -342,7 +326,7 @@ public static IEnumerable InvalidManagedToUnmanagedCodeSnippetsToCompi { // Marshallers with only support for their expected places in the signatures in // UnmanagedToManaged marshal modes. - CustomStructMarshallingCodeSnippets customStructMarshallingCodeSnippets = new(new CodeSnippets.Bidirectional(GetAttributeProvider(generator))); + CustomStructMarshallingCodeSnippets customStructMarshallingCodeSnippets = new(new CodeSnippets.Bidirectional(CodeSnippets.GetAttributeProvider(generator))); yield return new[] { ID(), customStructMarshallingCodeSnippets.Stateless.NativeToManagedOnlyInParameter }; yield return new[] { ID(), customStructMarshallingCodeSnippets.Stateless.ByValueOutParameter }; @@ -543,272 +527,6 @@ public async Task VerifyInterfaceWithLessVisibilityThanInterfaceWarns(string id, await VerifyComInterfaceGenerator.VerifySourceGeneratorAsync(source, diagnostics); } - public static IEnumerable ByValueMarshalAttributeOnValueTypes() - { - var codeSnippets = new CodeSnippets(GetAttributeProvider(GeneratorKind.ComInterfaceGenerator)); - const string inAttribute = "[{|#1:InAttribute|}]"; - const string outAttribute = "[{|#2:OutAttribute|}]"; - const string paramName = "p"; - string paramNameWithLocation = $$"""{|#0:{{paramName}}|}"""; - var inAttributeIsDefaultDiagnostic = new DiagnosticResult(GeneratorDiagnostics.UnnecessaryParameterMarshallingInfo) - .WithLocation(0) - .WithLocation(1) - .WithArguments(SR.InOutAttributes, paramName, SR.InAttributeOnlyIsDefault); - - - // [In] is default for all non-pinned marshalled types - yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute, "int", paramNameWithLocation), new DiagnosticResult[] { - inAttributeIsDefaultDiagnostic } }; - yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute, "byte", paramNameWithLocation), new DiagnosticResult[] { - inAttributeIsDefaultDiagnostic } }; - yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + "[MarshalAs(UnmanagedType.U4)]", "bool", paramNameWithLocation), new DiagnosticResult[] { - inAttributeIsDefaultDiagnostic } }; - yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + "[MarshalAs(UnmanagedType.U2)]", "char", paramNameWithLocation), new DiagnosticResult[] { - inAttributeIsDefaultDiagnostic } }; - - // [Out] is not allowed on value types passed by value - there is no indirection for the callee to make visible modifications. - var outAttributeNotSupportedOnValueParameters = new DiagnosticResult(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails) - .WithLocation(0) - .WithArguments(SR.OutAttributeNotSupportedOnByValueParameters, paramName); - yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(outAttribute, "int", paramNameWithLocation), new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters } }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType(outAttribute, "IntStruct", paramNameWithLocation) + CodeSnippets.IntStructAndMarshaller, - new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters - } }; - yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(outAttribute + "[MarshalAs(UnmanagedType.U4)]", "bool", paramNameWithLocation), new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters - } }; - yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(outAttribute, "[MarshalAs(UnmanagedType.U2)] char", paramNameWithLocation), new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters - } }; - // [In,Out] should only warn for Out attribute - yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute+outAttribute, "int", paramNameWithLocation), new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters } }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType(inAttribute+outAttribute, "IntStruct", paramNameWithLocation) + CodeSnippets.IntStructAndMarshaller, - new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters - } }; - yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + outAttribute + "[MarshalAs(UnmanagedType.U4)]", "bool", paramNameWithLocation), new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters - } }; - yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + outAttribute, "[MarshalAs(UnmanagedType.U2)] char", paramNameWithLocation), new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters - } }; - - // Any ref keyword is okay for value types - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("out", "IntStruct", paramNameWithLocation) + CodeSnippets.IntStructAndMarshaller, - new DiagnosticResult[] {} - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("out", "byte", paramNameWithLocation), - new DiagnosticResult[] {} - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("", "[MarshalAs(UnmanagedType.U2)] out char", paramNameWithLocation), - new DiagnosticResult[] {} - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("in", "IntStruct", paramNameWithLocation) + CodeSnippets.IntStructAndMarshaller, - new DiagnosticResult[] {} - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("in", "byte", paramNameWithLocation), - new DiagnosticResult[] {} - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("", "[MarshalAs(UnmanagedType.U2)] in char", paramNameWithLocation), - new DiagnosticResult[] {} - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("ref", "IntStruct", paramNameWithLocation) + CodeSnippets.IntStructAndMarshaller, - new DiagnosticResult[] {} - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("ref", "byte", paramNameWithLocation), - new DiagnosticResult[] {} - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("", "[MarshalAs(UnmanagedType.U2)] ref char", paramNameWithLocation), - new DiagnosticResult[] {} - }; - } - - public static IEnumerable ByValueMarshalAttributeOnReferenceTypes() - { - var codeSnippets = new CodeSnippets(GetAttributeProvider(GeneratorKind.ComInterfaceGenerator)); - const string inAttribute = "[{|#1:InAttribute|}]"; - const string outAttribute = "[{|#2:OutAttribute|}]"; - const string paramName = "p"; - string paramNameWithLocation = $$"""{|#0:{{paramName}}|}"""; - var inAttributeIsDefaultDiagnostic = new DiagnosticResult(GeneratorDiagnostics.UnnecessaryParameterMarshallingInfo) - .WithLocation(0) - .WithLocation(1) - .WithArguments(SR.InOutAttributes, paramName, SR.InAttributeOnlyIsDefault); - - // [In] is default - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType(inAttribute, "string", paramNameWithLocation, (StringMarshalling.Utf8, null)), - new DiagnosticResult[] { inAttributeIsDefaultDiagnostic } - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType(inAttribute, "IntClass", paramNameWithLocation) + CodeSnippets.IntClassAndMarshaller, - new DiagnosticResult[] { inAttributeIsDefaultDiagnostic } - }; - - var outNotAllowedOnRefTypes = new DiagnosticResult(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails) - .WithLocation(0) - .WithArguments(SR.OutAttributeNotSupportedOnByValueParameters, paramName); - - // [Out] is not allowed on strings - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType(outAttribute, "string", paramNameWithLocation, (StringMarshalling.Utf8, null)), - new DiagnosticResult[] { outNotAllowedOnRefTypes } - }; - - // [Out] warns on by value reference types - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType(outAttribute, "IntClass", paramNameWithLocation) + CodeSnippets.IntClassAndMarshaller, - new DiagnosticResult[] { outNotAllowedOnRefTypes } - }; - - // [In,Out] is fine on classes - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType(inAttribute + outAttribute, "IntClass", paramNameWithLocation) + CodeSnippets.IntClassAndMarshaller, - new DiagnosticResult[] { outNotAllowedOnRefTypes } - }; - - // All refkinds are okay on classes and strings - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("in", "string", paramNameWithLocation, (StringMarshalling.Utf8, null)), - new DiagnosticResult[] { } - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("in", "IntClass", paramNameWithLocation) + CodeSnippets.IntClassAndMarshaller, - new DiagnosticResult[] { } - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("out", "string", paramNameWithLocation, (StringMarshalling.Utf8, null)), - new DiagnosticResult[] { } - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("out", "IntClass", paramNameWithLocation) + CodeSnippets.IntClassAndMarshaller, - new DiagnosticResult[] { } - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("ref", "string", paramNameWithLocation, (StringMarshalling.Utf8, null)), - new DiagnosticResult[] { } - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType("ref", "IntClass", paramNameWithLocation) + CodeSnippets.IntClassAndMarshaller, - new DiagnosticResult[] { } - }; - } - - public static IEnumerable ByValueMarshalAttributeOnPinnedMarshalledTypes() - { - var codeSnippets = new CodeSnippets(GetAttributeProvider(GeneratorKind.ComInterfaceGenerator)); - const string inAttribute = "[{|#1:InAttribute|}]"; - const string outAttribute = "[{|#2:OutAttribute|}]"; - const string paramName = "p"; - string paramNameWithLocation = $$"""{|#0:{{paramName}}|}"""; - const string constElementCount = @"[MarshalUsing(ConstantElementCount = 10)]"; - var inAttributeIsDefaultDiagnostic = new DiagnosticResult(GeneratorDiagnostics.UnnecessaryParameterMarshallingInfo) - .WithLocation(0) - .WithLocation(1) - .WithArguments(SR.InOutAttributes, paramName, SR.InAttributeOnlyIsDefault); - - yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + constElementCount, "int[]", paramNameWithLocation), new DiagnosticResult[] { - inAttributeIsDefaultDiagnostic - }}; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType(inAttribute + constElementCount, "char[]", paramNameWithLocation, (StringMarshalling.Utf16, null)), - new DiagnosticResult[] { inAttributeIsDefaultDiagnostic } - }; - - // bools that are marshalled into a new array are in by default - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType( - inAttribute + "[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeConst = 10)]", - "bool[]", - paramNameWithLocation, - (StringMarshalling.Utf16, null)), - new DiagnosticResult[] { inAttributeIsDefaultDiagnostic } - }; - // Overriding marshalling with a custom marshaller makes it not pinned - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType(inAttribute, "[MarshalUsing(typeof(IntMarshaller), ElementIndirectionDepth = 1), MarshalUsing(ConstantElementCount = 10)]int[]", paramNameWithLocation) + CodeSnippets.IntMarshaller, - new DiagnosticResult[] { inAttributeIsDefaultDiagnostic } - }; - - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType(inAttribute + outAttribute + constElementCount, "int[]", paramNameWithLocation), - new DiagnosticResult[] { } - }; - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType(inAttribute + outAttribute + constElementCount, "char[]", paramNameWithLocation, (StringMarshalling.Utf16, null)), - new DiagnosticResult[] { } - }; - - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType(outAttribute + constElementCount, "int[]", paramNameWithLocation), - new DiagnosticResult[] { } - }; - - yield return new object[] { - ID(), - codeSnippets.ByValueMarshallingOfType(outAttribute + constElementCount, "char[]", paramNameWithLocation, (StringMarshalling.Utf16, null)), - new DiagnosticResult[] { } - }; - } - - [Theory] - [MemberData(nameof(ByValueMarshalAttributeOnValueTypes))] - [MemberData(nameof(ByValueMarshalAttributeOnReferenceTypes))] - [MemberData(nameof(ByValueMarshalAttributeOnPinnedMarshalledTypes))] - public async Task VerifyByValueMarshallingAttributeUsage(string id, string source, DiagnosticResult[] diagnostics) - { - _ = id; - VerifyComInterfaceGenerator.Test test = new(referenceAncillaryInterop: false) - { - TestCode = source, - TestBehaviors = TestBehaviors.SkipGeneratedSourcesCheck, - }; - test.ExpectedDiagnostics.AddRange(diagnostics); - await test.RunAsync(); - } - [Fact] public async Task VerifyNonPartialInterfaceWarns() { @@ -967,7 +685,7 @@ partial interface {|#0:J|} public static IEnumerable CountParameterIsOutSnippets() { - var g = GetAttributeProvider(GeneratorKind.ComInterfaceGenerator); + var g = CodeSnippets.GetAttributeProvider(GeneratorKind.ComInterfaceGenerator); CodeSnippets a = new(g); DiagnosticResult returnValueDiag = new DiagnosticResult(GeneratorDiagnostics.SizeOfInCollectionMustBeDefinedAtCallReturnValue) .WithLocation(1) diff --git a/src/libraries/System.Runtime.InteropServices/tests/Common/TestUtils.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/TestUtils.cs index 4d1ec3a5d2c7dd..cd065f54a48c0b 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/Common/TestUtils.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/Common/TestUtils.cs @@ -1,10 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Testing; using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -15,6 +11,10 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; using Xunit; namespace Microsoft.Interop.UnitTests @@ -51,6 +51,10 @@ public enum TestTargetFramework public static class TestUtils { + public static string ID( + [CallerLineNumber] int lineNumber = 0, + [CallerFilePath] string? filePath = null) + => TestUtils.GetFileLineName(lineNumber, filePath); internal static string GetFileLineName( [CallerLineNumber] int lineNumber = 0, [CallerFilePath] string? filePath = null) @@ -298,7 +302,7 @@ public void Stop() int count = Interlocked.Decrement(ref _count); if (count == 0) { - Environment.SetEnvironmentVariable(EnvVarName, null); + Environment.SetEnvironmentVariable(EnvVarName, null); } } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/ByValueContentsMarshalling.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/ByValueContentsMarshalling.cs new file mode 100644 index 00000000000000..e632481d52109f --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/ByValueContentsMarshalling.cs @@ -0,0 +1,135 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Testing; +using Microsoft.Interop; +using Xunit; +using static Microsoft.Interop.UnitTests.TestUtils; +using VerifyCS = Microsoft.Interop.UnitTests.Verifiers.CSharpSourceGeneratorVerifier; + +namespace LibraryImportGenerator.UnitTests +{ + public class ByValueContentsMarshalling + { + public static IEnumerable ByValueMarshalAttributeOnValueTypes() + { + CodeSnippets.ByValueParameterWithModifier("int[]", "In"); + + const string In = "InAttribute"; + const string Out = "OutAttribute"; + const string InOut = "InAttribute, OutAttribute"; + const string paramName = "p"; + const string MarshalUsingUtf16 = "MarshalUsing(typeof(Utf16StringMarshaller))"; + + var diagnostic = new DiagnosticResult(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails); + var outAttributeNotSupported = diagnostic + .WithLocation(0) + .WithArguments(SR.OutAttributeNotSupportedOnByValueParameters, paramName); + var inAttributeIsNotSupported = diagnostic + .WithLocation(0) + .WithArguments(SR.InAttributeNotSupportedOnByValueParameters, paramName); + var inOutAttributeNotSupported = diagnostic + .WithLocation(0) + .WithArguments(SR.InOutAttributeNotSupportedOnByValueParameters, paramName); + + DiagnosticResult[] InIsNotSupported = [inAttributeIsNotSupported]; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("int", In), InIsNotSupported }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("byte", In), InIsNotSupported }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("string", In + " , " + MarshalUsingUtf16), InIsNotSupported }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntStruct", In, CodeSnippets.IntStructAndMarshaller), InIsNotSupported }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntClass", In, CodeSnippets.IntClassAndMarshaller), InIsNotSupported }; + + DiagnosticResult[] OutIsNotSupported = [outAttributeNotSupported]; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("int", Out), OutIsNotSupported }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("byte", Out), OutIsNotSupported }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("string", Out + " , " + MarshalUsingUtf16), OutIsNotSupported }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntStruct", Out, CodeSnippets.IntStructAndMarshaller), OutIsNotSupported }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntClass", Out, CodeSnippets.IntClassAndMarshaller), OutIsNotSupported }; + + DiagnosticResult[] InOutIsNotSupported = [inOutAttributeNotSupported]; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("int", InOut), InOutIsNotSupported }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("byte", InOut), InOutIsNotSupported }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("string", InOut + " , " + MarshalUsingUtf16), InOutIsNotSupported }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntStruct", InOut, CodeSnippets.IntStructAndMarshaller), InOutIsNotSupported }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntClass", InOut, CodeSnippets.IntClassAndMarshaller), InOutIsNotSupported }; + + var inAndOutNotAllowedWithRefKind = new DiagnosticResult(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails) + .WithLocation(0) + .WithArguments("The '[In]' and '[Out]' attributes are unsupported on parameters passed by reference. Use the 'in', 'ref', or 'out' keywords instead.", "p"); + DiagnosticResult[] InAndOutNotAllowedWithRefKind = [inAndOutNotAllowedWithRefKind]; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("in int", In), InAndOutNotAllowedWithRefKind }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("ref int", In), InAndOutNotAllowedWithRefKind }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("ref int", InOut), InAndOutNotAllowedWithRefKind }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("out int", Out), InAndOutNotAllowedWithRefKind }; + } + + public static IEnumerable ByValueMarshalAttributeOnArrays() + { + CodeSnippets.ByValueParameterWithModifier("int[]", "In"); + + const string In = "InAttribute"; + const string Out = "OutAttribute"; + const string InOut = "InAttribute, OutAttribute"; + const string MarshalUsingUtf16 = "MarshalUsing(typeof(Utf16StringMarshaller), ElementIndirectionDepth = 1)"; + const string Count = "MarshalUsing(ConstantElementCount = 10)"; + DiagnosticResult[] None = []; + + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("int[]", string.Join(',', Count, In)), None }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("byte[]", string.Join(',', Count, In)), None }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("string[]", string.Join(',', Count, In, MarshalUsingUtf16)), None }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntStruct[]", string.Join(',', Count, In), CodeSnippets.IntStructAndMarshaller), None }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntClass[]", string.Join(',', Count, In), CodeSnippets.IntClassAndMarshaller), None }; + + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("int[]", string.Join(',', Count, Out)), None }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("byte[]", string.Join(',', Count, Out)), None }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("string[]", string.Join(',', Count, Out, MarshalUsingUtf16)), None }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntStruct[]", string.Join(',', Count, Out), CodeSnippets.IntStructAndMarshaller), None }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntClass[]", string.Join(',', Count, Out), CodeSnippets.IntClassAndMarshaller), None }; + + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("int[]", string.Join(',', Count, InOut)), None }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("byte[]", string.Join(',', Count, InOut)), None }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("string[]", string.Join(',', Count, InOut, MarshalUsingUtf16)), None }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntStruct[]", string.Join(',', Count, InOut), CodeSnippets.IntStructAndMarshaller), None }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntClass[]", string.Join(',', Count, InOut), CodeSnippets.IntClassAndMarshaller), None }; + + DiagnosticResult preferAttributes = new DiagnosticResult(GeneratorDiagnostics.LibraryImportUsageDoesNotFollowBestPractices) + .WithArguments(SR.PreferExplicitInOutAttributesOnArrays) + .WithLocation(0); + DiagnosticResult[] PreferAttributes = [preferAttributes]; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("int[]", Count), PreferAttributes }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("byte[]", Count), PreferAttributes }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("string[]", string.Join(',', Count, MarshalUsingUtf16)), PreferAttributes }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntStruct[]", Count, CodeSnippets.IntStructAndMarshaller), PreferAttributes }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("IntClass[]", Count, CodeSnippets.IntClassAndMarshaller), PreferAttributes }; + + var inAndOutNotAllowedWithRefKind = new DiagnosticResult(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails) + .WithLocation(0) + .WithArguments("The '[In]' and '[Out]' attributes are unsupported on parameters passed by reference. Use the 'in', 'ref', or 'out' keywords instead.", "p"); + DiagnosticResult[] InAndOutNotAllowedWithRefKind = [inAndOutNotAllowedWithRefKind]; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("in int[]", string.Join(',', Count, In)), InAndOutNotAllowedWithRefKind }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("ref int[]", string.Join(',', Count, In)), InAndOutNotAllowedWithRefKind }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("ref int[]", string.Join(',', Count, In, Out)), InAndOutNotAllowedWithRefKind }; + yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("out int[]", string.Join(',', Count, Out)), InAndOutNotAllowedWithRefKind }; + } + + + [Theory] + [MemberData(nameof(ByValueMarshalAttributeOnValueTypes))] + [MemberData(nameof(ByValueMarshalAttributeOnArrays))] + public async Task VerifyByValueMarshallingAttributeUsageInfoMessages(string id, string source, DiagnosticResult[] diagnostics) + { + _ = id; + VerifyCS.Test test = new(referenceAncillaryInterop: false) + { + TestCode = source, + TestBehaviors = TestBehaviors.SkipGeneratedSourcesCheck, + }; + test.DisabledDiagnostics.Remove(GeneratorDiagnostics.Ids.NotRecommendedGeneratedComInterfaceUsage); + test.ExpectedDiagnostics.AddRange(diagnostics); + await test.RunAsync(); + } + } +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CodeSnippets.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CodeSnippets.cs index e1039f70a90ef9..19832861a38aaa 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CodeSnippets.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CodeSnippets.cs @@ -986,6 +986,22 @@ out int pOutSize } """; + public const string IntClassAndMarshaller = IntClassDefinition + IntClassMarshallerDefinition; + public const string IntClassDefinition = """ + internal struct IntClass + { + public int Field; + } + """; + public const string IntClassMarshallerDefinition = """ + [CustomMarshaller(typeof(IntClass), MarshalMode.Default, typeof(IntClassMarshaller))] + internal static class IntClassMarshaller + { + public static nint ConvertToUnmanaged(IntClass managed) => (nint)0; + public static IntClass ConvertToManaged(nint unmanaged) => default; + } + """; + public const string IntStructAndMarshaller = IntStructDefinition + IntStructMarshallerDefinition; public const string IntStructDefinition = """ internal struct IntStruct diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CompileFails.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CompileFails.cs index ffb3fb5c6a14ba..2d278dc6237de2 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CompileFails.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CompileFails.cs @@ -350,56 +350,6 @@ public static IEnumerable CodeSnippetsToCompile() .WithArguments("MarshalAsAttribute", "t") }}; - // Unsupported [In, Out] attributes usage - - // By ref with [In, Out] attributes - yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("in int", "In"), new[] - { - VerifyCS.Diagnostic(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails) - .WithLocation(0) - .WithArguments("The '[In]' and '[Out]' attributes are unsupported on parameters passed by reference. Use the 'in', 'ref', or 'out' keywords instead.", "p") - } }; - yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("ref int", "In"), new[] - { - VerifyCS.Diagnostic(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails) - .WithLocation(0) - .WithArguments("The '[In]' and '[Out]' attributes are unsupported on parameters passed by reference. Use the 'in', 'ref', or 'out' keywords instead.", "p") - } }; - yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("ref int", "In, Out"), new[] - { - VerifyCS.Diagnostic(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails) - .WithLocation(0) - .WithArguments("The '[In]' and '[Out]' attributes are unsupported on parameters passed by reference. Use the 'in', 'ref', or 'out' keywords instead.", "p") - } }; - yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("out int", "Out"), new[] - { - VerifyCS.Diagnostic(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails) - .WithLocation(0) - .WithArguments("The '[In]' and '[Out]' attributes are unsupported on parameters passed by reference. Use the 'in', 'ref', or 'out' keywords instead.", "p") - } }; - - // By value non-array with [In, Out] attributes - yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("{|#1:In|}"), new [] { - VerifyCS.Diagnostic(GeneratorDiagnostics.UnnecessaryParameterMarshallingInfo) - .WithLocation(0) - .WithLocation(1) - .WithArguments(SR.InOutAttributes, "p", SR.InAttributeOnlyIsDefault) - .WithSeverity(DiagnosticSeverity.Info) - } }; - yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("Out"), new[] - { - VerifyCS.Diagnostic(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails) - .WithLocation(0) - .WithArguments(SR.OutAttributeNotSupportedOnByValueParameters, "p") - } }; - - yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("In, Out"), new[] - { - VerifyCS.Diagnostic(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails) - .WithLocation(0) - .WithArguments(SR.OutAttributeNotSupportedOnByValueParameters, "p") - } }; - // LCIDConversion yield return new object[] { ID(), CodeSnippets.LCIDConversionAttribute, new[] { VerifyCS.Diagnostic(GeneratorDiagnostics.ConfigurationNotSupported) @@ -832,13 +782,6 @@ public static IEnumerable CodeSnippetsToCompile() .WithLocation(1) .WithArguments("ref return", "Basic.RefReadonlyReturn()"), } }; - yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("{|#10:In|}"), new[] - { - VerifyCS.Diagnostic(GeneratorDiagnostics.UnnecessaryParameterMarshallingInfo) - .WithLocation(0) - .WithLocation(10) - .WithArguments("[In] and [Out] attributes", "p", SR.InAttributeOnlyIsDefault) - } }; } [Theory] diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Compiles.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Compiles.cs index 438d589b2c29d0..5d37fffd52a5b6 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Compiles.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Compiles.cs @@ -17,7 +17,6 @@ using Microsoft.CodeAnalysis.Text; using Microsoft.Interop.UnitTests; using Xunit; -using GeneratorDiagnostics = Microsoft.Interop.GeneratorDiagnostics; using VerifyCS = Microsoft.Interop.UnitTests.Verifiers.CSharpSourceGeneratorVerifier; namespace LibraryImportGenerator.UnitTests @@ -744,28 +743,5 @@ public NoChangeTest(TestTargetFramework framework) return (newCompilation, diagnostics); } } - - public static IEnumerable ByValueMarshalKindSnippets() - { - // Blittable array - yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("{|#10:Out|}"), new DiagnosticResult[] { } }; - - yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("{|#10:In|}, {|#11:Out|}"), new DiagnosticResult[] { } }; - - yield return new object[] { ID(), CodeSnippets.ByValueParameterWithModifier("{|#10:In|}"), new DiagnosticResult[] { - VerifyCS.Diagnostic(GeneratorDiagnostics.UnnecessaryParameterMarshallingInfo) - .WithLocation(0) - .WithLocation(10) - .WithArguments("[In] and [Out] attributes", "p", SR.InAttributeOnlyIsDefault) - } }; - } - - [MemberData(nameof(ByValueMarshalKindSnippets))] - [Theory] - public async Task ValidateDiagnosticsForUnnecessaryByValueMarshalKindAttributes(string id, string source, DiagnosticResult[] diagnostics) - { - _ = id; - await VerifyCS.VerifySourceGeneratorAsync(source, diagnostics); - } } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/SharedTypes.csproj b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/SharedTypes.csproj index c68eadac7ca4b4..cb767939315c84 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/SharedTypes.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/SharedTypes.csproj @@ -11,6 +11,8 @@ + + From 8cc9e079965da81a12cc5b4f35bc8549310f0ab7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 10:14:40 -0700 Subject: [PATCH 097/783] Remove AD0001 NoWarn from Microsoft.Extensions.Logging.Abstractions project (#91236) Co-authored-by: Buyaa Namnan --- .../src/Microsoft.Extensions.Logging.Abstractions.csproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj index db0c78fb49df05..085cade3966b96 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj @@ -4,8 +4,6 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true true - - $(NoWarn);AD0001 true Logging abstractions for Microsoft.Extensions.Logging. From bbaba10171c0e8d26b9d31877799d2ebe309c7ee Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 10:15:34 -0700 Subject: [PATCH 098/783] [release/8.0] Add Retry and Task.Delay to WinHttpHandler AfterReadResponseServerError_ClientWrite test (#91271) * Add Task.Delay to give more time for reset frame * Apply James' solution --------- Co-authored-by: Ahmet Ibrahim Aksoy (from Dev Box) --- .../FunctionalTests/BidirectionStreamingTest.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/BidirectionStreamingTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/BidirectionStreamingTest.cs index d18de54bc46cba..ce79f20ad4efec 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/BidirectionStreamingTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/BidirectionStreamingTest.cs @@ -143,7 +143,17 @@ public async Task AfterReadResponseServerError_ClientWrite() // Server sends RST_STREAM. await connection.WriteFrameAsync(new RstStreamFrame(FrameFlags.EndStream, 0, streamId)); - await Assert.ThrowsAsync(() => requestStream.WriteAsync(new byte[50]).AsTask()); + await Assert.ThrowsAsync(async () => + { + for (int i = 0; i < 10; i++) + { + await requestStream.WriteAsync(new byte[50]); + + // WriteAsync succeeded because handler hasn't processed RST_STREAM yet. + // Small wait before trying again. + await Task.Delay(50); + } + }); } } From 605cd300339f1c127c2c46aac425822d2cdeeb68 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 10:27:15 -0700 Subject: [PATCH 099/783] [release/8.0] JIT: Fix various HW intrinsic lowerings for unused values (#91266) * JIT: Fix LowerHWIntrinsicToScalar with unused values Fix #91173 * Fix more cases --------- Co-authored-by: Jakob Botsch Nielsen --- src/coreclr/jit/lowerarmarch.cpp | 4 +++ src/coreclr/jit/lowerxarch.cpp | 45 ++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 86a5b2b1ab4cb4..2536d44aa00c56 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -1900,6 +1900,10 @@ GenTree* Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node) { use.ReplaceWith(tmp2); } + else + { + tmp2->SetUnusedValue(); + } BlockRange().Remove(node); return tmp2->gtNext; diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index eba7bdb93e20fb..c1b5079f124545 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -3868,6 +3868,10 @@ GenTree* Lowering::LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node) { use.ReplaceWith(newIndir); } + else + { + newIndir->SetUnusedValue(); + } BlockRange().Remove(op1); BlockRange().Remove(node); @@ -3916,6 +3920,10 @@ GenTree* Lowering::LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node) { use.ReplaceWith(lclFld); } + else + { + lclFld->SetUnusedValue(); + } BlockRange().Remove(op1); BlockRange().Remove(op2); @@ -4158,6 +4166,11 @@ GenTree* Lowering::LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node) { use.ReplaceWith(cast); } + else + { + node->ClearUnusedValue(); + cast->SetUnusedValue(); + } next = LowerNode(cast); } @@ -4737,6 +4750,10 @@ GenTree* Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node) { use.ReplaceWith(tmp1); } + else + { + tmp1->SetUnusedValue(); + } BlockRange().Remove(node); return LowerNode(tmp1); @@ -5267,6 +5284,10 @@ GenTree* Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node) { use.ReplaceWith(tmp1); } + else + { + tmp1->SetUnusedValue(); + } BlockRange().Remove(node); return tmp1->gtNext; @@ -5314,6 +5335,10 @@ GenTree* Lowering::LowerHWIntrinsicToScalar(GenTreeHWIntrinsic* node) { use.ReplaceWith(newIndir); } + else + { + newIndir->SetUnusedValue(); + } BlockRange().Remove(op1); BlockRange().Remove(node); @@ -5342,6 +5367,10 @@ GenTree* Lowering::LowerHWIntrinsicToScalar(GenTreeHWIntrinsic* node) { use.ReplaceWith(lclFld); } + else + { + lclFld->SetUnusedValue(); + } BlockRange().Remove(op1); BlockRange().Remove(node); @@ -5426,6 +5455,11 @@ GenTree* Lowering::LowerHWIntrinsicToScalar(GenTreeHWIntrinsic* node) { use.ReplaceWith(cast); } + else + { + node->ClearUnusedValue(); + cast->SetUnusedValue(); + } next = LowerNode(cast); } @@ -8332,8 +8366,15 @@ void Lowering::TryFoldCnsVecForEmbeddedBroadcast(GenTreeHWIntrinsic* parentNode, BlockRange().InsertBefore(broadcastNode, createScalar); BlockRange().InsertBefore(createScalar, constScalar); LIR::Use use; - BlockRange().TryGetUse(childNode, &use); - use.ReplaceWith(broadcastNode); + if (BlockRange().TryGetUse(childNode, &use)) + { + use.ReplaceWith(broadcastNode); + } + else + { + broadcastNode->SetUnusedValue(); + } + BlockRange().Remove(childNode); LowerNode(createScalar); LowerNode(broadcastNode); From 2ec0bc7f0bbbe1bd7323fbbb00a549bf9cbae215 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 10:34:36 -0700 Subject: [PATCH 100/783] [release/8.0] [mono] Extend mono_gsharedvt_constrained_call JIT icall to handle static virtual methods (#91059) * Extend mono_gsharedvt_constrained_call JIT icall to handle static virtual methods * Handle static virtual calls in constrained_gsharedvt_call_setup * Fix lint * Add runtime test * Remove runtime test --------- Co-authored-by: Milos Kotlar --- src/mono/mono/mini/jit-icalls.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/jit-icalls.c b/src/mono/mono/mini/jit-icalls.c index 04a15e94aea165..628d18abe35cfd 100644 --- a/src/mono/mono/mini/jit-icalls.c +++ b/src/mono/mono/mini/jit-icalls.c @@ -1358,7 +1358,7 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k error_init (error); - if (mono_class_is_interface (klass) || !m_class_is_valuetype (klass)) { + if ((mono_class_is_interface (klass) || !m_class_is_valuetype (klass)) && !m_method_is_static (cmethod)) { MonoObject *this_obj; is_iface = mono_class_is_interface (klass); @@ -1390,7 +1390,12 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k } } - if (m_class_is_valuetype (klass) && (m->klass == mono_defaults.object_class || m->klass == m_class_get_parent (mono_defaults.enum_class) || m->klass == mono_defaults.enum_class)) { + if (m_method_is_static (cmethod)) { + /* + * Static calls don't have this arg + */ + *this_arg = NULL; + } else if (m_class_is_valuetype (klass) && (m->klass == mono_defaults.object_class || m->klass == m_class_get_parent (mono_defaults.enum_class) || m->klass == mono_defaults.enum_class)) { /* * Calling a non-vtype method with a vtype receiver, has to box. */ From c3a87405ada82d8424f2b713ebd3c5866a768bad Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 13:14:33 -0700 Subject: [PATCH 101/783] [release/8.0] [Mono] Fix unsafe accessor related issue for full AOT (#91270) * Fix unsafe accessor related issue for full aot * Only skip for WRAPPER_SUBTYPE_UNSAFE_ACCESSOR --------- Co-authored-by: Fan Yang --- src/mono/mono/mini/aot-compiler.c | 10 ++++++---- src/mono/mono/mini/method-to-ir.c | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 1944a77d2c00b0..023cd6ce42b0b5 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -3844,10 +3844,12 @@ encode_method_ref (MonoAotCompile *acfg, MonoMethod *method, guint8 *buf, guint8 else if (info->subtype == WRAPPER_SUBTYPE_UNSAFE_ACCESSOR) { encode_method_ref (acfg, info->d.unsafe_accessor.method, p, &p); encode_value (info->d.unsafe_accessor.kind, p, &p); - /* WISH: is there some kind of string heap token we could use here? */ - uint32_t len = (uint32_t) strlen (info->d.unsafe_accessor.member_name); - encode_value (len, p, &p); - encode_string (info->d.unsafe_accessor.member_name, p, &p); + if (info->d.unsafe_accessor.member_name) { + /* WISH: is there some kind of string heap token we could use here? */ + uint32_t len = (uint32_t) strlen (info->d.unsafe_accessor.member_name); + encode_value (len, p, &p); + encode_string (info->d.unsafe_accessor.member_name, p, &p); + } } else if (info->subtype == WRAPPER_SUBTYPE_INTERP_IN) encode_signature (acfg, info->d.interp_in.sig, p, &p); diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index e3605981bafcdf..dedc6804c3cbd8 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -6452,8 +6452,18 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b generic_context = &generic_container->context; cfg->generic_context = generic_context; - if (!cfg->gshared) - g_assert (!sig->has_type_parameters); + if (!cfg->gshared) { + gboolean check_type_parameter = TRUE; + if (method->wrapper_type == MONO_WRAPPER_OTHER) { + WrapperInfo *info = mono_marshal_get_wrapper_info (method); + g_assert (info); + if (info->subtype == WRAPPER_SUBTYPE_UNSAFE_ACCESSOR) + check_type_parameter = FALSE; + } + + if (check_type_parameter) + g_assert (!sig->has_type_parameters); + } if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) { g_assert (method->is_inflated); From 776a845159b69a665935bfc297942a86399cf28a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 16:26:14 -0700 Subject: [PATCH 102/783] Disable failing test (#91269) Co-authored-by: Fan Yang --- src/tests/issues.targets | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tests/issues.targets b/src/tests/issues.targets index b867b9134b5732..e9485d290e2d5d 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -2712,6 +2712,9 @@ https://github.com/dotnet/runtime/issues/82859 + + https://github.com/dotnet/runtime/issues/90605 + From dddf0d0f8260cde735e8469862eb031ed8413409 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Wed, 30 Aug 2023 01:26:43 +0200 Subject: [PATCH 103/783] backport 90388 to Net8 (#91201) --- .../sample/wasm/browser-advanced/index.html | 5 +- src/mono/sample/wasm/browser-advanced/main.js | 1 + .../wasm/browser-bench/appstart-frame.html | 3 -- .../sample/wasm/browser-bench/frame-main.js | 5 +- src/mono/wasm/features.md | 3 +- src/mono/wasm/runtime/exports.ts | 4 +- src/mono/wasm/runtime/globals.ts | 1 - src/mono/wasm/runtime/loader/assets.ts | 18 +++----- src/mono/wasm/runtime/loader/config.ts | 19 ++++---- src/mono/wasm/runtime/loader/exit.ts | 2 +- src/mono/wasm/runtime/loader/globals.ts | 1 + src/mono/wasm/runtime/loader/run.ts | 6 +-- src/mono/wasm/runtime/snapshot.ts | 23 ++++++++-- src/mono/wasm/runtime/startup.ts | 46 ++++++++----------- src/mono/wasm/runtime/types/internal.ts | 6 ++- 15 files changed, 74 insertions(+), 69 deletions(-) diff --git a/src/mono/sample/wasm/browser-advanced/index.html b/src/mono/sample/wasm/browser-advanced/index.html index c8961d7c715408..24d51ea29672d6 100644 --- a/src/mono/sample/wasm/browser-advanced/index.html +++ b/src/mono/sample/wasm/browser-advanced/index.html @@ -13,10 +13,7 @@ - - - - + diff --git a/src/mono/sample/wasm/browser-advanced/main.js b/src/mono/sample/wasm/browser-advanced/main.js index f95fcbf9903be6..b5c414322fefd0 100644 --- a/src/mono/sample/wasm/browser-advanced/main.js +++ b/src/mono/sample/wasm/browser-advanced/main.js @@ -31,6 +31,7 @@ try { // here we show how emscripten could be further configured // It is preferred to use specific 'with***' methods instead in all other cases. .withConfig({ + startupMemoryCache: true, resources: { modulesAfterConfigLoaded: { "advanced-sample.lib.module.js": "" diff --git a/src/mono/sample/wasm/browser-bench/appstart-frame.html b/src/mono/sample/wasm/browser-bench/appstart-frame.html index 5bb75e32aa1b75..481ffa4e27301f 100644 --- a/src/mono/sample/wasm/browser-bench/appstart-frame.html +++ b/src/mono/sample/wasm/browser-bench/appstart-frame.html @@ -12,9 +12,6 @@ - - - diff --git a/src/mono/sample/wasm/browser-bench/frame-main.js b/src/mono/sample/wasm/browser-bench/frame-main.js index c1042928d78d07..88358e0310a10b 100644 --- a/src/mono/sample/wasm/browser-bench/frame-main.js +++ b/src/mono/sample/wasm/browser-bench/frame-main.js @@ -31,6 +31,10 @@ try { } const runtime = await dotnet + .withConfig({ + maxParallelDownloads: 10000, + // diagnosticTracing:true, + }) .withModuleConfig({ printErr: () => undefined, print: () => undefined, @@ -38,7 +42,6 @@ try { if (window.parent != window) { window.parent.resolveAppStartEvent("onConfigLoaded"); } - // config.diagnosticTracing = true; } }) .create(); diff --git a/src/mono/wasm/features.md b/src/mono/wasm/features.md index 46aa26d85038e1..c131002dde7968 100644 --- a/src/mono/wasm/features.md +++ b/src/mono/wasm/features.md @@ -193,12 +193,13 @@ See also [fetch integrity on MDN](https://developer.mozilla.org/en-US/docs/Web/A ### Pre-fetching In order to start downloading application resources as soon as possible you can add HTML elements to `` of your page similar to: +Adding too many files into prefetch could be counterproductive. +Please benchmark your startup performance on real target devices and with realistic network conditions. ```html - ``` See also [link rel prefetch on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/prefetch) diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index a29fd2da59d84f..6e50e26e164c0c 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -8,7 +8,7 @@ import type { RuntimeAPI } from "./types"; import { Module, linkerDisableLegacyJsInterop, exportedRuntimeAPI, passEmscriptenInternals, runtimeHelpers, setRuntimeGlobals, } from "./globals"; import { GlobalObjects, is_nullish } from "./types/internal"; -import { configureEmscriptenStartup, configureWorkerStartup } from "./startup"; +import { configureEmscriptenStartup, configureRuntimeStartup, configureWorkerStartup } from "./startup"; import { create_weak_ref } from "./weak-ref"; import { export_internal } from "./exports-internal"; @@ -143,5 +143,5 @@ class RuntimeList { // export external API export { - passEmscriptenInternals, initializeExports, initializeReplacements, configureEmscriptenStartup, configureWorkerStartup, setRuntimeGlobals + passEmscriptenInternals, initializeExports, initializeReplacements, configureRuntimeStartup, configureEmscriptenStartup, configureWorkerStartup, setRuntimeGlobals }; \ No newline at end of file diff --git a/src/mono/wasm/runtime/globals.ts b/src/mono/wasm/runtime/globals.ts index 5db69fc91bf619..b14bafd5ed2d7b 100644 --- a/src/mono/wasm/runtime/globals.ts +++ b/src/mono/wasm/runtime/globals.ts @@ -59,7 +59,6 @@ export function setRuntimeGlobals(globalObjects: GlobalObjects) { gitHash, allAssetsInMemory: createPromiseController(), dotnetReady: createPromiseController(), - memorySnapshotSkippedOrDone: createPromiseController(), afterInstantiateWasm: createPromiseController(), beforePreInit: createPromiseController(), afterPreInit: createPromiseController(), diff --git a/src/mono/wasm/runtime/loader/assets.ts b/src/mono/wasm/runtime/loader/assets.ts index ba18815a08db80..be7c0e4592938b 100644 --- a/src/mono/wasm/runtime/loader/assets.ts +++ b/src/mono/wasm/runtime/loader/assets.ts @@ -78,8 +78,6 @@ const containedInSnapshotByAssetTypes: { "pdb": true, "heap": true, "icu": true, - ...jsModulesAssetTypes, - "dotnetwasm": true, }; // these assets are instantiated differently than the main flow @@ -95,7 +93,7 @@ export function shouldLoadIcuAsset(asset: AssetEntryInternal): boolean { return !(asset.behavior == "icu" && asset.name != loaderHelpers.preferredIcuAsset); } -function convert_single_asset(modulesAssets: AssetEntryInternal[], resource: ResourceList | undefined, behavior: SingleAssetBehaviors): AssetEntryInternal { +function convert_single_asset(assetsCollection: AssetEntryInternal[], resource: ResourceList | undefined, behavior: SingleAssetBehaviors): AssetEntryInternal { const keys = Object.keys(resource || {}); mono_assert(keys.length == 1, `Expect to have one ${behavior} asset in resources`); @@ -110,7 +108,7 @@ function convert_single_asset(modulesAssets: AssetEntryInternal[], resource: Res set_single_asset(asset); // so that we can use it on the worker too - modulesAssets.push(asset); + assetsCollection.push(asset); return asset; } @@ -168,15 +166,12 @@ export async function mono_download_assets(): Promise { countAndStartDownload(asset); } - // continue after the dotnet.runtime.js was loaded - await loaderHelpers.runtimeModuleLoaded.promise; - // continue after we know if memory snapshot is available or not - await runtimeHelpers.memorySnapshotSkippedOrDone.promise; + await loaderHelpers.memorySnapshotSkippedOrDone.promise; // start fetching assets in parallel, only if memory snapshot is not available. for (const asset of containedInSnapshotAssets) { - if (!runtimeHelpers.loadedMemorySnapshot) { + if (!runtimeHelpers.loadedMemorySnapshotSize) { countAndStartDownload(asset); } else { // Otherwise cleanup in case we were given pending download. It would be even better if we could abort the download. @@ -193,6 +188,8 @@ export async function mono_download_assets(): Promise { } loaderHelpers.allDownloadsQueued.promise_control.resolve(); + + // continue after the dotnet.runtime.js was loaded await loaderHelpers.runtimeModuleLoaded.promise; const promises_of_asset_instantiation: Promise[] = []; @@ -211,7 +208,6 @@ export async function mono_download_assets(): Promise { // wait till after onRuntimeInitialized and after memory snapshot is loaded or skipped await runtimeHelpers.beforeOnRuntimeInitialized.promise; - await runtimeHelpers.memorySnapshotSkippedOrDone.promise; runtimeHelpers.instantiate_asset(asset, url, data); } } else { @@ -284,7 +280,7 @@ export function prepareAssets() { mono_assert(resources.jsModuleNative, "resources.jsModuleNative must be defined"); mono_assert(resources.jsModuleRuntime, "resources.jsModuleRuntime must be defined"); mono_assert(!MonoWasmThreads || resources.jsModuleWorker, "resources.jsModuleWorker must be defined"); - convert_single_asset(modulesAssets, resources.wasmNative, "dotnetwasm"); + convert_single_asset(alwaysLoadedAssets, resources.wasmNative, "dotnetwasm"); convert_single_asset(modulesAssets, resources.jsModuleNative, "js-module-native"); convert_single_asset(modulesAssets, resources.jsModuleRuntime, "js-module-runtime"); if (MonoWasmThreads) { diff --git a/src/mono/wasm/runtime/loader/config.ts b/src/mono/wasm/runtime/loader/config.ts index c35553ae593e8c..097f6d1ca2cb15 100644 --- a/src/mono/wasm/runtime/loader/config.ts +++ b/src/mono/wasm/runtime/loader/config.ts @@ -10,6 +10,7 @@ import { importLibraryInitializers, invokeLibraryInitializers } from "./libraryI import { mono_exit } from "./exit"; import { makeURLAbsoluteWithApplicationBase } from "./polyfills"; import { appendUniqueQuery } from "./assets"; +import { mono_assert } from "./globals"; export function deep_merge_config(target: MonoConfigInternal, source: MonoConfigInternal): MonoConfigInternal { // no need to merge the same object @@ -220,15 +221,12 @@ export async function mono_wasm_load_config(module: DotnetModuleInternal): Promi await loaderHelpers.afterConfigLoaded.promise; return; } - configLoaded = true; - if (!configFilePath) { - normalizeConfig(); - loaderHelpers.afterConfigLoaded.promise_control.resolve(loaderHelpers.config); - return; - } - mono_log_debug("mono_wasm_load_config"); try { - await loadBootConfig(module); + configLoaded = true; + if (configFilePath) { + mono_log_debug("mono_wasm_load_config"); + await loadBootConfig(module); + } normalizeConfig(); @@ -249,7 +247,12 @@ export async function mono_wasm_load_config(module: DotnetModuleInternal): Promi normalizeConfig(); + mono_assert(!loaderHelpers.config.startupMemoryCache || !module.instantiateWasm, "startupMemoryCache is not supported with Module.instantiateWasm"); + loaderHelpers.afterConfigLoaded.promise_control.resolve(loaderHelpers.config); + if (!loaderHelpers.config.startupMemoryCache) { + loaderHelpers.memorySnapshotSkippedOrDone.promise_control.resolve(); + } } catch (err) { const errMessage = `Failed to load config file ${configFilePath} ${err} ${(err as Error)?.stack}`; loaderHelpers.config = module.config = Object.assign(loaderHelpers.config, { message: errMessage, error: err, isError: true }); diff --git a/src/mono/wasm/runtime/loader/exit.ts b/src/mono/wasm/runtime/loader/exit.ts index e8cb2e42eb2ef1..6b6767e89672e6 100644 --- a/src/mono/wasm/runtime/loader/exit.ts +++ b/src/mono/wasm/runtime/loader/exit.ts @@ -122,9 +122,9 @@ function abort_promises(reason: any) { loaderHelpers.afterConfigLoaded.promise_control.reject(reason); loaderHelpers.wasmDownloadPromise.promise_control.reject(reason); loaderHelpers.runtimeModuleLoaded.promise_control.reject(reason); + loaderHelpers.memorySnapshotSkippedOrDone.promise_control.reject(reason); if (runtimeHelpers.dotnetReady) { runtimeHelpers.dotnetReady.promise_control.reject(reason); - runtimeHelpers.memorySnapshotSkippedOrDone.promise_control.reject(reason); runtimeHelpers.afterInstantiateWasm.promise_control.reject(reason); runtimeHelpers.beforePreInit.promise_control.reject(reason); runtimeHelpers.afterPreInit.promise_control.reject(reason); diff --git a/src/mono/wasm/runtime/loader/globals.ts b/src/mono/wasm/runtime/loader/globals.ts index a710ea0cb3b92d..55974cf4c51777 100644 --- a/src/mono/wasm/runtime/loader/globals.ts +++ b/src/mono/wasm/runtime/loader/globals.ts @@ -87,6 +87,7 @@ export function setLoaderGlobals( allDownloadsQueued: createPromiseController(), wasmDownloadPromise: createPromiseController(), runtimeModuleLoaded: createPromiseController(), + memorySnapshotSkippedOrDone: createPromiseController(), is_exited, is_runtime_running, diff --git a/src/mono/wasm/runtime/loader/run.ts b/src/mono/wasm/runtime/loader/run.ts index a3cb7977a30f0c..b3437a5a81d61b 100644 --- a/src/mono/wasm/runtime/loader/run.ts +++ b/src/mono/wasm/runtime/loader/run.ts @@ -454,10 +454,11 @@ function importModules() { } async function initializeModules(es6Modules: [RuntimeModuleExportsInternal, NativeModuleExportsInternal]) { - const { initializeExports, initializeReplacements, configureEmscriptenStartup, configureWorkerStartup, setRuntimeGlobals, passEmscriptenInternals } = es6Modules[0]; + const { initializeExports, initializeReplacements, configureRuntimeStartup, configureEmscriptenStartup, configureWorkerStartup, setRuntimeGlobals, passEmscriptenInternals } = es6Modules[0]; const { default: emscriptenFactory } = es6Modules[1]; setRuntimeGlobals(globalObjectsRoot); initializeExports(globalObjectsRoot); + await configureRuntimeStartup(); loaderHelpers.runtimeModuleLoaded.promise_control.resolve(); emscriptenFactory((originalModule: EmscriptenModuleInternal) => { @@ -494,9 +495,8 @@ async function createEmscriptenMain(): Promise { mono_exit(1, err); }); - init_globalization(); - setTimeout(() => { + init_globalization(); mono_download_assets(); // intentionally not awaited }, 0); diff --git a/src/mono/wasm/runtime/snapshot.ts b/src/mono/wasm/runtime/snapshot.ts index 1d1df904643f51..c23422353a7dd3 100644 --- a/src/mono/wasm/runtime/snapshot.ts +++ b/src/mono/wasm/runtime/snapshot.ts @@ -44,22 +44,35 @@ async function openCache(): Promise { } } -export async function getMemorySnapshotSize(): Promise { +export async function checkMemorySnapshotSize(): Promise { try { + if (!runtimeHelpers.config.startupMemoryCache) { + // we could start downloading DLLs because snapshot is disabled + return; + } + const cacheKey = await getCacheKey(); if (!cacheKey) { - return undefined; + return; } const cache = await openCache(); if (!cache) { - return undefined; + return; } const res = await cache.match(cacheKey); const contentLength = res?.headers.get("content-length"); - return contentLength ? parseInt(contentLength) : undefined; + const memorySize = contentLength ? parseInt(contentLength) : undefined; + + runtimeHelpers.loadedMemorySnapshotSize = memorySize; + runtimeHelpers.storeMemorySnapshotPending = !memorySize; } catch (ex) { mono_log_warn("Failed find memory snapshot in the cache", ex); - return undefined; + } + finally { + if (!runtimeHelpers.loadedMemorySnapshotSize) { + // we could start downloading DLLs because there is no snapshot yet + loaderHelpers.memorySnapshotSkippedOrDone.promise_control.resolve(); + } } } diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index f67a8b7c18ba90..e6f8d80ef82f48 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -21,7 +21,7 @@ import { instantiate_wasm_asset, wait_for_all_assets } from "./assets"; import { mono_wasm_init_diagnostics } from "./diagnostics"; import { replace_linker_placeholders } from "./exports-binding"; import { endMeasure, MeasuredBlock, startMeasure } from "./profiler"; -import { getMemorySnapshot, storeMemorySnapshot, getMemorySnapshotSize } from "./snapshot"; +import { checkMemorySnapshotSize, getMemorySnapshot, storeMemorySnapshot } from "./snapshot"; import { mono_log_debug, mono_log_error, mono_log_warn, mono_set_thread_id } from "./logging"; // threads @@ -39,6 +39,19 @@ import { assertNoProxies } from "./gc-handles"; // default size if MonoConfig.pthreadPoolSize is undefined const MONO_PTHREAD_POOL_SIZE = 4; +export async function configureRuntimeStartup(): Promise { + if (linkerWasmEnableSIMD) { + mono_assert(await loaderHelpers.simd(), "This browser/engine doesn't support WASM SIMD. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); + } + if (linkerWasmEnableEH) { + mono_assert(await loaderHelpers.exceptions(), "This browser/engine doesn't support WASM exception handling. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); + } + + await init_polyfills_async(); + + await checkMemorySnapshotSize(); +} + // we are making emscripten startup async friendly // emscripten is executing the events without awaiting it and so we need to block progress via PromiseControllers above export function configureEmscriptenStartup(module: DotnetModuleInternal): void { @@ -117,8 +130,6 @@ function instantiateWasm( const mark = startMeasure(); if (userInstantiateWasm) { - // user wasm instantiation doesn't support memory snapshots - runtimeHelpers.memorySnapshotSkippedOrDone.promise_control.resolve(); const exports = userInstantiateWasm(imports, (instance: WebAssembly.Instance, module: WebAssembly.Module | undefined) => { endMeasure(mark, MeasuredBlock.instantiateWasm); runtimeHelpers.afterInstantiateWasm.promise_control.resolve(); @@ -375,14 +386,6 @@ async function mono_wasm_pre_init_essential_async(): Promise { mono_log_debug("mono_wasm_pre_init_essential_async"); Module.addRunDependency("mono_wasm_pre_init_essential_async"); - if (linkerWasmEnableSIMD) { - mono_assert(await loaderHelpers.simd(), "This browser/engine doesn't support WASM SIMD. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); - } - if (linkerWasmEnableEH) { - mono_assert(await loaderHelpers.exceptions(), "This browser/engine doesn't support WASM exception handling. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); - } - - await init_polyfills_async(); if (MonoWasmThreads) { preAllocatePThreadWorkerPool(MONO_PTHREAD_POOL_SIZE, runtimeHelpers.config); @@ -457,20 +460,9 @@ async function instantiate_wasm_module( ): Promise { // this is called so early that even Module exports like addRunDependency don't exist yet try { - let memorySize: number | undefined = undefined; await loaderHelpers.afterConfigLoaded; mono_log_debug("instantiate_wasm_module"); - if (runtimeHelpers.config.startupMemoryCache) { - memorySize = await getMemorySnapshotSize(); - runtimeHelpers.loadedMemorySnapshot = !!memorySize; - runtimeHelpers.storeMemorySnapshotPending = !runtimeHelpers.loadedMemorySnapshot; - } - if (!runtimeHelpers.loadedMemorySnapshot) { - // we should start downloading DLLs etc as they are not in the snapshot - runtimeHelpers.memorySnapshotSkippedOrDone.promise_control.resolve(); - } - await runtimeHelpers.beforePreInit.promise; Module.addRunDependency("instantiate_wasm_module"); @@ -484,19 +476,19 @@ async function instantiate_wasm_module( mono_log_debug("instantiate_wasm_module done"); - if (runtimeHelpers.loadedMemorySnapshot) { + if (runtimeHelpers.loadedMemorySnapshotSize) { try { const wasmMemory = (Module.asm?.memory || Module.wasmMemory)!; // .grow() takes a delta compared to the previous size - wasmMemory.grow((memorySize! - wasmMemory.buffer.byteLength + 65535) >>> 16); + wasmMemory.grow((runtimeHelpers.loadedMemorySnapshotSize! - wasmMemory.buffer.byteLength + 65535) >>> 16); runtimeHelpers.updateMemoryViews(); } catch (err) { mono_log_warn("failed to resize memory for the snapshot", err); - runtimeHelpers.loadedMemorySnapshot = false; + runtimeHelpers.loadedMemorySnapshotSize = undefined; } // now we know if the loading of memory succeeded or not, we can start loading the rest of the assets - runtimeHelpers.memorySnapshotSkippedOrDone.promise_control.resolve(); + loaderHelpers.memorySnapshotSkippedOrDone.promise_control.resolve(); } runtimeHelpers.afterInstantiateWasm.promise_control.resolve(); } catch (err) { @@ -509,7 +501,7 @@ async function instantiate_wasm_module( async function mono_wasm_before_memory_snapshot() { const mark = startMeasure(); - if (runtimeHelpers.loadedMemorySnapshot) { + if (runtimeHelpers.loadedMemorySnapshotSize) { // get the bytes after we re-sized the memory, so that we don't have too much memory in use at the same time const memoryBytes = await getMemorySnapshot(); const heapU8 = localHeapViewU8(); diff --git a/src/mono/wasm/runtime/types/internal.ts b/src/mono/wasm/runtime/types/internal.ts index fcbeb03eadefdd..aedf803aceff1f 100644 --- a/src/mono/wasm/runtime/types/internal.ts +++ b/src/mono/wasm/runtime/types/internal.ts @@ -128,6 +128,7 @@ export type LoaderHelpers = { allDownloadsQueued: PromiseAndController, wasmDownloadPromise: PromiseAndController, runtimeModuleLoaded: PromiseAndController, + memorySnapshotSkippedOrDone: PromiseAndController, is_exited: () => boolean, is_runtime_running: () => boolean, @@ -176,7 +177,7 @@ export type RuntimeHelpers = { mono_wasm_runtime_is_ready: boolean; mono_wasm_bindings_is_ready: boolean; - loadedMemorySnapshot: boolean, + loadedMemorySnapshotSize?: number, enablePerfMeasure: boolean; waitForDebugger?: number; ExitStatus: ExitStatusError; @@ -194,7 +195,6 @@ export type RuntimeHelpers = { allAssetsInMemory: PromiseAndController, dotnetReady: PromiseAndController, - memorySnapshotSkippedOrDone: PromiseAndController, afterInstantiateWasm: PromiseAndController, beforePreInit: PromiseAndController, afterPreInit: PromiseAndController, @@ -490,6 +490,7 @@ export type setGlobalObjectsType = (globalObjects: GlobalObjects) => void; export type initializeExportsType = (globalObjects: GlobalObjects) => RuntimeAPI; export type initializeReplacementsType = (replacements: EmscriptenReplacements) => void; export type configureEmscriptenStartupType = (module: DotnetModuleInternal) => void; +export type configureRuntimeStartupType = () => Promise; export type configureWorkerStartupType = (module: DotnetModuleInternal) => Promise @@ -497,6 +498,7 @@ export type RuntimeModuleExportsInternal = { setRuntimeGlobals: setGlobalObjectsType, initializeExports: initializeExportsType, initializeReplacements: initializeReplacementsType, + configureRuntimeStartup: configureRuntimeStartupType, configureEmscriptenStartup: configureEmscriptenStartupType, configureWorkerStartup: configureWorkerStartupType, passEmscriptenInternals: passEmscriptenInternalsType, From c7558999450da512074cae9b9ddf6470b4c53f07 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 16:36:57 -0700 Subject: [PATCH 104/783] [release/8.0] Add boolean field to indicate whether or not the Windows thread pool is being used (#91246) * Add boolean field to indicate whether or not the Windows thread pool is being used * Update src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs Co-authored-by: Stephen Toub * Remove trailing spaces * Move comment * Update fields and comments * Disable CA1823 - unused field --------- Co-authored-by: unknown Co-authored-by: Eduardo Velarde <32459232+eduardo-vp@users.noreply.github.com> Co-authored-by: Stephen Toub --- .../src/System/Threading/ThreadPool.Windows.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs index 6882b0482c017a..0da875498afc18 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs @@ -13,6 +13,12 @@ public static partial class ThreadPool internal static bool UseWindowsThreadPool { get; } = AppContextConfigHelper.GetBooleanConfig("System.Threading.ThreadPool.UseWindowsThreadPool", "DOTNET_ThreadPool_UseWindowsThreadPool"); +#pragma warning disable CA1823 + // The field should reflect what the property returns because the property can be stubbed by trimming, + // such that sos reflects the actual state of what thread pool is being used and not just the config value. + private static readonly bool s_useWindowsThreadPool = UseWindowsThreadPool; // Name relied on by sos +#pragma warning restore CA1823 + #if NATIVEAOT private const bool IsWorkerTrackingEnabledInConfig = false; #else From c00d0ff5ed3ea293567fca46de64bf129be823af Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 16:39:26 -0700 Subject: [PATCH 105/783] [release/8.0] Update dependencies from dotnet/cecil dotnet/arcade dotnet/hotreload-utils dotnet/source-build-reference-packages (#91264) * Update dependencies from https://github.com/dotnet/cecil build 20230828.2 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23421.1 -> To Version 0.11.4-alpha.23428.2 * Update dependencies from https://github.com/dotnet/arcade build 20230828.2 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23425.2 -> To Version 8.0.0-beta.23428.2 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20230828.3 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23421.1 -> To Version 8.0.0-alpha.0.23428.3 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20230828.2 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23424.1 -> To Version 8.0.0-alpha.1.23428.2 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Larry Ewing --- eng/Version.Details.xml | 84 ++++++++++++++++++++--------------------- eng/Versions.props | 34 ++++++++--------- global.json | 6 +-- 3 files changed, 62 insertions(+), 62 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index aad708a98fcdce..efb4b40dceea8c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -85,9 +85,9 @@ 02fe27cd6a9b001c8feb7938e6ef4b3799745759b - + https://github.com/dotnet/cecil - d412306c1514a26737574838900052d8758da5be + fa5acbd2ccba88c9d46ce0dd8f5310f9d3c5c46d @@ -95,9 +95,9 @@ 66dbaefff04250dc72849f0172e0c53bcfb3ab38 - + https://github.com/dotnet/source-build-reference-packages - 93c23409e630c4f267234540b0e3557b76a53ef4 + 26ce96327dd346534926c4551f8b8d62a6fc724f @@ -107,9 +107,9 @@ - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 @@ -117,69 +117,69 @@ ed9a83526483c094fb51e7000b6f816ce6cb0325 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 https://github.com/dotnet/runtime-assets @@ -330,9 +330,9 @@ https://github.com/dotnet/xharness 480b9159eb7e69b182a87581d5a336e97e0b6dae - + https://github.com/dotnet/arcade - 90c167d5c57de4a8bced566379dbd893556c94e8 + 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization @@ -350,9 +350,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization ffa66bdcbd319c11795d23e835e7a44344723332 - + https://github.com/dotnet/hotreload-utils - e02247b9b7ec1d9e407312342147d8587a8ca20e + 4f453acb93d3340457a64b06a5f884adab76fd0b https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index 6414c8e37f55d0..6b31387aabe99d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -85,21 +85,21 @@ 8.0.100-preview.7.23329.3 - 8.0.0-beta.23425.2 - 8.0.0-beta.23425.2 - 8.0.0-beta.23425.2 - 8.0.0-beta.23425.2 - 8.0.0-beta.23425.2 - 2.5.1-beta.23425.2 - 8.0.0-beta.23425.2 - 8.0.0-beta.23425.2 - 8.0.0-beta.23425.2 - 8.0.0-beta.23425.2 - 8.0.0-beta.23425.2 - 8.0.0-beta.23425.2 - 8.0.0-beta.23425.2 - 8.0.0-beta.23425.2 - 8.0.0-beta.23425.2 + 8.0.0-beta.23428.2 + 8.0.0-beta.23428.2 + 8.0.0-beta.23428.2 + 8.0.0-beta.23428.2 + 8.0.0-beta.23428.2 + 2.5.1-beta.23428.2 + 8.0.0-beta.23428.2 + 8.0.0-beta.23428.2 + 8.0.0-beta.23428.2 + 8.0.0-beta.23428.2 + 8.0.0-beta.23428.2 + 8.0.0-beta.23428.2 + 8.0.0-beta.23428.2 + 8.0.0-beta.23428.2 + 8.0.0-beta.23428.2 6.0.0-preview.1.102 @@ -184,7 +184,7 @@ 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 - 8.0.0-alpha.0.23421.1 + 8.0.0-alpha.0.23428.3 2.4.2 1.0.0 2.4.5 @@ -213,7 +213,7 @@ 8.0.0-rc.1.23406.6 - 0.11.4-alpha.23421.1 + 0.11.4-alpha.23428.2 8.0.0-rc.1.23406.6 diff --git a/global.json b/global.json index ffe9ed56766f48..fd45afe4dd2784 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.100-preview.7.23376.3" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23425.2", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23425.2", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23425.2", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23428.2", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23428.2", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23428.2", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From 36b3790bfc6fe077c4047aec0d64a0157c0c7928 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 16:40:25 -0700 Subject: [PATCH 106/783] [release/8.0] [browser] Add `EmccMaximumHeapSize` to define maximum memory (#91277) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * EmccMaximumHeapSize to define maximum memory * Fix typo in comment * Space in param use --------- Co-authored-by: Marek Fišera --- src/mono/wasm/build/WasmApp.Native.targets | 9 +++++---- src/mono/wasm/build/WasmApp.targets | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index 7060397f0cb85c..295474566a14a0 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -221,10 +221,11 @@ <_EmccCommonFlags Include="$(_DefaultEmccFlags)" /> <_EmccCommonFlags Include="$(EmccFlags)" /> - <_EmccCommonFlags Include="-g" Condition="'$(WasmNativeDebugSymbols)' == 'true'" /> - <_EmccCommonFlags Include="-v" Condition="'$(EmccVerbose)' != 'false'" /> - <_EmccCommonFlags Include="-s DISABLE_EXCEPTION_CATCHING=0" Condition="'$(WasmEnableExceptionHandling)' == 'false'" /> - <_EmccCommonFlags Include="-fwasm-exceptions" Condition="'$(WasmEnableExceptionHandling)' == 'true'" /> + <_EmccCommonFlags Include="-g" Condition="'$(WasmNativeDebugSymbols)' == 'true'" /> + <_EmccCommonFlags Include="-v" Condition="'$(EmccVerbose)' != 'false'" /> + <_EmccCommonFlags Include="-s DISABLE_EXCEPTION_CATCHING=0" Condition="'$(WasmEnableExceptionHandling)' == 'false'" /> + <_EmccCommonFlags Include="-fwasm-exceptions" Condition="'$(WasmEnableExceptionHandling)' == 'true'" /> + <_EmccCommonFlags Include="-s MAXIMUM_MEMORY=$(EmccMaximumHeapSize)" Condition="'$(EmccMaximumHeapSize)' != ''" /> <_EmccIncludePaths Include="$(_WasmIntermediateOutputPath.TrimEnd('\/'))" /> <_EmccIncludePaths Include="$(_WasmRuntimePackIncludeDir)mono-2.0" /> diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index be1b7214e2c0bd..0a22f3f82d528f 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -57,6 +57,8 @@ - $(EmccInitialHeapSize) - Initial heap size specified with `emcc`. Default value: 16777216 or size of the DLLs, whichever is larger. Corresponds to `-s INITIAL_MEMORY=...` emcc arg. (previously named EmccTotalMemory, which is still kept as an alias) + - $(EmccMaximumHeapSize) - Maximum heap size specified with `emcc`. Default value: 2147483648 or size of the DLLs, whichever is larger. + Corresponds to `-s MAXIMUM_MEMORY=...` emcc arg. - $(EmccStackSize) - Stack size. Default value: 5MB. Corresponds to `-s STACK_SIZE=...` emcc arg. From 40d2134aa50389d70fd845a7a6c06f46383e602e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 10:13:55 -0700 Subject: [PATCH 107/783] [release/8.0] [mono][metadata] Replace use of mem manager lock with loader lock (#91327) * [mono][metadata] Replace use of mem manager lock with loader lock Hash table operations under the mem manager lock could end up taking the loader lock when performing type comparison, in the case where custom modifiers needed to be loaded. Use the loader lock instead to prevent deadlocks. * [mono][metadata] Use loader lock during generic class hash table lookup --------- Co-authored-by: Vlad Brezae --- src/mono/mono/metadata/metadata.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/metadata/metadata.c b/src/mono/mono/metadata/metadata.c index 7c7cd4433eecf6..f9abe652b019a3 100644 --- a/src/mono/mono/metadata/metadata.c +++ b/src/mono/mono/metadata/metadata.c @@ -3434,7 +3434,8 @@ mono_metadata_get_canonical_generic_inst (MonoGenericInst *candidate) MonoMemoryManager *mm = mono_mem_manager_get_generic (data.images, data.nimages); collect_data_free (&data); - mono_mem_manager_lock (mm); + // Hashtable key equal func can take loader lock + mono_loader_lock (); if (!mm->ginst_cache) mm->ginst_cache = g_hash_table_new_full (mono_metadata_generic_inst_hash, mono_metadata_generic_inst_equal, NULL, (GDestroyNotify)free_generic_inst); @@ -3456,7 +3457,7 @@ mono_metadata_get_canonical_generic_inst (MonoGenericInst *candidate) g_hash_table_insert (mm->ginst_cache, ginst, ginst); } - mono_mem_manager_unlock (mm); + mono_loader_unlock (); return ginst; } @@ -3467,7 +3468,8 @@ mono_metadata_get_canonical_aggregate_modifiers (MonoAggregateModContainer *cand g_assert (candidate->count > 0); MonoMemoryManager *mm = mono_metadata_get_mem_manager_for_aggregate_modifiers (candidate); - mono_mem_manager_lock (mm); + // Hashtable key equal func can take loader lock + mono_loader_lock (); if (!mm->aggregate_modifiers_cache) mm->aggregate_modifiers_cache = g_hash_table_new_full (aggregate_modifiers_hash, aggregate_modifiers_equal, NULL, (GDestroyNotify)free_aggregate_modifiers); @@ -3484,7 +3486,7 @@ mono_metadata_get_canonical_aggregate_modifiers (MonoAggregateModContainer *cand g_hash_table_insert (mm->aggregate_modifiers_cache, amods, amods); } - mono_mem_manager_unlock (mm); + mono_loader_unlock (); return amods; } @@ -3543,7 +3545,8 @@ mono_metadata_lookup_generic_class (MonoClass *container_class, MonoGenericInst if (gclass) return gclass; - mono_mem_manager_lock (mm); + // Hashtable key equal func can take loader lock + mono_loader_lock (); gclass = mono_mem_manager_alloc0 (mm, sizeof (MonoGenericClass)); if (is_dynamic) @@ -3563,7 +3566,7 @@ mono_metadata_lookup_generic_class (MonoClass *container_class, MonoGenericInst // g_hash_table_insert (set->gclass_cache, gclass, gclass); - mono_mem_manager_unlock (mm); + mono_loader_unlock (); return gclass2; } From e018fb7c957f1552aa967fe9a4c3ce715df6ed43 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:40:56 -0700 Subject: [PATCH 108/783] Fix Http2 MultiConnection test race conditions (#91343) Co-authored-by: Miha Zupan --- ...lientHandlerTestBase.SocketsHttpHandler.cs | 17 ++ .../tests/FunctionalTests/MetricsTest.cs | 13 +- .../SocketsHttpHandlerTest.Cancellation.cs | 4 +- .../FunctionalTests/SocketsHttpHandlerTest.cs | 193 ++++++++---------- 4 files changed, 109 insertions(+), 118 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs index 602d177f5f1be1..888b38b813127e 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs @@ -3,14 +3,31 @@ using System.IO; using System.Net.Quic; +using System.Net.Sockets; using System.Net.Test.Common; using System.Reflection; +using System.Threading; using System.Threading.Tasks; namespace System.Net.Http.Functional.Tests { public abstract partial class HttpClientHandlerTestBase : FileCleanupTestBase { + protected static async Task DefaultConnectCallback(EndPoint endPoint, CancellationToken cancellationToken) + { + Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp) { NoDelay = true }; + try + { + await socket.ConnectAsync(endPoint, cancellationToken); + return new NetworkStream(socket, ownsSocket: true); + } + catch + { + socket.Dispose(); + throw; + } + } + protected static bool IsWinHttpHandler => false; public static bool IsQuicSupported diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs index f3a97d2f15d530..da36366246f415 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs @@ -292,17 +292,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => GetUnderlyingSocketsHttpHandler(Handler).ConnectCallback = async (ctx, cancellationToken) => { connectionStarted.SetResult(); - Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp) { NoDelay = true }; - try - { - await socket.ConnectAsync(ctx.DnsEndPoint, cancellationToken); - return new NetworkStream(socket, ownsSocket: true); - } - catch - { - socket.Dispose(); - throw; - } + + return await DefaultConnectCallback(ctx.DnsEndPoint, cancellationToken); }; // Enable recording request-duration to test the path with metrics enabled. diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Cancellation.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Cancellation.cs index c793a1d55d6e76..76d7086c37c174 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Cancellation.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Cancellation.cs @@ -165,9 +165,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => else { // Succeed the second connection attempt - Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp) { NoDelay = true }; - await socket.ConnectAsync(context.DnsEndPoint, token); - return new NetworkStream(socket, ownsSocket: true); + return await DefaultConnectCallback(context.DnsEndPoint, token); } }; diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index e25f69529b0e60..2613b451be4556 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -1369,17 +1369,7 @@ await RetryHelper.ExecuteAsync(async () => { Assert.Equal("foo", context.DnsEndPoint.Host); - Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp) { NoDelay = true }; - try - { - await socket.ConnectAsync(lastServerUri.IdnHost, lastServerUri.Port); - return new NetworkStream(socket, ownsSocket: true); - } - catch - { - socket.Dispose(); - throw; - } + return await DefaultConnectCallback(new DnsEndPoint(lastServerUri.IdnHost, lastServerUri.Port), ct); }; TaskCompletionSource waitingForLastRequest = new(TaskCreationOptions.RunContinuationsAsynchronously); @@ -2659,30 +2649,18 @@ public async Task Http2_MultipleConnectionsEnabled_ManyRequestsEnqueuedSimultane AcquireAllStreamSlots(server, client, sendTasks, RequestCount); - List<(Http2LoopbackConnection connection, int streamId)> acceptedRequests = new(); - await using Http2LoopbackConnection c1 = await server.EstablishConnectionAsync(new SettingsEntry { SettingId = SettingId.MaxConcurrentStreams, Value = 100 }); - for (int i = 0; i < MaxConcurrentStreams; i++) - { - (int streamId, _) = await c1.ReadAndParseRequestHeaderAsync(); - acceptedRequests.Add((c1, streamId)); - } + int[] streamIds1 = await AcceptRequests(c1, MaxConcurrentStreams); await using Http2LoopbackConnection c2 = await server.EstablishConnectionAsync(new SettingsEntry { SettingId = SettingId.MaxConcurrentStreams, Value = 100 }); - for (int i = 0; i < MaxConcurrentStreams; i++) - { - (int streamId, _) = await c2.ReadAndParseRequestHeaderAsync(); - acceptedRequests.Add((c2, streamId)); - } + int[] streamIds2 = await AcceptRequests(c2, MaxConcurrentStreams); await using Http2LoopbackConnection c3 = await server.EstablishConnectionAsync(new SettingsEntry { SettingId = SettingId.MaxConcurrentStreams, Value = 100 }); (int finalStreamId, _) = await c3.ReadAndParseRequestHeaderAsync(); - acceptedRequests.Add((c3, finalStreamId)); - foreach ((Http2LoopbackConnection connection, int streamId) request in acceptedRequests) - { - await request.connection.SendDefaultResponseAsync(request.streamId); - } + await SendResponses(c1, streamIds1); + await SendResponses(c2, streamIds2); + await c3.SendDefaultResponseAsync(finalStreamId); await VerifySendTasks(sendTasks); } @@ -2702,19 +2680,17 @@ public async Task Http2_MultipleConnectionsEnabled_InfiniteRequestsCompletelyBlo Http2LoopbackConnection connection0 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); - // Block the first connection on infinite requests. + // Accept requests but don't send responses on connection 0 int[] blockedStreamIds = await AcceptRequests(connection0, MaxConcurrentStreams).ConfigureAwait(false); - Assert.Equal(MaxConcurrentStreams, blockedStreamIds.Length); Http2LoopbackConnection connection1 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); - await HandleAllPendingRequests(connection1, MaxConcurrentStreams).ConfigureAwait(false); + // Send responses on connection 1 + await SendResponses(connection1, await AcceptRequests(connection1, MaxConcurrentStreams).ConfigureAwait(false)); - // Complete infinite requests. - int handledRequestCount = await SendResponses(connection0, blockedStreamIds); - - Assert.Equal(MaxConcurrentStreams, handledRequestCount); + // Send responses on connection 0 + await SendResponses(connection0, blockedStreamIds); await VerifySendTasks(sendTasks).ConfigureAwait(false); } @@ -2729,44 +2705,62 @@ public async Task Http2_MultipleConnectionsEnabled_OpenAndCloseMultipleConnectio const int MaxConcurrentStreams = 2; using Http2LoopbackServer server = Http2LoopbackServer.CreateServer(); + server.AllowMultipleConnections = true; + + // Allow 5 connections through the ConnectCallback. + SemaphoreSlim connectCallbackSemaphore = new(initialCount: 5); + using SocketsHttpHandler handler = CreateHandler(); + + handler.ConnectCallback = async (context, ct) => + { + await connectCallbackSemaphore.WaitAsync(ct); + + return await DefaultConnectCallback(context.DnsEndPoint, ct); + }; + using (HttpClient client = CreateHttpClient(handler)) { - server.AllowMultipleConnections = true; - List> sendTasks = new List>(); + List> sendTasks = new(); + Http2LoopbackConnection connection0 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + int[] streamIds0 = await AcceptRequests(connection0, MaxConcurrentStreams).ConfigureAwait(false); + Http2LoopbackConnection connection1 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + int[] streamIds1 = await AcceptRequests(connection1, MaxConcurrentStreams).ConfigureAwait(false); + Http2LoopbackConnection connection2 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + int[] streamIds2 = await AcceptRequests(connection2, MaxConcurrentStreams).ConfigureAwait(false); - Task[] handleRequestTasks = new[] { - HandleAllPendingRequests(connection0, MaxConcurrentStreams), - HandleAllPendingRequests(connection1, MaxConcurrentStreams), - HandleAllPendingRequests(connection2, MaxConcurrentStreams) - }; - - await TestHelper.WhenAllCompletedOrAnyFailed(handleRequestTasks).ConfigureAwait(false); + await TestHelper.WhenAllCompletedOrAnyFailed( + SendResponses(connection0, streamIds0), + SendResponses(connection1, streamIds1), + SendResponses(connection2, streamIds2)) + .ConfigureAwait(false); - await connection0.ShutdownIgnoringErrorsAsync(await handleRequestTasks[0]).ConfigureAwait(false); - await connection2.ShutdownIgnoringErrorsAsync(await handleRequestTasks[2]).ConfigureAwait(false); + await connection0.ShutdownIgnoringErrorsAsync(streamIds0[^1]).ConfigureAwait(false); + await connection2.ShutdownIgnoringErrorsAsync(streamIds2[^1]).ConfigureAwait(false); - //Fill all connection1's stream slots + // Fill all connection1's stream slots AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + streamIds1 = await AcceptRequests(connection1, MaxConcurrentStreams).ConfigureAwait(false); Http2LoopbackConnection connection3 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + int[] streamIds3 = await AcceptRequests(connection3, MaxConcurrentStreams).ConfigureAwait(false); + Http2LoopbackConnection connection4 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + int[] streamIds4 = await AcceptRequests(connection4, MaxConcurrentStreams).ConfigureAwait(false); - Task[] finalHandleTasks = new[] { - HandleAllPendingRequests(connection1, MaxConcurrentStreams), - HandleAllPendingRequests(connection3, MaxConcurrentStreams), - HandleAllPendingRequests(connection4, MaxConcurrentStreams) - }; - - await TestHelper.WhenAllCompletedOrAnyFailed(finalHandleTasks).ConfigureAwait(false); + await TestHelper.WhenAllCompletedOrAnyFailed( + SendResponses(connection1, streamIds1), + SendResponses(connection3, streamIds3), + SendResponses(connection4, streamIds4)) + .ConfigureAwait(false); await VerifySendTasks(sendTasks).ConfigureAwait(false); } @@ -2778,24 +2772,36 @@ public async Task Http2_MultipleConnectionsEnabled_IdleConnectionTimeoutExpired_ { const int MaxConcurrentStreams = 2; using Http2LoopbackServer server = Http2LoopbackServer.CreateServer(); + server.AllowMultipleConnections = true; + + SemaphoreSlim connectCallbackSemaphore = new(initialCount: 2); + using SocketsHttpHandler handler = CreateHandler(); handler.PooledConnectionIdleTimeout = TimeSpan.FromSeconds(20); + + handler.ConnectCallback = async (context, ct) => + { + await connectCallbackSemaphore.WaitAsync(ct); + + return await DefaultConnectCallback(context.DnsEndPoint, ct); + }; + using (HttpClient client = CreateHttpClient(handler)) { - server.AllowMultipleConnections = true; - List> sendTasks = new List>(); + List> sendTasks0 = new(); + List> sendTasks1 = new(); + List> sendTasks2 = new(); + Http2LoopbackConnection connection0 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); - AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); - int[] acceptedStreamIds = await AcceptRequests(connection0, MaxConcurrentStreams).ConfigureAwait(false); - Assert.Equal(MaxConcurrentStreams, acceptedStreamIds.Length); + AcquireAllStreamSlots(server, client, sendTasks0, MaxConcurrentStreams); + int[] streamIds0 = await AcceptRequests(connection0, MaxConcurrentStreams).ConfigureAwait(false); - List> connection1SendTasks = new List>(); Http2LoopbackConnection connection1 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); - AcquireAllStreamSlots(server, client, connection1SendTasks, MaxConcurrentStreams); - await HandleAllPendingRequests(connection1, MaxConcurrentStreams).ConfigureAwait(false); + AcquireAllStreamSlots(server, client, sendTasks1, MaxConcurrentStreams); + await SendResponses(connection1, await AcceptRequests(connection1, MaxConcurrentStreams).ConfigureAwait(false)); - // Complete all the requests. - await VerifySendTasks(connection1SendTasks).ConfigureAwait(false); + // Complete all the requests on connection1. + await VerifySendTasks(sendTasks1).ConfigureAwait(false); // Wait until the idle connection timeout expires. await connection1.WaitForClientDisconnectAsync(false).WaitAsync(TestHelper.PassingTestTimeout).ConfigureAwait(false); @@ -2803,17 +2809,20 @@ public async Task Http2_MultipleConnectionsEnabled_IdleConnectionTimeoutExpired_ Assert.True(connection1.IsInvalid); Assert.False(connection0.IsInvalid); - Http2LoopbackConnection connection2 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); - - AcquireAllStreamSlots(server, client, sendTasks, MaxConcurrentStreams); + // Due to a race condition in how a new Http2 connection is returned to the pool, we may have started a third connection attempt in the background. + // We were blocking such attempts from going through to the Socket layer until now to avoid having to deal with the extra connect when accepting connection2 below. + // Allow the third connection through the ConnectCallback now. + connectCallbackSemaphore.Release(); - await HandleAllPendingRequests(connection2, MaxConcurrentStreams).ConfigureAwait(false); + Http2LoopbackConnection connection2 = await PrepareConnection(server, client, MaxConcurrentStreams).ConfigureAwait(false); + AcquireAllStreamSlots(server, client, sendTasks2, MaxConcurrentStreams); + await SendResponses(connection2, await AcceptRequests(connection2, MaxConcurrentStreams).ConfigureAwait(false)); - //Make sure connection0 is still alive. - int handledRequests0 = await SendResponses(connection0, acceptedStreamIds).ConfigureAwait(false); - Assert.Equal(MaxConcurrentStreams, handledRequests0); + // Make sure connection0 is still alive. + await SendResponses(connection0, streamIds0).ConfigureAwait(false); - await VerifySendTasks(sendTasks).ConfigureAwait(false); + await VerifySendTasks(sendTasks0).ConfigureAwait(false); + await VerifySendTasks(sendTasks2).ConfigureAwait(false); } } @@ -2842,7 +2851,10 @@ private async Task PrepareConnection(Http2LoopbackServe Task warmUpTask = client.GetAsync(server.Address); - Http2LoopbackConnection connection = await GetConnection(server, maxConcurrentStreams).WaitAsync(TestHelper.PassingTestTimeout).ConfigureAwait(false); + var concurrentStreamsSetting = new SettingsEntry { SettingId = SettingId.MaxConcurrentStreams, Value = maxConcurrentStreams }; + + Http2LoopbackConnection connection = await server.EstablishConnectionAsync(timeout: null, ackTimeout: TimeSpan.FromSeconds(10), concurrentStreamsSetting) + .WaitAsync(TestHelper.PassingTestTimeout).ConfigureAwait(false); (int streamId, _) = await connection.ReadAndParseRequestHeaderAsync().WaitAsync(TestHelper.PassingTestTimeout).ConfigureAwait(false); await connection.SendDefaultResponseAsync(streamId).WaitAsync(TestHelper.PassingTestTimeout).ConfigureAwait(false); @@ -2862,49 +2874,25 @@ private static void AcquireAllStreamSlots(Http2LoopbackServer server, HttpClient } } - private static async Task GetConnection(Http2LoopbackServer server, uint maxConcurrentStreams) - { - var concurrentStreamsSetting = new SettingsEntry { SettingId = SettingId.MaxConcurrentStreams, Value = maxConcurrentStreams }; - - return await server.EstablishConnectionAsync(timeout: null, ackTimeout: TimeSpan.FromSeconds(10), concurrentStreamsSetting).ConfigureAwait(false); - } - - private async Task HandleAllPendingRequests(Http2LoopbackConnection connection, int totalRequestCount) - { - int lastStreamId = -1; - for (int i = 0; i < totalRequestCount; i++) - { - (int streamId, _) = await connection.ReadAndParseRequestHeaderAsync().ConfigureAwait(false); - await connection.SendDefaultResponseAsync(streamId).ConfigureAwait(false); - lastStreamId = streamId; - } - - return lastStreamId; - } - private async Task AcceptRequests(Http2LoopbackConnection connection, int requestCount) { int[] streamIds = new int[requestCount]; for (int i = 0; i < streamIds.Length; i++) { - (int streamId, _) = await connection.ReadAndParseRequestHeaderAsync().ConfigureAwait(false); + (int streamId, _) = await connection.ReadAndParseRequestHeaderAsync().WaitAsync(TestHelper.PassingTestTimeout).ConfigureAwait(false); streamIds[i] = streamId; } return streamIds; } - private async Task SendResponses(Http2LoopbackConnection connection, IEnumerable streamIds) + private async Task SendResponses(Http2LoopbackConnection connection, IEnumerable streamIds) { - int count = 0; foreach (int streamId in streamIds) { - count++; - await connection.SendDefaultResponseAsync(streamId).ConfigureAwait(false); + await connection.SendDefaultResponseAsync(streamId).WaitAsync(TestHelper.PassingTestTimeout).ConfigureAwait(false); } - - return count; } } @@ -3108,10 +3096,7 @@ public async Task ConnectCallback_ConnectionPrefix_Success(bool useSsl) var socketsHandler = (SocketsHttpHandler)GetUnderlyingSocketsHttpHandler(handler); socketsHandler.ConnectCallback = async (context, token) => { - Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - await clientSocket.ConnectAsync(listenSocket.LocalEndPoint); - - Stream clientStream = new NetworkStream(clientSocket, ownsSocket: true); + Stream clientStream = await DefaultConnectCallback(listenSocket.LocalEndPoint, token); await clientStream.WriteAsync(RequestPrefix); From 028b380d67b891a6f45d02d633145a0c7b58a857 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:43:07 -0700 Subject: [PATCH 109/783] [release/8.0] [browser] Update browser template to use Wasm SDK (#91046) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use WasmSdk in browser template * Remove default html-path * Use wwwroot when looking for main.js in template for replacement * Temporarily remove WasmRuntimeAssetsLocation from WBT because WasmSDK doesn't support it yet * Integrate console log forward into DevServer * Replace UseRouter * Use next middleware only if it's not console * CancellationTokenSource on CancelKeyPress * Address feedback from initial DevServer integration * Update src/mono/wasm/host/BrowserHost.cs Co-authored-by: Ankit Jain * Remove debugging code * Fix WBT * Fix starting outside of project directory * Support WasmRuntimeAssetsLocation in Wasm SDK * Revert "Support WasmRuntimeAssetsLocation in Wasm SDK" * Active issue for WasmRuntimeAssetsLocation * Feedback --------- Co-authored-by: Marek Fišera Co-authored-by: Ankit Jain --- ...rosoft.NET.Sdk.WebAssembly.Browser.targets | 8 +++-- .../Templates/WasmTemplateTests.cs | 7 ++-- .../WasmSdkBasedProjectProvider.cs | 15 ++++++++ .../Wasm.Build.Tests/WasmTemplateTestBase.cs | 28 ++++++++++++--- src/mono/wasm/host/BrowserHost.cs | 4 +-- src/mono/wasm/host/DevServer/DevServer.cs | 3 +- .../wasm/host/DevServer/DevServerStartup.cs | 34 ++++++++++++++++--- src/mono/wasm/host/Program.cs | 3 ++ .../templates/templates/browser/README.md | 26 -------------- .../templates/browser/browser.0.csproj | 11 ++---- .../browser/runtimeconfig.template.json | 5 ++- .../browser/{ => wwwroot}/index.html | 0 .../templates/browser/{ => wwwroot}/main.js | 0 13 files changed, 88 insertions(+), 56 deletions(-) delete mode 100644 src/mono/wasm/templates/templates/browser/README.md rename src/mono/wasm/templates/templates/browser/{ => wwwroot}/index.html (100%) rename src/mono/wasm/templates/templates/browser/{ => wwwroot}/main.js (100%) diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets index f8898000dab693..324f36cad7957f 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets @@ -19,9 +19,13 @@ Copyright (c) .NET Foundation. All rights reserved. dotnet $([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), '..', 'WasmAppHost')) - <_RuntimeConfigJsonPath>$([MSBuild]::NormalizePath($(OutputPath), '$(AssemblyName).runtimeconfig.json')) + + <_RunWorkingDirectory>$(OutputPath) + <_RunWorkingDirectory Condition="'$(_RunWorkingDirectory)' != '' and !$([System.IO.Path]::IsPathRooted($(_RunWorkingDirectory)))">$([System.IO.Path]::Combine($(MSBuildProjectDirectory), $(_RunWorkingDirectory))) + <_RuntimeConfigJsonPath>$([MSBuild]::NormalizePath($(_RunWorkingDirectory), '$(AssemblyName).runtimeconfig.json')) + exec "$([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost.dll'))" --use-staticwebassets --runtime-config "$(_RuntimeConfigJsonPath)" $(WasmHostArguments) - $(OutputPath) + $(_RunWorkingDirectory) diff --git a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs index 76a64c9fe4e76a..08488d487a6151 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs @@ -39,7 +39,7 @@ private void UpdateProgramCS() private void UpdateBrowserMainJs(string targetFramework, string runtimeAssetsRelativePath = DefaultRuntimeAssetsRelativePath) { - string mainJsPath = Path.Combine(_projectDir!, "main.js"); + string mainJsPath = Path.Combine(_projectDir!, "wwwroot", "main.js"); string mainJsContent = File.ReadAllText(mainJsPath); // .withExitOnUnhandledError() is available only only >net7.0 @@ -408,11 +408,12 @@ public void ConsolePublishAndRun(string config, bool aot, bool relinking) [Theory] [InlineData("", BuildTestBase.DefaultTargetFramework, DefaultRuntimeAssetsRelativePath)] - [InlineData("", BuildTestBase.DefaultTargetFramework, "./")] + // [ActiveIssue("https://github.com/dotnet/runtime/issues/90979")] + // [InlineData("", BuildTestBase.DefaultTargetFramework, "./")] + // [InlineData("-f net8.0", "net8.0", "./")] // [ActiveIssue("https://github.com/dotnet/runtime/issues/79313")] // [InlineData("-f net7.0", "net7.0")] [InlineData("-f net8.0", "net8.0", DefaultRuntimeAssetsRelativePath)] - [InlineData("-f net8.0", "net8.0", "./")] public async Task BrowserBuildAndRun(string extraNewArgs, string targetFramework, string runtimeAssetsRelativePath) { string config = "Debug"; diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs b/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs index 1f70aa46df8fa1..9ff2155c68e600 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs @@ -57,6 +57,21 @@ protected override IReadOnlySet GetDotNetFilesExpectedSet(AssertBundleOp return res; } + + public void AssertBundle(BuildArgs buildArgs, BuildProjectOptions buildProjectOptions) + { + AssertBundle(new( + Config: buildArgs.Config, + IsPublish: buildProjectOptions.Publish, + TargetFramework: buildProjectOptions.TargetFramework, + BinFrameworkDir: buildProjectOptions.BinFrameworkDir ?? FindBinFrameworkDir(buildArgs.Config, buildProjectOptions.Publish, buildProjectOptions.TargetFramework), + PredefinedIcudt: buildProjectOptions.PredefinedIcudt, + GlobalizationMode: buildProjectOptions.GlobalizationMode, + AssertSymbolsFile: false, + ExpectedFileType: buildProjectOptions.Publish && buildArgs.Config == "Release" ? NativeFilesType.Relinked : NativeFilesType.FromRuntimePack + )); + } + public void AssertBundle(AssertWasmSdkBundleOptions assertOptions) { IReadOnlyDictionary actualDotnetFiles = AssertBasicBundle(assertOptions); diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs index a76aaee38a929b..6280a022c1a424 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs @@ -59,19 +59,23 @@ public string CreateWasmTemplateProject(string id, string template = "wasmbrowse public (string projectDir, string buildOutput) BuildTemplateProject(BuildArgs buildArgs, string id, - BuildProjectOptions buildProjectOptions, - AssertTestMainJsAppBundleOptions? assertAppBundleOptions = null) + BuildProjectOptions buildProjectOptions) { (CommandResult res, string logFilePath) = BuildProjectWithoutAssert(id, buildArgs.Config, buildProjectOptions); if (buildProjectOptions.UseCache) _buildContext.CacheBuild(buildArgs, new BuildProduct(_projectDir!, logFilePath, true, res.Output)); if (buildProjectOptions.AssertAppBundle) - AssertBundle(buildArgs, buildProjectOptions, res.Output, assertAppBundleOptions); + { + if (buildProjectOptions.IsBrowserProject) + AssertWasmSdkBundle(buildArgs, buildProjectOptions, res.Output); + else + AssertTestMainJsBundle(buildArgs, buildProjectOptions, res.Output); + } return (_projectDir!, res.Output); } - public void AssertBundle(BuildArgs buildArgs, + public void AssertTestMainJsBundle(BuildArgs buildArgs, BuildProjectOptions buildProjectOptions, string? buildOutput = null, AssertTestMainJsAppBundleOptions? assertAppBundleOptions = null) @@ -79,11 +83,25 @@ public void AssertBundle(BuildArgs buildArgs, if (buildOutput is not null) ProjectProviderBase.AssertRuntimePackPath(buildOutput, buildProjectOptions.TargetFramework ?? DefaultTargetFramework); - // TODO: templates don't use wasm sdk yet var testMainJsProvider = new TestMainJsProjectProvider(_testOutput, _projectDir!); if (assertAppBundleOptions is not null) testMainJsProvider.AssertBundle(assertAppBundleOptions); else testMainJsProvider.AssertBundle(buildArgs, buildProjectOptions); } + + public void AssertWasmSdkBundle(BuildArgs buildArgs, + BuildProjectOptions buildProjectOptions, + string? buildOutput = null, + AssertWasmSdkBundleOptions? assertAppBundleOptions = null) + { + if (buildOutput is not null) + ProjectProviderBase.AssertRuntimePackPath(buildOutput, buildProjectOptions.TargetFramework ?? DefaultTargetFramework); + + var projectProvider = new WasmSdkBasedProjectProvider(_testOutput, _projectDir!); + if (assertAppBundleOptions is not null) + projectProvider.AssertBundle(assertAppBundleOptions); + else + projectProvider.AssertBundle(buildArgs, buildProjectOptions); + } } diff --git a/src/mono/wasm/host/BrowserHost.cs b/src/mono/wasm/host/BrowserHost.cs index 5c16a420e76deb..adb24f81f88dac 100644 --- a/src/mono/wasm/host/BrowserHost.cs +++ b/src/mono/wasm/host/BrowserHost.cs @@ -167,7 +167,7 @@ private static DevServerOptions CreateDevServerOptions(BrowserArguments args, st devServerOptions = CreateDevServerOptions(urls, staticWebAssetsPath, onConsoleConnected); if (devServerOptions == null) - throw new CommandLineException("Please, provide mainAssembly in hostProperties of runtimeconfig"); + throw new CommandLineException($"Please, provide mainAssembly in hostProperties of runtimeconfig. Alternatively leave the static web assets manifest ('*{staticWebAssetsV2Extension}') in the build output directory '{appPath}' ."); } return devServerOptions; @@ -183,7 +183,7 @@ private static DevServerOptions CreateDevServerOptions(BrowserArguments args, st ); private static string? FindFirstFileWithExtension(string directory, string extension) - => Directory.EnumerateFiles(directory, "*" + extension).First(); + => Directory.EnumerateFiles(directory, "*" + extension).FirstOrDefault(); private async Task RunConsoleMessagesPump(WebSocket socket, WasmTestMessagesProcessor messagesProcessor, CancellationToken token) { diff --git a/src/mono/wasm/host/DevServer/DevServer.cs b/src/mono/wasm/host/DevServer/DevServer.cs index b1369deabcc0cc..1acbe6954eeb3b 100644 --- a/src/mono/wasm/host/DevServer/DevServer.cs +++ b/src/mono/wasm/host/DevServer/DevServer.cs @@ -70,8 +70,7 @@ private static IConfiguration ConfigureHostConfiguration(DevServerOptions option [WebHostDefaults.EnvironmentKey] = "Development", ["Logging:LogLevel:Microsoft"] = "Warning", ["Logging:LogLevel:Microsoft.Hosting.Lifetime"] = "Information", - [WebHostDefaults.StaticWebAssetsKey] = options.StaticWebAssetsPath, - ["ApplyCopHeaders"] = options.WebServerUseCrossOriginPolicy.ToString() + [WebHostDefaults.StaticWebAssetsKey] = options.StaticWebAssetsPath }; config.AddInMemoryCollection(inMemoryConfiguration); diff --git a/src/mono/wasm/host/DevServer/DevServerStartup.cs b/src/mono/wasm/host/DevServer/DevServerStartup.cs index f438caf4b4b7ae..0fdc45a1754fdf 100644 --- a/src/mono/wasm/host/DevServer/DevServerStartup.cs +++ b/src/mono/wasm/host/DevServer/DevServerStartup.cs @@ -2,13 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.IO; +using System.Net.WebSockets; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Microsoft.WebAssembly.AppHost; namespace Microsoft.WebAssembly.AppHost.DevServer; @@ -27,16 +30,16 @@ public static void ConfigureServices(IServiceCollection services) services.AddRouting(); } - public static void Configure(IApplicationBuilder app, TaskCompletionSource realUrlsAvailableTcs, ILogger logger, IHostApplicationLifetime applicationLifetime, IConfiguration configuration) + public static void Configure(IApplicationBuilder app, IOptions optionsContainer, TaskCompletionSource realUrlsAvailableTcs, ILogger logger, IHostApplicationLifetime applicationLifetime, IConfiguration configuration) { app.UseDeveloperExceptionPage(); EnableConfiguredPathbase(app, configuration); app.UseWebAssemblyDebugging(); - bool applyCopHeaders = configuration.GetValue("ApplyCopHeaders"); + DevServerOptions options = optionsContainer.Value; - if (applyCopHeaders) + if (options.WebServerUseCrossOriginPolicy) { app.Use(async (ctx, next) => { @@ -63,6 +66,29 @@ public static void Configure(IApplicationBuilder app, TaskCompletionSource + { + if (ctx.Request.Path.StartsWithSegments("/console")) + { + if (!ctx.WebSockets.IsWebSocketRequest) + { + ctx.Response.StatusCode = 400; + return; + } + + using WebSocket socket = await ctx.WebSockets.AcceptWebSocketAsync(); + await options.OnConsoleConnected(socket); + } + else + { + await next(ctx); + } + }); + } app.UseEndpoints(endpoints => { @@ -70,7 +96,7 @@ public static void Configure(IApplicationBuilder app, TaskCompletionSource { - if (applyCopHeaders) + if (options.WebServerUseCrossOriginPolicy) { // Browser multi-threaded runtime requires cross-origin policy headers to enable SharedArrayBuffer. ApplyCrossOriginPolicyHeaders(fileContext.Context); diff --git a/src/mono/wasm/host/Program.cs b/src/mono/wasm/host/Program.cs index a5005dce9d0fc4..105eb59929ecab 100644 --- a/src/mono/wasm/host/Program.cs +++ b/src/mono/wasm/host/Program.cs @@ -30,6 +30,9 @@ public static async Task Main(string[] args) RegisterHostHandler(WasmHost.Wasmtime, WasiEngineHost.InvokeAsync); using CancellationTokenSource cts = new(); + + Console.CancelKeyPress += (object? sender, ConsoleCancelEventArgs e) => cts.Cancel(); + ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder .AddPassThroughConsole() diff --git a/src/mono/wasm/templates/templates/browser/README.md b/src/mono/wasm/templates/templates/browser/README.md deleted file mode 100644 index 7ddf4fd1bce9bd..00000000000000 --- a/src/mono/wasm/templates/templates/browser/README.md +++ /dev/null @@ -1,26 +0,0 @@ -## .NET WebAssembly Browser app - -## Build - -You can build the app from Visual Studio or from the command-line: - -``` -dotnet build -c Debug/Release -``` - -After building the app, the result is in the `bin/$(Configuration)/net7.0/browser-wasm/AppBundle` directory. - -## Run - -You can build the app from Visual Studio or the command-line: - -``` -dotnet run -c Debug/Release -``` - -Or you can start any static file server from the AppBundle directory: - -``` -dotnet tool install dotnet-serve -dotnet serve -d:bin/$(Configuration)/net7.0/browser-wasm/AppBundle -``` \ No newline at end of file diff --git a/src/mono/wasm/templates/templates/browser/browser.0.csproj b/src/mono/wasm/templates/templates/browser/browser.0.csproj index 401bdae24fab86..588c5219582125 100644 --- a/src/mono/wasm/templates/templates/browser/browser.0.csproj +++ b/src/mono/wasm/templates/templates/browser/browser.0.csproj @@ -1,13 +1,6 @@ - + - net7.0 - browser-wasm - Exe + net8.0 true - - - - - diff --git a/src/mono/wasm/templates/templates/browser/runtimeconfig.template.json b/src/mono/wasm/templates/templates/browser/runtimeconfig.template.json index 8f0557352c6ed3..b96a94320ba5ee 100644 --- a/src/mono/wasm/templates/templates/browser/runtimeconfig.template.json +++ b/src/mono/wasm/templates/templates/browser/runtimeconfig.template.json @@ -3,9 +3,8 @@ "perHostConfig": [ { "name": "browser", - "html-path": "index.html", - "Host": "browser" + "host": "browser" } ] } -} +} \ No newline at end of file diff --git a/src/mono/wasm/templates/templates/browser/index.html b/src/mono/wasm/templates/templates/browser/wwwroot/index.html similarity index 100% rename from src/mono/wasm/templates/templates/browser/index.html rename to src/mono/wasm/templates/templates/browser/wwwroot/index.html diff --git a/src/mono/wasm/templates/templates/browser/main.js b/src/mono/wasm/templates/templates/browser/wwwroot/main.js similarity index 100% rename from src/mono/wasm/templates/templates/browser/main.js rename to src/mono/wasm/templates/templates/browser/wwwroot/main.js From f841e210743e4ffe623bdc07084d3fd3cc770d69 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:43:55 -0700 Subject: [PATCH 110/783] Update dependencies from https://github.com/dotnet/arcade build 20230829.1 (#91329) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23428.2 -> To Version 8.0.0-beta.23429.1 Dependency coherency updates Microsoft.DotNet.XliffTasks From Version 1.0.0-beta.23423.1 -> To Version 1.0.0-beta.23426.1 (parent: Microsoft.DotNet.Arcade.Sdk Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 76 ++++++++++++++++++++--------------------- eng/Versions.props | 30 ++++++++-------- global.json | 6 ++-- 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index efb4b40dceea8c..c60d708a560fa2 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -107,79 +107,79 @@ - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/xliff-tasks - ed9a83526483c094fb51e7000b6f816ce6cb0325 + 194f32828726c3f1f63f79f3dc09b9e99c157b11 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 https://github.com/dotnet/runtime-assets @@ -330,9 +330,9 @@ https://github.com/dotnet/xharness 480b9159eb7e69b182a87581d5a336e97e0b6dae - + https://github.com/dotnet/arcade - 3d92d0bfd8c9006f5fe1687e465dc4f8aa068b00 + 804d586c07a6c598551a2913f0958680cb9135a9 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index 6b31387aabe99d..f6df5c7fdd62e8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -85,21 +85,21 @@ 8.0.100-preview.7.23329.3 - 8.0.0-beta.23428.2 - 8.0.0-beta.23428.2 - 8.0.0-beta.23428.2 - 8.0.0-beta.23428.2 - 8.0.0-beta.23428.2 - 2.5.1-beta.23428.2 - 8.0.0-beta.23428.2 - 8.0.0-beta.23428.2 - 8.0.0-beta.23428.2 - 8.0.0-beta.23428.2 - 8.0.0-beta.23428.2 - 8.0.0-beta.23428.2 - 8.0.0-beta.23428.2 - 8.0.0-beta.23428.2 - 8.0.0-beta.23428.2 + 8.0.0-beta.23429.1 + 8.0.0-beta.23429.1 + 8.0.0-beta.23429.1 + 8.0.0-beta.23429.1 + 8.0.0-beta.23429.1 + 2.5.1-beta.23429.1 + 8.0.0-beta.23429.1 + 8.0.0-beta.23429.1 + 8.0.0-beta.23429.1 + 8.0.0-beta.23429.1 + 8.0.0-beta.23429.1 + 8.0.0-beta.23429.1 + 8.0.0-beta.23429.1 + 8.0.0-beta.23429.1 + 8.0.0-beta.23429.1 6.0.0-preview.1.102 diff --git a/global.json b/global.json index fd45afe4dd2784..bdd818850a3add 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.100-preview.7.23376.3" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23428.2", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23428.2", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23428.2", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23429.1", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23429.1", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23429.1", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From a02c66044abbb4f4d9db87ebc370f78ba084b945 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:47:43 -0700 Subject: [PATCH 111/783] Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230829.4 (#91330) optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23427.2 -> To Version 1.0.0-prerelease.23429.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c60d708a560fa2..e2026ba5907ba6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -334,21 +334,21 @@ https://github.com/dotnet/arcade 804d586c07a6c598551a2913f0958680cb9135a9 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - ffa66bdcbd319c11795d23e835e7a44344723332 + 1d8fc814dda596c04d571122ce984f45f92c56f8 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - ffa66bdcbd319c11795d23e835e7a44344723332 + 1d8fc814dda596c04d571122ce984f45f92c56f8 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - ffa66bdcbd319c11795d23e835e7a44344723332 + 1d8fc814dda596c04d571122ce984f45f92c56f8 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - ffa66bdcbd319c11795d23e835e7a44344723332 + 1d8fc814dda596c04d571122ce984f45f92c56f8 https://github.com/dotnet/hotreload-utils @@ -384,13 +384,13 @@ d10b02ae5cc670609d920a672985ed4456bdd6b6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - ffa66bdcbd319c11795d23e835e7a44344723332 + 1d8fc814dda596c04d571122ce984f45f92c56f8 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - ffa66bdcbd319c11795d23e835e7a44344723332 + 1d8fc814dda596c04d571122ce984f45f92c56f8 diff --git a/eng/Versions.props b/eng/Versions.props index f6df5c7fdd62e8..8234d10cc507cc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -156,12 +156,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23427.2 - 1.0.0-prerelease.23427.2 - 1.0.0-prerelease.23427.2 - 1.0.0-prerelease.23427.2 - 1.0.0-prerelease.23427.2 - 1.0.0-prerelease.23427.2 + 1.0.0-prerelease.23429.4 + 1.0.0-prerelease.23429.4 + 1.0.0-prerelease.23429.4 + 1.0.0-prerelease.23429.4 + 1.0.0-prerelease.23429.4 + 1.0.0-prerelease.23429.4 16.11.27-beta1.23180.1 2.0.0-beta4.23307.1 From 592e01f5619a21e331d8b1fcf129f05cf8626816 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:48:03 -0700 Subject: [PATCH 112/783] Ensure the relevant containable nodes are handled (#91334) Co-authored-by: Tanner Gooding --- src/coreclr/jit/lowerxarch.cpp | 16 +++++ .../JitBlue/Runtime_91170/Runtime_91170.cs | 63 +++++++++++++++++++ .../Runtime_91170/Runtime_91170.csproj | 8 +++ 3 files changed, 87 insertions(+) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91170/Runtime_91170.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91170/Runtime_91170.csproj diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index c1b5079f124545..00143839a440d7 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -8135,7 +8135,16 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_Vector128_ToScalar: case NI_Vector256_ToScalar: case NI_Vector512_ToScalar: + case NI_SSE2_ConvertToInt32: + case NI_SSE2_ConvertToUInt32: + case NI_SSE2_X64_ConvertToInt64: + case NI_SSE2_X64_ConvertToUInt64: + case NI_SSE2_Extract: + case NI_SSE41_Extract: + case NI_SSE41_X64_Extract: case NI_AVX_ExtractVector128: + case NI_AVX2_ConvertToInt32: + case NI_AVX2_ConvertToUInt32: case NI_AVX2_ExtractVector128: case NI_AVX512F_ExtractVector128: case NI_AVX512F_ExtractVector256: @@ -8178,6 +8187,13 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre return false; } + case NI_Vector128_get_Zero: + case NI_Vector256_get_Zero: + { + // These are only containable as part of Sse41.Insert + return false; + } + case NI_SSE3_MoveAndDuplicate: case NI_AVX2_BroadcastScalarToVector128: case NI_AVX2_BroadcastScalarToVector256: diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91170/Runtime_91170.cs b/src/tests/JIT/Regression/JitBlue/Runtime_91170/Runtime_91170.cs new file mode 100644 index 00000000000000..afb26b6def0bc0 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91170/Runtime_91170.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license.aa + +// Found by Antigen + +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using System.Numerics; +using Xunit; + +public class TestClass +{ + public struct S1 + { + } + + static short s_short_8 = 5; + static int s_int_9 = -2; + long long_59 = 4; + uint uint_64 = 1; + Vector256 v256_int_90 = Vector256.Create(2, -5, 4, 4, 5, 0, -1, 5); + S1 s1_99 = new S1(); + + private uint Method4(out short p_short_161, S1 p_s1_162, bool p_bool_163, ref int p_int_164) + { + unchecked + { + p_short_161 = 15|4; + if ((long_59 *= 15>>4)!= (long_59 |= 15^4)) + { + } + else + { + Vector128.CreateScalarUnsafe(Vector256.Sum(v256_int_90)); + } + return 15|4; + } + } + + private void Method0() + { + unchecked + { + uint_64 = Method4(out s_short_8, s1_99, 15<4, ref s_int_9); + return; + } + } + + [Fact] + public static void TestEntryPoint() + { + new TestClass().Method0(); + } +} +/* + +Assert failure(PID 34336 [0x00008620], Thread: 38576 [0x96b0]): Assertion failed '!childNode->isContainableHWIntrinsic()' in 'TestClass:Method4(byref,TestClass+S1,bool,byref):uint:this' during 'Lowering nodeinfo' (IL size 63; hash 0xa4e6dede; Tier0) + File: D:\git\runtime\src\coreclr\jit\lowerxarch.cpp Line: 8201 + Image: D:\git\runtime\artifacts\tests\coreclr\windows.x64.Checked\tests\Core_Root\CoreRun.exe +*/ diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91170/Runtime_91170.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_91170/Runtime_91170.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91170/Runtime_91170.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From 8ec6101174f841ec455180fba8f08d895e76ef2a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 14:06:02 -0700 Subject: [PATCH 113/783] [release/8.0] Emit interceptor info correctly when invocation expr is on separate line (#91218) * Emit interceptor info correctly when invocation expr is on separate line * Add more tests and add helper to udpate baselines * Add comments to binding gen tests for invocations on new lines (#91237) * Add comments to binding gen tests for invocations on new lines * Address feedback & test static method call syntax * Reorganize and comment the newline/whitespace scenarios * Reorganize and comment the newline/whitespace scenarios for ConfigurationExtensions --------- Co-authored-by: Jeff Handley * Update baselines --------- Co-authored-by: Layomi Akinrinade Co-authored-by: Jeff Handley --- ...onfigurationServiceCollectionExtensions.cs | 2 +- .../gen/Helpers/InterceptorLocationInfo.cs | 35 ++- .../ConfigurationBinderTests.Helpers.cs | 12 + .../ConfigurationBinderTests.TestClasses.cs | 12 - .../OptionsBuilder/Bind_T.generated.txt | 2 +- .../Bind_T_BinderOptions.generated.txt | 2 +- .../Configure_T.generated.txt | 2 +- .../Configure_T_BinderOptions.generated.txt | 2 +- .../Configure_T_name.generated.txt | 2 +- ...nfigure_T_name_BinderOptions.generated.txt | 2 +- .../ConfigurationBinderTests.Generator.cs | 253 ++++++++++++++++++ ...cs => GeneratorTests.Baselines.Options.cs} | 2 +- ...selines.cs => GeneratorTests.Baselines.cs} | 3 +- ...ingGeneratorTests.cs => GeneratorTests.cs} | 22 +- ...ation.Binder.SourceGeneration.Tests.csproj | 9 +- .../Common/ConfigurationExtensionsTests.cs | 21 ++ ...ionsBuilderConfigurationExtensionsTests.cs | 7 +- .../ConfigurationExtensionsTest.Generator.cs | 160 +++++++++++ ...onExtensions.SourceGeneration.Tests.csproj | 4 +- 19 files changed, 502 insertions(+), 52 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBinderTests.Generator.cs rename src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/{ConfigurationBindingGeneratorTests.Baselines.Options.cs => GeneratorTests.Baselines.Options.cs} (98%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/{ConfigurationBindingGeneratorTests.Baselines.cs => GeneratorTests.Baselines.cs} (99%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/{ConfigurationBindingGeneratorTests.cs => GeneratorTests.cs} (94%) create mode 100644 src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Common/ConfigurationExtensionsTests.cs create mode 100644 src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/ConfigurationExtensionsTest.Generator.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs index 0348eb5047e970..41eeb8b657342d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs @@ -62,7 +62,7 @@ private void EmitConfigureMethods() _writer.WriteLine($$""" OptionsServiceCollectionExtensions.AddOptions({{Identifier.services}}); {{Identifier.services}}.{{Identifier.AddSingleton}}<{{Identifier.IOptionsChangeTokenSource}}<{{Identifier.TOptions}}>>(new {{Identifier.ConfigurationChangeTokenSource}}<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.configuration}})); - return {{Identifier.services}}.{{Identifier.AddSingleton}}<{{optionsNamespaceName}}.IConfigureOptions<{{Identifier.TOptions}}>>(new {{optionsNamespaceName}}.ConfigureNamedOptions<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.obj}} => {{nameof(MethodsToGen_CoreBindingHelper.BindCoreMain)}}({{Identifier.configuration}}, {{Identifier.obj}}, typeof({{Identifier.TOptions}}){{Identifier.configureOptions}}))); + return {{Identifier.services}}.{{Identifier.AddSingleton}}<{{optionsNamespaceName}}.IConfigureOptions<{{Identifier.TOptions}}>>(new {{optionsNamespaceName}}.ConfigureNamedOptions<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.obj}} => {{nameof(MethodsToGen_CoreBindingHelper.BindCoreMain)}}({{Identifier.configuration}}, {{Identifier.obj}}, typeof({{Identifier.TOptions}}), {{Identifier.configureOptions}}))); """); EmitEndBlock(); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/InterceptorLocationInfo.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/InterceptorLocationInfo.cs index d1dc4f4afa7e7e..441acbe6a7444f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/InterceptorLocationInfo.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/InterceptorLocationInfo.cs @@ -15,28 +15,27 @@ internal sealed record InterceptorLocationInfo { public InterceptorLocationInfo(IInvocationOperation operation) { - SyntaxNode operationSyntax = operation.Syntax; - TextSpan operationSpan = operationSyntax.Span; - SyntaxTree operationSyntaxTree = operationSyntax.SyntaxTree; - - FilePath = GetInterceptorFilePath(operationSyntaxTree, operation.SemanticModel?.Compilation.Options.SourceReferenceResolver); - - FileLinePositionSpan span = operationSyntaxTree.GetLineSpan(operationSpan); - LineNumber = span.StartLinePosition.Line + 1; - - // Calculate the character offset to the end of the binding invocation detected. - int invocationLength = ((MemberAccessExpressionSyntax)((InvocationExpressionSyntax)operationSyntax).Expression).Expression.Span.Length; - CharacterNumber = span.StartLinePosition.Character + invocationLength + 2; + MemberAccessExpressionSyntax memberAccessExprSyntax = ((MemberAccessExpressionSyntax)((InvocationExpressionSyntax)operation.Syntax).Expression); + SyntaxTree operationSyntaxTree = operation.Syntax.SyntaxTree; + TextSpan memberNameSpan = memberAccessExprSyntax.Name.Span; + FileLinePositionSpan linePosSpan = operationSyntaxTree.GetLineSpan(memberNameSpan); + + LineNumber = linePosSpan.StartLinePosition.Line + 1; + CharacterNumber = linePosSpan.StartLinePosition.Character + 1; + FilePath = GetInterceptorFilePath(); + + // Use the same logic used by the interceptors API for resolving the source mapped value of a path. + // https://github.com/dotnet/roslyn/blob/f290437fcc75dad50a38c09e0977cce13a64f5ba/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs#L1063-L1064 + string GetInterceptorFilePath() + { + SourceReferenceResolver? sourceReferenceResolver = operation.SemanticModel?.Compilation.Options.SourceReferenceResolver; + return sourceReferenceResolver?.NormalizePath(operationSyntaxTree.FilePath, baseFilePath: null) ?? operationSyntaxTree.FilePath; + } } public string FilePath { get; } public int LineNumber { get; } public int CharacterNumber { get; } - - // Utilize the same logic used by the interceptors API for resolving the source mapped value of a path. - // https://github.com/dotnet/roslyn/blob/f290437fcc75dad50a38c09e0977cce13a64f5ba/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs#L1063-L1064 - private static string GetInterceptorFilePath(SyntaxTree tree, SourceReferenceResolver? resolver) => - resolver?.NormalizePath(tree.FilePath, baseFilePath: null) ?? tree.FilePath; } internal sealed record ConfigurationBinderInterceptorInfo @@ -52,7 +51,7 @@ public void RegisterOverloadInfo(MethodsToGen_ConfigurationBinder overload, Type } public OverloadInterceptorInfo GetOverloadInfo(MethodsToGen_ConfigurationBinder overload) => - DetermineOverload(overload, initIfNull: false) ?? throw new ArgumentNullException(nameof(overload)); + DetermineOverload(overload, initIfNull: false) ?? throw new ArgumentOutOfRangeException(nameof(overload)); private OverloadInterceptorInfo? DetermineOverload(MethodsToGen_ConfigurationBinder overload, bool initIfNull) { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.Helpers.cs index a1d1a72ffab20f..d6521ed86dfdec 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.Helpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.Helpers.cs @@ -160,5 +160,17 @@ public class CustomICollectionWithoutAnAddMethod : ICollection public int Count => _items.Count; public bool IsReadOnly => false; } + + public interface IGeolocation + { + public double Latitude { get; set; } + public double Longitude { get; set; } + } + + public sealed record GeolocationRecord : IGeolocation + { + public double Latitude { get; set; } + public double Longitude { get; set; } + } #endregion } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs index 1e537b407963d9..76ed9d959e6220 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs @@ -667,12 +667,6 @@ public struct StructWithParameterlessAndParameterizedCtor public int MyInt { get; } } - public interface IGeolocation - { - public double Latitude { get; set; } - public double Longitude { get; set; } - } - [TypeConverter(typeof(GeolocationTypeConverter))] public struct Geolocation : IGeolocation { @@ -704,12 +698,6 @@ public sealed class GeolocationClass : IGeolocation public double Longitude { get; set; } } - public sealed record GeolocationRecord : IGeolocation - { - public double Latitude { get; set; } - public double Longitude { get; set; } - } - public class GeolocationWrapper { public Geolocation Location { get; set; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt index 633196e7a742d5..ff590d8398f3a1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt @@ -68,7 +68,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration OptionsServiceCollectionExtensions.AddOptions(services); services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); - return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions)configureOptions))); + return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions), configureOptions))); } #endregion IServiceCollection extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt index fb5b4b4ad721d8..b7b6ef86a4c056 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt @@ -62,7 +62,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration OptionsServiceCollectionExtensions.AddOptions(services); services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); - return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions)configureOptions))); + return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions), configureOptions))); } #endregion IServiceCollection extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt index 7f626f0e27c527..7a956f99b57b13 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt @@ -53,7 +53,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration OptionsServiceCollectionExtensions.AddOptions(services); services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); - return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions)configureOptions))); + return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions), configureOptions))); } #endregion IServiceCollection extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt index 5848c2412f9b78..399f6ffe35b935 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt @@ -53,7 +53,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration OptionsServiceCollectionExtensions.AddOptions(services); services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); - return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions)configureOptions))); + return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions), configureOptions))); } #endregion IServiceCollection extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt index 91226d730166f1..197e268561f7eb 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt @@ -53,7 +53,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration OptionsServiceCollectionExtensions.AddOptions(services); services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); - return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions)configureOptions))); + return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions), configureOptions))); } #endregion IServiceCollection extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt index 8c9ccaa71a779f..0cb5881950dee3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt @@ -47,7 +47,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration OptionsServiceCollectionExtensions.AddOptions(services); services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); - return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions)configureOptions))); + return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions), configureOptions))); } #endregion IServiceCollection extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBinderTests.Generator.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBinderTests.Generator.cs new file mode 100644 index 00000000000000..0e4a97b85b548a --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBinderTests.Generator.cs @@ -0,0 +1,253 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Extensions.Configuration; +using Xunit; + +namespace Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests +{ + public partial class ConfigurationBinderTests : ConfigurationBinderTestsBase + { + // These are regression tests for https://github.com/dotnet/runtime/issues/90851 + // Source Generator Interceptors rely on identifying an accurate invocation + // source location (line and character positions). These tests cover newline + // and whitespace scenarios to ensure the interceptors get wired up correctly. + + [Fact] + public void TestBindingInvocationsWithNewlines_GetMethodTypeArg() + { + IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{""Longitude"":1,""Latitude"":2}"); + + // Newline between the configuration instance and the binding invocation (with the dot on the first line) + GeolocationRecord record1 = (GeolocationRecord)configuration. + Get(typeof(GeolocationRecord), _ => { }); + + AssertRecordIsBound(record1, 1, 2); + + // Newline between the configuration instance and the binding invocation (with the dot on the second line) + GeolocationRecord record2 = (GeolocationRecord)configuration + .Get(typeof(GeolocationRecord), _ => { }); + + AssertRecordIsBound(record2, 1, 2); + + // Newlines between the instance, the invocation, and the arguments + GeolocationRecord record3 = (GeolocationRecord)configuration + .Get( + typeof(GeolocationRecord), + _ => { } + ); + + AssertRecordIsBound(record3, 1, 2); + + // Newlines before and after the instance (with the dot on the first line) + GeolocationRecord record4 = (GeolocationRecord) + configuration. + Get(typeof(GeolocationRecord), _ => { }); + + AssertRecordIsBound(record4, 1, 2); + + // Newlines before and after the instance (with the dot on the second line) + GeolocationRecord record5 = (GeolocationRecord) + configuration + .Get(typeof(GeolocationRecord), _ => { }); + + AssertRecordIsBound(record5, 1, 2); + + // Newlines in every place possible + GeolocationRecord + record6 + = + ( + GeolocationRecord + ) + configuration + . + Get + ( + typeof + ( + GeolocationRecord + ) + , + _ + => + { + } + ) + ; + + AssertRecordIsBound(record6, 1, 2); + } + + [Fact] + public void TestBindingInvocationsWithNewlines_GetMethodGeneric() + { + IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{""Longitude"":1,""Latitude"":2}"); + + // Newline between the invocation method name and the generic type argument + GeolocationRecord record1 = configuration.Get + (); + + AssertRecordIsBound(record1, 1, 2); + + // Newlines on either side of the generic type argument + GeolocationRecord record2 = configuration.Get< + GeolocationRecord + >(); + + AssertRecordIsBound(record2, 1, 2); + + // Newlines in every place possible + GeolocationRecord + record3 + = + configuration + . + Get + < + GeolocationRecord + > + () + ; + + AssertRecordIsBound(record3, 1, 2); + } + + [Fact] + public void TestBindingInvocationsWithNewlines_BindExtensionMethod() + { + // Newline between the configuration instance and the extension method invocation + GeolocationRecord record1 = new GeolocationRecord(); + TestHelpers.GetConfigurationFromJsonString(@"{""Longitude"":1,""Latitude"":2}") + .Bind(record1); + + AssertRecordIsBound(record1, 1, 2); + + // Newlines between the method that returns the instance and the extension method invocation + GeolocationRecord record2 = new GeolocationRecord(); + TestHelpers + .GetConfigurationFromJsonString(@"{""Longitude"":1,""Latitude"":2}") + .Bind(record2); + + AssertRecordIsBound(record2, 1, 2); + + // Newlines within the argument to the method returning the configuration and around the extension method argument + GeolocationRecord record3 = new GeolocationRecord(); + TestHelpers + .GetConfigurationFromJsonString(@"{""Longitude"":1, + ""Latitude"":2} + ") + .Bind( + record3 + ); + + AssertRecordIsBound(record3, 1, 2); + + // Newlines in every place possible + GeolocationRecord record4 = new GeolocationRecord(); + TestHelpers + . + GetConfigurationFromJsonString + ( + @"{""Longitude"":1, ""Latitude"":2}" + ) + . + Bind + ( + record4 + ) + ; + + AssertRecordIsBound(record4, 1, 2); + } + + [Fact] + public void TestBindingInvocationsWithNewlines_BindStaticMethod() + { + IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{""Longitude"":1,""Latitude"":2}"); + + // Newline between the class and the static method invocation (with the dot on the first line) + GeolocationRecord record1 = new GeolocationRecord(); + ConfigurationBinder. + Bind(configuration, record1); + + // Newline between the class and the static method invocation (with the dot on the second line) + GeolocationRecord record2 = new GeolocationRecord(); + ConfigurationBinder + .Bind(configuration, record2); + + AssertRecordIsBound(record2, 1, 2); + + // Newline before the arguments + GeolocationRecord record3 = new GeolocationRecord(); + ConfigurationBinder.Bind( + configuration, record3); + + AssertRecordIsBound(record3, 1, 2); + + // Newlines in every place possible + GeolocationRecord record4 = new GeolocationRecord(); + ConfigurationBinder + . + Bind + ( + configuration + , + record4 + ) + ; + + AssertRecordIsBound(record4, 1, 2); + } + + [Fact] + public void TestBindingInvocationsWithNewlines_GetValueMethod() + { + IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{""Longitude"":1,""Latitude"":2}"); + + // Newline between the configuration instance and the binding invocation (with the dot on the first line) + int lat1 = configuration. + GetValue("Latitude"); + + Assert.Equal(2, lat1); + + // Newline between the configuration instance and the binding invocation (with the dot on the second line) + int lat2 = configuration + .GetValue("Latitude"); + + Assert.Equal(2, lat2); + + // Newlines in every place possible + long + lat3 + = + configuration + . + GetValue + < + int + > + ( + "Latitude" + ) + ; + Assert.Equal(2, lat3); + + // Newlines and pragmas wrapped around the generic type argument + long lat4 = configuration.GetValue< +#if DEBUG + int +#else + long +#endif + >("Latitude"); + + Assert.Equal(2, lat4); + } + + private static void AssertRecordIsBound(GeolocationRecord record, int longitude, int latitude) + { + Assert.Equal((longitude, latitude), (record.Longitude, record.Latitude)); + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.Options.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.Options.cs similarity index 98% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.Options.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.Options.cs index c9eb9c70927f99..0126744eacbfa4 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.Options.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.Options.cs @@ -4,7 +4,7 @@ using System.Threading.Tasks; using Xunit; -namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests +namespace Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests { public partial class ConfigurationBindingGeneratorTests { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs similarity index 99% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs index b5c3fb49c5e7eb..65e812d30b420f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.Baselines.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs @@ -8,7 +8,7 @@ using Microsoft.CodeAnalysis.CSharp; using Xunit; -namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests +namespace Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests { public partial class ConfigurationBindingGeneratorTests { @@ -649,7 +649,6 @@ public interface ICustomSet : ISet await VerifyAgainstBaselineUsingFile("Collections.generated.txt", source, assessDiagnostics: (d) => { - Console.WriteLine((d.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count(), d.Where(diag => diag.Id == Diagnostics.PropertyNotSupported.Id).Count())); Assert.Equal(3, d.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); Assert.Equal(6, d.Where(diag => diag.Id == Diagnostics.PropertyNotSupported.Id).Count()); }); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs similarity index 94% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs index a512c5efe495b1..68f8a66612e67f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs @@ -14,13 +14,14 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration.Binder.SourceGeneration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests; using SourceGenerators.Tests; using Xunit; -namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests +namespace Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests { [ActiveIssue("https://github.com/dotnet/runtime/issues/52062", TestPlatforms.Browser)] public partial class ConfigurationBindingGeneratorTests : ConfigurationBinderTestsBase @@ -388,11 +389,24 @@ private static async Task VerifyAgainstBaselineUsingFile( var (d, r) = await RunGenerator(testSourceCode, languageVersion); bool success = RoslynTestUtils.CompareLines(expectedLines, r[0].SourceText, out string errorMessage); -#if !SKIP_BASELINES +#if UPDATE_BASELINES + if (!success) + { + string? repoRootDir = Environment.GetEnvironmentVariable("RepoRootDir"); + Assert.True(repoRootDir is not null, "To update baselines, specifiy the root runtime repo dir"); + + IEnumerable lines = r[0].SourceText.Lines.Select(l => l.ToString()); + string source = string.Join(Environment.NewLine, lines).TrimEnd(Environment.NewLine.ToCharArray()) + Environment.NewLine; + path = Path.Combine($"{repoRootDir}\\src\\libraries\\Microsoft.Extensions.Configuration.Binder\\tests\\SourceGenerationTests\\", path); + + await File.WriteAllTextAsync(path, source).ConfigureAwait(false); + success = true; + } +#endif + Assert.Single(r); (assessDiagnostics ?? ((d) => Assert.Empty(d))).Invoke(d); Assert.True(success, errorMessage); -#endif } private static async Task<(ImmutableArray, ImmutableArray)> RunGenerator( diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj index cfd45c365d42a0..94d95564a47352 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj @@ -11,7 +11,7 @@ $(DefineConstants);BUILDING_SOURCE_GENERATOR_TESTS;ROSLYN4_0_OR_GREATER;ROSLYN4_4_OR_GREATER $(DefineConstants);LAUNCH_DEBUGGER - $(DefineConstants);SKIP_BASELINES + $(DefineConstants);UPDATE_BASELINES @@ -28,6 +28,7 @@ + @@ -50,9 +51,9 @@ PreserveNewest - - - + + + diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Common/ConfigurationExtensionsTests.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Common/ConfigurationExtensionsTests.cs new file mode 100644 index 00000000000000..95cee559072f07 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Common/ConfigurationExtensionsTests.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace Microsoft.Extensions.Options.ConfigurationExtensions.Tests +{ + public partial class ConfigurationExtensionsTests + { + private static IConfiguration s_emptyConfig { get; } = new ConfigurationBuilder().Build(); + + private static OptionsBuilder CreateOptionsBuilder() + { + var services = new ServiceCollection(); + return new OptionsBuilder(services, Options.DefaultName); + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Common/OptionsBuilderConfigurationExtensionsTests.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Common/OptionsBuilderConfigurationExtensionsTests.cs index 6d1d4a018f097e..d90122ef74d8bc 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Common/OptionsBuilderConfigurationExtensionsTests.cs +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Common/OptionsBuilderConfigurationExtensionsTests.cs @@ -31,7 +31,8 @@ public static void BindConfiguration_ThrowsForNullConfigurationSectionPath() Assert.Throws("configSectionPath", () => { - optionsBuilder.BindConfiguration(configSectionPath); + optionsBuilder + .BindConfiguration(configSectionPath); }); } @@ -170,8 +171,8 @@ public static void BindConfiguration_UpdatesOptionOnConfigurationUpdate() services.AddSingleton(new ConfigurationBuilder() .Add(configSource) .Build()); - OptionsBuilder optionsBuilder = services.AddOptions(); - _ = optionsBuilder.BindConfiguration(configSectionName); + _ = services.AddOptions() + .BindConfiguration(configSectionName); using ServiceProvider serviceProvider = services.BuildServiceProvider(); var optionsMonitor = serviceProvider.GetRequiredService>(); bool updateHasRun = false; diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/ConfigurationExtensionsTest.Generator.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/ConfigurationExtensionsTest.Generator.cs new file mode 100644 index 00000000000000..a18efc6909b71d --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/ConfigurationExtensionsTest.Generator.cs @@ -0,0 +1,160 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace Microsoft.Extensions.Options.ConfigurationExtensions.Tests +{ + public partial class ConfigurationExtensionsTests + { + // These are regression tests for https://github.com/dotnet/runtime/issues/90851 + // Source Generator Interceptors rely on identifying an accurate invocation + // source location (line and character positions). These tests cover newline + // and whitespace scenarios to ensure the interceptors get wired up correctly. + + [Fact] + public void TestBindingInvocationsWithNewlines_BindExtension() + { + OptionsBuilder? optionsBuilder = CreateOptionsBuilder(); + + // Newline between instance and invocation using configureBinder argument (with the dot on the first line) + optionsBuilder. + Bind(s_emptyConfig, configureBinder: null); + + // Newline between instance and invocation using configureBinder argument (with the dot on the second line) + optionsBuilder + .Bind(s_emptyConfig, configureBinder: null); + + // Newline between instance and invocation (with the dot on the first line) + optionsBuilder. + Bind(s_emptyConfig); + + // Newline between instance and invocation (with the dot on the second line) + optionsBuilder + .Bind(s_emptyConfig); + + // Newlines in every place possible + optionsBuilder + . + Bind + ( + s_emptyConfig + , + configureBinder + : + null + ) + ; + } + + [Fact] + public void TestBindingInvocationsWithNewlines_BindConfigurationExtension() + { + OptionsBuilder? optionsBuilder = CreateOptionsBuilder(); + + // Newline between instance and invocation using configureBinder argument (with the dot on the first line) + optionsBuilder. + BindConfiguration(configSectionPath: "path", + _ => { }); + + // Newline between instance and invocation using configureBinder argument (with the dot on the second line) + optionsBuilder + .BindConfiguration(configSectionPath: "path", + _ => { }); + + // Newlines between the instance and invocation and within the arguments. No indentation before invocation. + optionsBuilder. + BindConfiguration( + configSectionPath: "path", + _ => { }); + + // Newlines in every place possible + optionsBuilder + . + BindConfiguration + ( + configSectionPath + : + "path" + , + _ + => + { + } + ) + ; + } + + [Fact] + public void TestBindingInvocationsWithNewlines_ConfigureExtension() + { + OptionsBuilder? optionsBuilder = CreateOptionsBuilder(); + IServiceCollection services = new ServiceCollection(); + + // Newlines between each method call + services + .Configure(s_emptyConfig) + .AddOptions(); + + // Newlines in every place possible + services + . + Configure + < + FakeOptions + > + ( + name + : + null! + , + s_emptyConfig + ) + ; + } + + [Fact] + public void TestBindingInvocationsWithNewlines_StaticCalls() + { + OptionsBuilder? optionsBuilder = CreateOptionsBuilder(); + IServiceCollection services = new ServiceCollection(); + + // Bind: Newlines in every place possible + OptionsBuilderConfigurationExtensions + . + Bind + ( + optionsBuilder + , + s_emptyConfig + ) + ; + + // // BindConfiguration: Newlines in every place possible + OptionsBuilderConfigurationExtensions + . + BindConfiguration + ( + optionsBuilder + , + "path" + ); + + // Configure: Newlines in every place possible + OptionsConfigurationServiceCollectionExtensions + . + Configure + < + FakeOptions + > + ( + services + , + s_emptyConfig + ) + ; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/Microsoft.Extensions.Options.ConfigurationExtensions.SourceGeneration.Tests.csproj b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/Microsoft.Extensions.Options.ConfigurationExtensions.SourceGeneration.Tests.csproj index 0676fddc289826..f08d2bd649bc3f 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/Microsoft.Extensions.Options.ConfigurationExtensions.SourceGeneration.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/Microsoft.Extensions.Options.ConfigurationExtensions.SourceGeneration.Tests.csproj @@ -20,10 +20,12 @@ + - + + From 71740922153cdfab9f853a8deb6357eac3172561 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 14:07:02 -0700 Subject: [PATCH 114/783] [release/8.0] Fix crash when calling AssemblyLoadContext.Unload twice (#91346) * Fix crash when calling AssemblyLoadContext.Unload twice The AssemblyLoadContext.InitiateUnload method was not handling multiple calls correctly. Instead of making the extra calls dummy, it was calling the native runtime helper again. This change fixes it by simply ensuring that the runtime helper is called just once. * Add regression test --------- Co-authored-by: Jan Vorlicek --- .../Runtime/Loader/AssemblyLoadContext.cs | 29 ++++++++++++------- .../CollectibleAssemblyLoadContextTest.cs | 19 +++++++++++- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs index b8b4ba086ad69b..59123e42fb52a2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs @@ -135,25 +135,32 @@ private void InitiateUnload() { RaiseUnloadEvent(); + InternalState previousState; + // When in Unloading state, we are not supposed to be called on the finalizer // as the native side is holding a strong reference after calling Unload lock (_unloadLock) { - Debug.Assert(_state == InternalState.Alive); - - var thisStrongHandle = GCHandle.Alloc(this, GCHandleType.Normal); - var thisStrongHandlePtr = GCHandle.ToIntPtr(thisStrongHandle); - // The underlying code will transform the original weak handle - // created by InitializeLoadContext to a strong handle - PrepareForAssemblyLoadContextRelease(_nativeAssemblyLoadContext, thisStrongHandlePtr); + previousState = _state; + if (previousState == InternalState.Alive) + { + var thisStrongHandle = GCHandle.Alloc(this, GCHandleType.Normal); + var thisStrongHandlePtr = GCHandle.ToIntPtr(thisStrongHandle); + // The underlying code will transform the original weak handle + // created by InitializeLoadContext to a strong handle + PrepareForAssemblyLoadContextRelease(_nativeAssemblyLoadContext, thisStrongHandlePtr); - _state = InternalState.Unloading; + _state = InternalState.Unloading; + } } - Dictionary> allContexts = AllContexts; - lock (allContexts) + if (previousState == InternalState.Alive) { - allContexts.Remove(_id); + Dictionary> allContexts = AllContexts; + lock (allContexts) + { + allContexts.Remove(_id); + } } } diff --git a/src/libraries/System.Runtime.Loader/tests/CollectibleAssemblyLoadContextTest.cs b/src/libraries/System.Runtime.Loader/tests/CollectibleAssemblyLoadContextTest.cs index 90527c3d0be9de..83d1c9aebf61f7 100644 --- a/src/libraries/System.Runtime.Loader/tests/CollectibleAssemblyLoadContextTest.cs +++ b/src/libraries/System.Runtime.Loader/tests/CollectibleAssemblyLoadContextTest.cs @@ -16,12 +16,16 @@ public partial class AssemblyLoadContextTest // Tests related to Collectible assemblies [MethodImpl(MethodImplOptions.NoInlining)] - static void CreateAndLoadContext(CollectibleChecker checker) + static void CreateAndLoadContext(CollectibleChecker checker, bool unloadTwice = false) { var alc = new ResourceAssemblyLoadContext(true); checker.SetAssemblyLoadContext(0, alc); alc.Unload(); + if (unloadTwice) + { + alc.Unload(); + } // Check that any attempt to load an assembly after an explicit Unload will fail Assert.Throws(() => alc.LoadFromAssemblyPath(Path.GetFullPath("none.dll"))); @@ -39,6 +43,19 @@ public static void Unload_CollectibleWithNoAssemblyLoaded() checker.GcAndCheck(); } + [Fact] + [ActiveIssue("https://github.com/mono/mono/issues/15142", TestRuntimes.Mono)] + public static void DoubleUnload_CollectibleWithNoAssemblyLoaded() + { + // Use a collectible ALC + Unload + // Check that we receive the Unloading event + + var checker = new CollectibleChecker(1); + CreateAndLoadContext(checker, unloadTwice: true); + checker.GcAndCheck(); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsPreciseGcSupported))] public static void Finalizer_CollectibleWithNoAssemblyLoaded() { From 41b2c8f8f50e87efa9c2e5435d87fe550631ec44 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Wed, 30 Aug 2023 14:07:16 -0700 Subject: [PATCH 115/783] Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2256251 (#91347) * Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2256251 * Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2256251 --- .../gen/Resources/xlf/Strings.cs.xlf | 4 ++-- .../gen/Resources/xlf/Strings.de.xlf | 4 ++-- .../gen/Resources/xlf/Strings.es.xlf | 4 ++-- .../gen/Resources/xlf/Strings.fr.xlf | 4 ++-- .../gen/Resources/xlf/Strings.it.xlf | 4 ++-- .../gen/Resources/xlf/Strings.ja.xlf | 4 ++-- .../gen/Resources/xlf/Strings.ko.xlf | 4 ++-- .../gen/Resources/xlf/Strings.pl.xlf | 4 ++-- .../gen/Resources/xlf/Strings.pt-BR.xlf | 4 ++-- .../gen/Resources/xlf/Strings.ru.xlf | 4 ++-- .../gen/Resources/xlf/Strings.tr.xlf | 4 ++-- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 4 ++-- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 4 ++-- .../gen/Resources/xlf/Strings.pl.xlf | 2 +- .../gen/Resources/xlf/Strings.pl.xlf | 2 +- .../gen/Common/Resources/xlf/Strings.cs.xlf | 2 +- .../gen/Common/Resources/xlf/Strings.de.xlf | 2 +- .../gen/Common/Resources/xlf/Strings.es.xlf | 2 +- .../gen/Common/Resources/xlf/Strings.fr.xlf | 2 +- .../gen/Common/Resources/xlf/Strings.it.xlf | 2 +- .../gen/Common/Resources/xlf/Strings.ja.xlf | 2 +- .../gen/Common/Resources/xlf/Strings.ko.xlf | 2 +- .../gen/Common/Resources/xlf/Strings.pl.xlf | 2 +- .../gen/Common/Resources/xlf/Strings.pt-BR.xlf | 2 +- .../gen/Common/Resources/xlf/Strings.ru.xlf | 2 +- .../gen/Common/Resources/xlf/Strings.tr.xlf | 2 +- .../gen/Common/Resources/xlf/Strings.zh-Hans.xlf | 2 +- .../gen/Common/Resources/xlf/Strings.zh-Hant.xlf | 2 +- .../System.Text.Json/gen/Resources/xlf/Strings.pl.xlf | 2 +- 29 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf index 29bfa35727e806..8c264bc592c9c0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf @@ -29,12 +29,12 @@ The project's language version has to be at least 'C# 12'. - The project's language version has to be at least 'C# 12'. + Jazyková verze projektu musí být alespoň C# 12 Language version is required to be at least C# 12 - Language version is required to be at least C# 12 + Verze jazyka musí být alespoň C# 12 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf index fc071eba18289d..37100d25efae20 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf @@ -29,12 +29,12 @@ The project's language version has to be at least 'C# 12'. - The project's language version has to be at least 'C# 12'. + Die Sprachversion des Projekts muss mindestens "C# 12" sein. Language version is required to be at least C# 12 - Language version is required to be at least C# 12 + Die Sprachversion muss mindestens C# 12 sein. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf index 772e016401aaf5..00bf90592cc311 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf @@ -29,12 +29,12 @@ The project's language version has to be at least 'C# 12'. - The project's language version has to be at least 'C# 12'. + La versión del lenguaje del proyecto debe ser al menos "C# 12". Language version is required to be at least C# 12 - Language version is required to be at least C# 12 + La versión del lenguaje debe ser al menos C# 12 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf index 29b944202c4577..847bc6155aaaee 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf @@ -29,12 +29,12 @@ The project's language version has to be at least 'C# 12'. - The project's language version has to be at least 'C# 12'. + La version de langage du projet doit être au moins 'C# 12'. Language version is required to be at least C# 12 - Language version is required to be at least C# 12 + La version du langage doit être au moins C# 12. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf index 2f6f0a32d918d8..9ee871268cff5a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf @@ -29,12 +29,12 @@ The project's language version has to be at least 'C# 12'. - The project's language version has to be at least 'C# 12'. + La versione del linguaggio del progetto deve essere almeno 'C# 12'. Language version is required to be at least C# 12 - Language version is required to be at least C# 12 + La versione del linguaggio deve essere almeno C# 12 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf index 56e8f33a179316..b7d5becee73ca2 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf @@ -29,12 +29,12 @@ The project's language version has to be at least 'C# 12'. - The project's language version has to be at least 'C# 12'. + プロジェクトの言語バージョンは少なくとも 'C# 12' である必要があります。 Language version is required to be at least C# 12 - Language version is required to be at least C# 12 + 言語バージョンは少なくとも C# 12 である必要があります diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf index fee49ec4680490..4c94c55903310e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf @@ -29,12 +29,12 @@ The project's language version has to be at least 'C# 12'. - The project's language version has to be at least 'C# 12'. + 프로젝트의 언어 버전은 'C# 12' 이상이어야 합니다. Language version is required to be at least C# 12 - Language version is required to be at least C# 12 + 언어 버전은 C# 12 이상이어야 합니다. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf index 8ea73703ba5058..808afa9723f55a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf @@ -29,12 +29,12 @@ The project's language version has to be at least 'C# 12'. - The project's language version has to be at least 'C# 12'. + Wersja językowa projektu musi mieć wartość co najmniej „C# 12”. Language version is required to be at least C# 12 - Language version is required to be at least C# 12 + Wymagana jest wersja językowa o wartości co najmniej C# 12 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf index 9486601e2438cf..9f723e7e6af48b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf @@ -29,12 +29,12 @@ The project's language version has to be at least 'C# 12'. - The project's language version has to be at least 'C# 12'. + A versão da linguagem do projeto deve ser no mínimo 'C# 12'. Language version is required to be at least C# 12 - Language version is required to be at least C# 12 + A versão do idioma deve ser pelo menos C# 12 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf index bbf81d0d807838..cc2f61c6e9d514 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf @@ -29,12 +29,12 @@ The project's language version has to be at least 'C# 12'. - The project's language version has to be at least 'C# 12'. + Версия языка проекта должна быть не ниже "C# 12". Language version is required to be at least C# 12 - Language version is required to be at least C# 12 + Версия языка должна быть не ниже C# 12 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf index 1f2c2c6e9617e5..06aaaded5cf2c1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf @@ -29,12 +29,12 @@ The project's language version has to be at least 'C# 12'. - The project's language version has to be at least 'C# 12'. + Projenin dil sürümü en az 'C# 12' olmalıdır. Language version is required to be at least C# 12 - Language version is required to be at least C# 12 + Dil sürümünün en az C# 12 olması gerekir diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf index ffc49d0c8b8b06..ef3affe4e22bcc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -29,12 +29,12 @@ The project's language version has to be at least 'C# 12'. - The project's language version has to be at least 'C# 12'. + 项目的语言版本必须至少为 "C# 12"。 Language version is required to be at least C# 12 - Language version is required to be at least C# 12 + 语言版本必须至少为 C# 12 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf index 24a5268fc5f261..39dd659d8890dd 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -29,12 +29,12 @@ The project's language version has to be at least 'C# 12'. - The project's language version has to be at least 'C# 12'. + 專案的語言版本必須至少為 'C# 12'。 Language version is required to be at least C# 12 - Language version is required to be at least C# 12 + 語言版本要求至少為 C#12 diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pl.xlf index b7c27d6dc5a24b..a40b72d24ffcea 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pl.xlf @@ -69,7 +69,7 @@ The Logging source generator is not available in C# {0}. Please use language version {1} or greater. - The Logging source generator is not available in C# {0}. Please use language version {1} or greater. + Generator źródła rejestrowania nie jest dostępny w języku C# {0}. Użyj wersji językowej {1} lub nowszej. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf index 5949f6a902609b..190ca17b561792 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf @@ -124,7 +124,7 @@ The options validation source generator is not available in C# {0}. Please use language version {1} or greater. - The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + Generator źródła sprawdzania poprawności opcji nie jest dostępny w języku C# {0}. Użyj wersji językowej {1} lub nowszej. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf index 829de99735954b..7f3261b6a59368 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf @@ -1311,4 +1311,4 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf index 1f959d763c7ba7..4661bf889dc59a 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf @@ -1311,4 +1311,4 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf index fab077ea6bac23..7fdaa530d64fb8 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf @@ -1311,4 +1311,4 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf index 3f8638ef4ee7f8..35a71ca7310139 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf @@ -934,7 +934,7 @@ The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - L’attribut '[Out]' est uniquement pris en charge sur les paramètres de tableau. Envisagez d’utiliser des mots clés 'out' ou 'ref' pour rendre le paramètre mutable. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf index d6ed0fd8fc3b35..6fae51e9aef95a 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf @@ -934,7 +934,7 @@ The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - L'attributo '[Out]' è supportato solo nei parametri di matrice. Provare a usare le parole chiave 'out' o 'ref' per rendere modificabile il parametro. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf index 0963a7a2aa5267..006bd7cf02b7f6 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf @@ -1312,4 +1312,4 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf index 1cbdc68ed114d5..d40a4bf4760926 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf @@ -1311,4 +1311,4 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf index 05433b6de67407..679e91c677c37f 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf @@ -934,7 +934,7 @@ The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - Atrybut „[Out]” jest obsługiwany tylko w przypadku parametrów tablicy. Rozważ użycie słów kluczowych „out” lub „ref”, aby umożliwić modyfikowanie parametru. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf index c608ba0d78a585..cd845a3992cc12 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf @@ -1311,4 +1311,4 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf index bee98c1d72e1f8..115cf30ac4c61c 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf @@ -934,7 +934,7 @@ The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - Атрибут "[Out]" поддерживается только для параметров массива. Рассмотрите возможность использования ключевых слов "out" или "ref", чтобы сделать параметр изменяемым. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf index ba0b8468207011..6bcbaf87980d36 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf @@ -934,7 +934,7 @@ The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - '[Out]' özniteliği yalnızca dizi parametrelerinde desteklenir. Parametreyi değiştirilebilir yapmak için 'out' veya 'ref' anahtar sözcükleri kullanmayı düşünün. + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf index fd82f97082b4d8..240718627dd8e8 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf @@ -1311,4 +1311,4 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf index a1998a248b2fdf..c6103229ee5c4f 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf @@ -934,7 +934,7 @@ The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - 只有陣列參數才支援 '[Out]' 屬性。請考慮使用 'out' 或 'ref' 關鍵字將參數設為可變。 + The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. diff --git a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pl.xlf index 3ac0444fdee2a2..d8e7a990013fac 100644 --- a/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/System.Text.Json/gen/Resources/xlf/Strings.pl.xlf @@ -114,7 +114,7 @@ The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. - The System.Text.Json source generator is not available in C# {0}. Please use language version {1} or greater. + Generator źródła System.Text.Json nie jest dostępny w języku C# {0}. Użyj wersji językowej {1} lub nowszej. From c09812fda3500d92fee034c44bd5b1a1f7fd5fd2 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 31 Aug 2023 01:20:42 -0700 Subject: [PATCH 116/783] Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2256435 (#91360) --- .../gen/Common/Resources/xlf/Strings.fr.xlf | 16 ++++++++-------- .../gen/Common/Resources/xlf/Strings.ko.xlf | 16 ++++++++-------- .../gen/Common/Resources/xlf/Strings.pl.xlf | 16 ++++++++-------- .../gen/Common/Resources/xlf/Strings.pt-BR.xlf | 16 ++++++++-------- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf index 35a71ca7310139..50bffbbb83c75f 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf @@ -149,12 +149,12 @@ The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} - The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + L'utilisation de « GeneratedComInterfaceAttribute » ne suit pas les recommandations. {0} The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. - The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + L'utilisation de « GeneratedComInterfaceAttribute » ne suit pas les recommandations. @@ -459,7 +459,7 @@ The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. - The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + L'attribut '[In]' n'est pris en charge que sur les paramètres de tableau. Les paramètres par valeur sont considérés comme en lecture seule par défaut. @@ -484,7 +484,7 @@ The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. - The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + Les attributs '[In]' et '[Out]' ne sont pris en charge que sur les paramètres de tableau. Pensez à utiliser le mot-clé 'ref' pour rendre le paramètre mutable. @@ -724,12 +724,12 @@ The usage of 'LibraryImportAttribute' does not follow recommendations. {0} - The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + L'utilisation de « LibraryImport Attribute » ne suit pas les recommandations. {0} The usage of 'LibraryImportAttribute' does not follow recommendations. - The usage of 'LibraryImportAttribute' does not follow recommendations. + L'utilisation de « LibraryImport Attribute » ne suit pas les recommandations. @@ -934,7 +934,7 @@ The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + L'attribut '[Out]' n'est pris en charge que sur les paramètres de tableau. Pensez à utiliser les mots-clés « out » ou « ref » pour rendre le paramètre mutable. @@ -949,7 +949,7 @@ It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. - It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + Il est recommandé d'utiliser les attributs explicites '[In]' et '[Out]' sur les paramètres du tableau. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf index d40a4bf4760926..d3d130445bab26 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf @@ -149,12 +149,12 @@ The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} - The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + 'GeneratedComInterfaceAttribute' 사용법이 권장 사항을 따르지 않습니다. {0} The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. - The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + 'GeneratedComInterfaceAttribute' 사용법이 권장 사항을 따르지 않습니다. @@ -459,7 +459,7 @@ The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. - The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + '[In]' 특성은 배열 매개 변수에서만 지원됩니다. 값별 매개 변수는 기본적으로 읽기 전용으로 간주됩니다. @@ -484,7 +484,7 @@ The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. - The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + '[In]' 및 '[Out]' 특성은 배열 매개 변수에서만 지원됩니다. 매개 변수를 변경 가능하게 만들려면 'ref' 키워드를 사용하는 것이 좋습니다. @@ -724,12 +724,12 @@ The usage of 'LibraryImportAttribute' does not follow recommendations. {0} - The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + 'LibraryImportAttribute' 사용법이 권장 사항을 따르지 않습니다. {0} The usage of 'LibraryImportAttribute' does not follow recommendations. - The usage of 'LibraryImportAttribute' does not follow recommendations. + 'LibraryImportAttribute' 사용법이 권장 사항을 따르지 않습니다. @@ -934,7 +934,7 @@ The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + '[Out]' 특성은 배열 매개 변수에서만 지원됩니다. 매개 변수를 변경할 수 있도록 'out' 또는 'ref' 키워드를 사용하는 것이 좋습니다. @@ -949,7 +949,7 @@ It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. - It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + 배열 매개 변수에는 명시적인 '[In]' 및 '[Out]' 특성을 사용하는 것이 좋습니다. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf index 679e91c677c37f..c5dbc075109417 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf @@ -149,12 +149,12 @@ The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} - The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + Użycie atrybutu „GeneratedComInterfaceAttribute” nie jest zgodne z zaleceniami. {0} The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. - The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + Użycie atrybutu „GeneratedComInterfaceAttribute” nie jest zgodne z zaleceniami. @@ -459,7 +459,7 @@ The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. - The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + Atrybut „[In]” jest obsługiwany tylko w przypadku parametrów tablicy. Parametry według wartości są domyślnie uznawane za tylko do odczytu. @@ -484,7 +484,7 @@ The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. - The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + Atrybuty „[In]” i „[Out]” są obsługiwane tylko w przypadku parametrów tablicy. Rozważ użycie słowa kluczowego „ref”, aby umożliwić modyfikowanie parametru. @@ -724,12 +724,12 @@ The usage of 'LibraryImportAttribute' does not follow recommendations. {0} - The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + Użycie atrybutu „LibraryImportAttribute” nie jest zgodne z zaleceniami. {0} The usage of 'LibraryImportAttribute' does not follow recommendations. - The usage of 'LibraryImportAttribute' does not follow recommendations. + Użycie atrybutu „LibraryImportAttribute” nie jest zgodne z zaleceniami. @@ -934,7 +934,7 @@ The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + Atrybut „[Out]” jest obsługiwany tylko w przypadku parametrów tablicy. Rozważ użycie słów kluczowych „out” lub „ref”, aby umożliwić modyfikowanie parametru. @@ -949,7 +949,7 @@ It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. - It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + Zaleca się używanie jawnych atrybutów „[In]” i „[Out]” w parametrach tablicy. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf index cd845a3992cc12..80bc83669b4547 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf @@ -149,12 +149,12 @@ The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} - The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. {0} + O uso de 'GeneratedComInterfaceAttribute' não segue as recomendações. {0} The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. - The usage of 'GeneratedComInterfaceAttribute' does not follow recommendations. + O uso de 'GeneratedComInterfaceAttribute' não segue as recomendações. @@ -459,7 +459,7 @@ The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. - The '[In]' attribute is only supported on array parameters. By-value parameters are considered read-only by default. + O '[In]' atributo só tem suporte nos parâmetros de matriz. Parâmetros por valor são considerados somente leitura por padrão. @@ -484,7 +484,7 @@ The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. - The '[In]' and '[Out]' attributes are only supported on array parameters. Consider using the 'ref' keyword to make the parameter mutable. + Os atributos '[In]' e '[Out]' só têm suporte nos parâmetros de matriz. Considere usar a palavra-chave 'ref' para tornar o parâmetro mutável. @@ -724,12 +724,12 @@ The usage of 'LibraryImportAttribute' does not follow recommendations. {0} - The usage of 'LibraryImportAttribute' does not follow recommendations. {0} + O uso de 'LibraryImportAttribute' não segue as recomendações. {0} The usage of 'LibraryImportAttribute' does not follow recommendations. - The usage of 'LibraryImportAttribute' does not follow recommendations. + O uso de 'LibraryImportAttribute' não segue as recomendações. @@ -934,7 +934,7 @@ The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. - The '[Out]' attribute is only supported on array parameters. Consider using 'out' or 'ref' keywords to make the parameter mutable. + O atributo "[Out]" só tem suporte nos parâmetros de matriz. Considere usar palavras-chave "out" ou "ref" para tornar o parâmetro mutável. @@ -949,7 +949,7 @@ It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. - It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters. + É recomendável usar atributos '[In]' e '[Out]' explícitos nos parâmetros de matriz. From 903c3a58d47b7de5dba3e9058ea7f0011f4285af Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 31 Aug 2023 08:42:42 -0700 Subject: [PATCH 117/783] [release/8.0] Update dependencies from dotnet/roslyn (#91239) * Update dependencies from https://github.com/dotnet/roslyn build 20230828.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-2.23428.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230828.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-2.23428.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230828.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-2.23428.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230828.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-2.23428.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230828.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23428.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230828.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23428.5 * Update dependencies from https://github.com/dotnet/roslyn build 20230828.7 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23428.7 * Update dependencies from https://github.com/dotnet/roslyn build 20230829.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23429.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230829.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23429.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230829.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23429.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230829.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23429.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230829.7 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-2.23429.7 * Update dependencies from https://github.com/dotnet/roslyn build 20230829.9 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23429.9 * Update dependencies from https://github.com/dotnet/roslyn build 20230829.10 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23429.10 * Update dependencies from https://github.com/dotnet/roslyn build 20230829.12 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23429.12 * Update dependencies from https://github.com/dotnet/roslyn build 20230829.13 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23429.13 * Update dependencies from https://github.com/dotnet/roslyn build 20230829.14 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23429.14 * Update dependencies from https://github.com/dotnet/roslyn build 20230830.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23430.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230830.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-2.23430.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230830.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23430.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230830.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23430.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230830.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23430.5 * Update dependencies from https://github.com/dotnet/roslyn build 20230830.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-2.23426.1 -> To Version 4.8.0-3.23430.6 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e2026ba5907ba6..61b41ba5e21c1b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - 34268d1bb9370c7b01c742303a895a99daf10d6a + 0a5289acaadde17d768b8f69dbc35aeec74cc4f8 - + https://github.com/dotnet/roslyn - 34268d1bb9370c7b01c742303a895a99daf10d6a + 0a5289acaadde17d768b8f69dbc35aeec74cc4f8 - + https://github.com/dotnet/roslyn - 34268d1bb9370c7b01c742303a895a99daf10d6a + 0a5289acaadde17d768b8f69dbc35aeec74cc4f8 https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index 8234d10cc507cc..4720bab4b03e0e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -42,9 +42,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-2.23426.1 - 4.8.0-2.23426.1 - 4.8.0-2.23426.1 + 4.8.0-3.23430.6 + 4.8.0-3.23430.6 + 4.8.0-3.23430.6 diff --git a/eng/Versions.props b/eng/Versions.props index 4720bab4b03e0e..93153b418cab7c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -156,12 +156,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23429.4 - 1.0.0-prerelease.23429.4 - 1.0.0-prerelease.23429.4 - 1.0.0-prerelease.23429.4 - 1.0.0-prerelease.23429.4 - 1.0.0-prerelease.23429.4 + 1.0.0-prerelease.23430.6 + 1.0.0-prerelease.23430.6 + 1.0.0-prerelease.23430.6 + 1.0.0-prerelease.23430.6 + 1.0.0-prerelease.23430.6 + 1.0.0-prerelease.23430.6 16.11.27-beta1.23180.1 2.0.0-beta4.23307.1 From 35f043f414dbd234978f0eb694b47dfb42dd2031 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Thu, 31 Aug 2023 15:25:40 -0700 Subject: [PATCH 120/783] Update binder gen emitted-interceptor nullability to match framework impl (#91180) (#91359) --- .../ConfigurationBindingGenerator.Emitter.cs | 12 +- .../Helpers/Emitter/ConfigurationBinder.cs | 15 +- .../gen/Helpers/Emitter/CoreBindingHelpers.cs | 45 ++--- .../gen/Helpers/Emitter/Helpers.cs | 12 +- .../OptionsBuilderConfigurationExtensions.cs | 19 +- ...onfigurationServiceCollectionExtensions.cs | 16 +- .../gen/Helpers/MethodsToGen.cs | 14 +- .../gen/Helpers/Parser/ConfigurationBinder.cs | 8 +- .../OptionsBuilderConfigurationExtensions.cs | 8 +- ...onfigurationServiceCollectionExtensions.cs | 7 +- .../gen/Model/ObjectSpec.cs | 4 +- .../src/ConfigurationBinder.cs | 182 +++++++++--------- .../tests/Common/ConfigurationBinderTests.cs | 83 +++++++- .../Baselines/Collections.generated.txt | 56 +++--- .../ConfigurationBinder/Bind.generated.txt | 56 +++--- .../Bind_Instance.generated.txt | 40 ++-- .../Bind_Instance_BinderOptions.generated.txt | 40 ++-- .../Bind_Key_Instance.generated.txt | 40 ++-- .../ConfigurationBinder/Get.generated.txt | 50 ++--- .../ConfigurationBinder/Get_T.generated.txt | 40 ++-- .../Get_T_BinderOptions.generated.txt | 40 ++-- .../Get_TypeOf.generated.txt | 10 +- .../Get_TypeOf_BinderOptions.generated.txt | 10 +- .../BindConfiguration.generated.txt | 44 ++--- .../OptionsBuilder/Bind_T.generated.txt | 45 ++--- .../Bind_T_BinderOptions.generated.txt | 41 ++-- .../Baselines/Primitives.generated.txt | 66 +++---- .../Configure_T.generated.txt | 61 +++--- .../Configure_T_BinderOptions.generated.txt | 61 +++--- .../Configure_T_name.generated.txt | 61 +++--- ...nfigure_T_name_BinderOptions.generated.txt | 57 +++--- .../SourceGenerationTests/GeneratorTests.cs | 6 +- .../Common/ConfigurationExtensionsTests.cs | 55 ++++++ ...s.ConfigurationExtensions.UnitTests.csproj | 3 +- 34 files changed, 699 insertions(+), 608 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs index 756e10bc26b8d5..cb67c7ee1f5fb9 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs @@ -96,19 +96,19 @@ private void EmitBindCoreCall( EmitBindCoreCall(memberAccessExpr, initKind); } - void EmitBindCoreCall(string objExpression, InitializationKind initKind) + void EmitBindCoreCall(string instanceExpr, InitializationKind initKind) { - string bindCoreCall = $@"{nameof(MethodsToGen_CoreBindingHelper.BindCore)}({configArgExpr}, ref {objExpression}, {Identifier.binderOptions});"; - EmitObjectInit(objExpression, initKind); + string bindCoreCall = $@"{nameof(MethodsToGen_CoreBindingHelper.BindCore)}({configArgExpr}, ref {instanceExpr}, {Identifier.binderOptions});"; + EmitObjectInit(instanceExpr, initKind); _writer.WriteLine(bindCoreCall); - writeOnSuccess?.Invoke(objExpression); + writeOnSuccess?.Invoke(instanceExpr); } - void EmitObjectInit(string objExpression, InitializationKind initKind) + void EmitObjectInit(string instanceExpr, InitializationKind initKind) { if (initKind is not InitializationKind.None) { - this.EmitObjectInit(type, objExpression, initKind, configArgExpr); + this.EmitObjectInit(type, instanceExpr, initKind, configArgExpr); } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs index 64064887c7c70b..c7ead12d65589d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using SourceGenerators; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { @@ -101,13 +100,13 @@ private void EmitBindMethods_ConfigurationBinder() return; } - string objParamExpr = $"object? {Identifier.obj}"; + string instanceParamExpr = $"object? {Identifier.instance}"; if (ShouldEmitMethods(MethodsToGen_ConfigurationBinder.Bind_instance)) { EmitMethods( MethodsToGen_ConfigurationBinder.Bind_instance, - additionalParams: objParamExpr, + additionalParams: instanceParamExpr, configExpression: Identifier.configuration, configureOptions: false); } @@ -116,7 +115,7 @@ private void EmitBindMethods_ConfigurationBinder() { EmitMethods( MethodsToGen_ConfigurationBinder.Bind_instance_BinderOptions, - additionalParams: $"{objParamExpr}, {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions}", + additionalParams: $"{instanceParamExpr}, {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions}", configExpression: Identifier.configuration, configureOptions: true); } @@ -125,7 +124,7 @@ private void EmitBindMethods_ConfigurationBinder() { EmitMethods( MethodsToGen_ConfigurationBinder.Bind_key_instance, - additionalParams: $"string {Identifier.key}, {objParamExpr}", + additionalParams: $"string {Identifier.key}, {instanceParamExpr}", configExpression: $"{Expression.configurationGetSection}({Identifier.key})", configureOptions: false); } @@ -141,17 +140,17 @@ void EmitMethods(MethodsToGen_ConfigurationBinder method, string additionalParam EmitInterceptsLocationAnnotations(interceptorInfoList); EmitStartBlock($"public static void {Identifier.Bind}_{type.DisplayString.ToIdentifierSubstring()}(this {Identifier.IConfiguration} {Identifier.configuration}, {additionalParams})"); - if (!EmitInitException(type) && type.NeedsMemberBinding) + if (type.NeedsMemberBinding) { string binderOptionsArg = configureOptions ? $"{Identifier.GetBinderOptions}({Identifier.configureOptions})" : $"{Identifier.binderOptions}: null"; EmitCheckForNullArgument_WithBlankLine(Identifier.configuration); if (!type.IsValueType) { - EmitCheckForNullArgument_WithBlankLine(Identifier.obj); + EmitCheckForNullArgument_WithBlankLine(Identifier.instance, voidReturn: true); } _writer.WriteLine($$""" - var {{Identifier.typedObj}} = ({{type.EffectiveType.DisplayString}}){{Identifier.obj}}; + var {{Identifier.typedObj}} = ({{type.EffectiveType.DisplayString}}){{Identifier.instance}}; {{nameof(MethodsToGen_CoreBindingHelper.BindCore)}}({{configExpression}}, ref {{Identifier.typedObj}}, {{binderOptionsArg}}); """); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs index f30408fad596dd..bb2bd7ac61d15a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs @@ -101,8 +101,8 @@ private void EmitGetCoreMethod() } else if (!EmitInitException(effectiveType)) { - EmitBindCoreCall(effectiveType, Identifier.obj, Identifier.configuration, InitializationKind.Declaration); - _writer.WriteLine($"return {Identifier.obj};"); + EmitBindCoreCall(effectiveType, Identifier.instance, Identifier.configuration, InitializationKind.Declaration); + _writer.WriteLine($"return {Identifier.instance};"); } EmitEndBlock(); @@ -168,9 +168,8 @@ private void EmitBindCoreMainMethod() } EmitBlankLineIfRequired(); - EmitStartBlock($"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCoreMain)}({Identifier.IConfiguration} {Identifier.configuration}, object {Identifier.obj}, Type {Identifier.type}, {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions})"); - EmitCheckForNullArgument_WithBlankLine(Identifier.configuration); - EmitCheckForNullArgument_WithBlankLine(Identifier.obj); + EmitStartBlock($"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCoreMain)}({Identifier.IConfiguration} {Identifier.configuration}, object {Identifier.instance}, Type {Identifier.type}, {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions})"); + EmitCheckForNullArgument_WithBlankLine(Identifier.instance, voidReturn: true); EmitIConfigurationHasValueOrChildrenCheck(voidReturn: true); _writer.WriteLine($"{Identifier.BinderOptions}? {Identifier.binderOptions} = {Identifier.GetBinderOptions}({Identifier.configureOptions});"); _writer.WriteLine(); @@ -184,7 +183,7 @@ private void EmitBindCoreMainMethod() EmitStartBlock($"{conditionKindExpr} ({Identifier.type} == typeof({type.DisplayString}))"); if (!EmitInitException(effectiveType)) { - _writer.WriteLine($"var {Identifier.temp} = ({effectiveType.DisplayString}){Identifier.obj};"); + _writer.WriteLine($"var {Identifier.temp} = ({effectiveType.DisplayString}){Identifier.instance};"); EmitBindCoreCall(type, Identifier.temp, Identifier.configuration, InitializationKind.None); _writer.WriteLine($"return;"); } @@ -213,9 +212,7 @@ private void EmitBindCoreMethods() private void EmitBindCoreMethod(TypeSpec type) { - Debug.Assert(type.CanInitialize); - - string objParameterExpression = $"ref {type.DisplayString} {Identifier.obj}"; + string objParameterExpression = $"ref {type.DisplayString} {Identifier.instance}"; EmitStartBlock(@$"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCore)}({Identifier.IConfiguration} {Identifier.configuration}, {objParameterExpression}, {Identifier.BinderOptions}? {Identifier.binderOptions})"); TypeSpec effectiveType = type.EffectiveType; @@ -618,15 +615,15 @@ private void EmitPopulationImplForArray(EnumerableSpec type) // Resize array and add binded elements. _writer.WriteLine($$""" - {{Identifier.Int32}} {{Identifier.originalCount}} = {{Identifier.obj}}.{{Identifier.Length}}; - {{Identifier.Array}}.{{Identifier.Resize}}(ref {{Identifier.obj}}, {{Identifier.originalCount}} + {{tempIdentifier}}.{{Identifier.Count}}); - {{tempIdentifier}}.{{Identifier.CopyTo}}({{Identifier.obj}}, {{Identifier.originalCount}}); + {{Identifier.Int32}} {{Identifier.originalCount}} = {{Identifier.instance}}.{{Identifier.Length}}; + {{Identifier.Array}}.{{Identifier.Resize}}(ref {{Identifier.instance}}, {{Identifier.originalCount}} + {{tempIdentifier}}.{{Identifier.Count}}); + {{tempIdentifier}}.{{Identifier.CopyTo}}({{Identifier.instance}}, {{Identifier.originalCount}}); """); } private void EmitPopulationImplForEnumerableWithAdd(EnumerableSpec type) { - EmitCollectionCastIfRequired(type, out string objIdentifier); + EmitCollectionCastIfRequired(type, out string instanceIdentifier); Emit_Foreach_Section_In_ConfigChildren_StartBlock(); @@ -638,14 +635,14 @@ private void EmitPopulationImplForEnumerableWithAdd(EnumerableSpec type) stringParsableType, Expression.sectionValue, Expression.sectionPath, - (parsedValueExpr) => _writer.WriteLine($"{objIdentifier}.{Identifier.Add}({parsedValueExpr});"), + (parsedValueExpr) => _writer.WriteLine($"{instanceIdentifier}.{Identifier.Add}({parsedValueExpr});"), checkForNullSectionValue: true, useIncrementalStringValueIdentifier: false); } else { EmitBindCoreCall(elementType, Identifier.value, Identifier.section, InitializationKind.Declaration); - _writer.WriteLine($"{objIdentifier}.{Identifier.Add}({Identifier.value});"); + _writer.WriteLine($"{instanceIdentifier}.{Identifier.Add}({Identifier.value});"); } EmitEndBlock(); @@ -653,7 +650,7 @@ private void EmitPopulationImplForEnumerableWithAdd(EnumerableSpec type) private void EmitBindCoreImplForDictionary(DictionarySpec type) { - EmitCollectionCastIfRequired(type, out string objIdentifier); + EmitCollectionCastIfRequired(type, out string instanceIdentifier); Emit_Foreach_Section_In_ConfigChildren_StartBlock(); @@ -677,7 +674,7 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr) stringParsableElementType, Expression.sectionValue, Expression.sectionPath, - writeOnSuccess: parsedValueExpr => _writer.WriteLine($"{objIdentifier}[{parsedKeyExpr}] = {parsedValueExpr};"), + writeOnSuccess: parsedValueExpr => _writer.WriteLine($"{instanceIdentifier}[{parsedKeyExpr}] = {parsedValueExpr};"), checkForNullSectionValue: true, useIncrementalStringValueIdentifier: false); } @@ -696,7 +693,7 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr) string expressionForElementIsNotNull = $"{Identifier.element} is not null"; string elementTypeDisplayString = elementType.DisplayString + (elementType.IsValueType ? string.Empty : "?"); - string expressionForElementExists = $"{objIdentifier}.{Identifier.TryGetValue}({parsedKeyExpr}, out {elementTypeDisplayString} {Identifier.element})"; + string expressionForElementExists = $"{instanceIdentifier}.{Identifier.TryGetValue}({parsedKeyExpr}, out {elementTypeDisplayString} {Identifier.element})"; string conditionToUseExistingElement = expressionForElementExists; // If key already exists, bind to existing element instance if not null (for ref types). @@ -727,7 +724,7 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr) } EmitBindCoreCall(elementType, Identifier.element, Identifier.section, InitializationKind.None); - _writer.WriteLine($"{objIdentifier}[{parsedKeyExpr}] = {Identifier.element};"); + _writer.WriteLine($"{instanceIdentifier}[{parsedKeyExpr}] = {Identifier.element};"); } } @@ -747,7 +744,7 @@ private void EmitBindCoreImplForObject(ObjectSpec type) bool noSetter_And_IsReadonly = !property.CanSet && property.Type is CollectionSpec { InitializationStrategy: InitializationStrategy.ParameterizedConstructor }; if (property.ShouldBind() && !noSetter_And_IsReadonly) { - string containingTypeRef = property.IsStatic ? type.DisplayString : Identifier.obj; + string containingTypeRef = property.IsStatic ? type.DisplayString : Identifier.instance; EmitBindImplForMember( property, memberAccessExpr: $"{containingTypeRef}.{property.Name}", @@ -883,14 +880,14 @@ private void EmitBindCoreCallForMember( writeOnSuccess); } - private void EmitCollectionCastIfRequired(CollectionSpec type, out string objIdentifier) + private void EmitCollectionCastIfRequired(CollectionSpec type, out string instanceIdentifier) { - objIdentifier = Identifier.obj; + instanceIdentifier = Identifier.instance; if (type.PopulationStrategy is CollectionPopulationStrategy.Cast_Then_Add) { - objIdentifier = Identifier.temp; + instanceIdentifier = Identifier.temp; _writer.WriteLine($$""" - if ({{Identifier.obj}} is not {{type.PopulationCastType!.DisplayString}} {{objIdentifier}}) + if ({{Identifier.instance}} is not {{type.PopulationCastType!.DisplayString}} {{instanceIdentifier}}) { return; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs index bad56b7ce3275a..909272c7678447 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs @@ -45,6 +45,8 @@ private static class TypeDisplayString private static class Identifier { public const string binderOptions = nameof(binderOptions); + public const string config = nameof(config); + public const string configureBinder = nameof(configureBinder); public const string configureOptions = nameof(configureOptions); public const string configuration = nameof(configuration); public const string configSectionPath = nameof(configSectionPath); @@ -55,7 +57,7 @@ private static class Identifier public const string getPath = nameof(getPath); public const string key = nameof(key); public const string name = nameof(name); - public const string obj = nameof(obj); + public const string instance = nameof(instance); public const string optionsBuilder = nameof(optionsBuilder); public const string originalCount = nameof(originalCount); public const string section = nameof(section); @@ -211,12 +213,16 @@ private void EmitBlankLineIfRequired() _emitBlankLineBeforeNextStatement = true; } - private void EmitCheckForNullArgument_WithBlankLine(string paramName) + private void EmitCheckForNullArgument_WithBlankLine(string paramName, bool voidReturn = false) { + string returnExpr = voidReturn + ? "return" + : $"throw new ArgumentNullException(nameof({paramName}))"; + _writer.WriteLine($$""" if ({{paramName}} is null) { - throw new ArgumentNullException(nameof({{paramName}})); + {{returnExpr}}; } """); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs index d49198196fd491..7fd5d695eaf45a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs @@ -30,25 +30,25 @@ private void EmitBindMethods_Extensions_OptionsBuilder() } const string documentation = @"/// Registers a configuration instance which will bind against."; - const string paramList = $"{Identifier.IConfiguration} {Identifier.configuration}"; + const string paramList = $"{Identifier.IConfiguration} {Identifier.config}"; if (ShouldEmitMethods(MethodsToGen_Extensions_OptionsBuilder.Bind_T)) { EmitMethodStartBlock(MethodsToGen_Extensions_OptionsBuilder.Bind_T, "Bind", paramList, documentation); - _writer.WriteLine($"return Bind({Identifier.optionsBuilder}, {Identifier.configuration}, {Identifier.configureOptions}: null);"); + _writer.WriteLine($"return Bind({Identifier.optionsBuilder}, {Identifier.config}, {Identifier.configureBinder}: null);"); EmitEndBlock(); } EmitMethodStartBlock( MethodsToGen_Extensions_OptionsBuilder.Bind_T_BinderOptions, "Bind", - paramList + $", {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions}", + paramList + $", {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureBinder}", documentation); EmitCheckForNullArgument_WithBlankLine(Identifier.optionsBuilder); _writer.WriteLine($$""" - {{Identifier.Configure}}<{{Identifier.TOptions}}>({{Identifier.optionsBuilder}}.{{Identifier.Services}}, {{Identifier.optionsBuilder}}.Name, {{Identifier.configuration}}, {{Identifier.configureOptions}}); + {{Identifier.Configure}}<{{Identifier.TOptions}}>({{Identifier.optionsBuilder}}.{{Identifier.Services}}, {{Identifier.optionsBuilder}}.Name, {{Identifier.config}}, {{Identifier.configureBinder}}); return {{Identifier.optionsBuilder}}; """); @@ -63,19 +63,18 @@ private void EmitBindConfigurationMethod() } const string documentation = $@"/// Registers the dependency injection container to bind against the obtained from the DI service provider."; - string paramList = $"string {Identifier.configSectionPath}, {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions} = null"; + string paramList = $"string {Identifier.configSectionPath}, {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureBinder} = null"; EmitMethodStartBlock(MethodsToGen_Extensions_OptionsBuilder.BindConfiguration, "BindConfiguration", paramList, documentation); EmitCheckForNullArgument_WithBlankLine(Identifier.optionsBuilder); EmitCheckForNullArgument_WithBlankLine(Identifier.configSectionPath); - EmitStartBlock($"{Identifier.optionsBuilder}.{Identifier.Configure}<{Identifier.IConfiguration}>(({Identifier.obj}, {Identifier.configuration}) =>"); - EmitCheckForNullArgument_WithBlankLine(Identifier.obj); - EmitCheckForNullArgument_WithBlankLine(Identifier.configuration); + EmitStartBlock($"{Identifier.optionsBuilder}.{Identifier.Configure}<{Identifier.IConfiguration}>(({Identifier.instance}, {Identifier.config}) =>"); + EmitCheckForNullArgument_WithBlankLine(Identifier.config); _writer.WriteLine($$""" - {{Identifier.IConfiguration}} {{Identifier.section}} = string.Equals(string.Empty, {{Identifier.configSectionPath}}, StringComparison.OrdinalIgnoreCase) ? {{Identifier.configuration}} : {{Identifier.configuration}}.{{Identifier.GetSection}}({{Identifier.configSectionPath}}); - {{nameof(MethodsToGen_CoreBindingHelper.BindCoreMain)}}({{Identifier.section}}, {{Identifier.obj}}, typeof({{Identifier.TOptions}}), {{Identifier.configureOptions}}); + {{Identifier.IConfiguration}} {{Identifier.section}} = string.Equals(string.Empty, {{Identifier.configSectionPath}}, StringComparison.OrdinalIgnoreCase) ? {{Identifier.config}} : {{Identifier.config}}.{{Identifier.GetSection}}({{Identifier.configSectionPath}}); + {{nameof(MethodsToGen_CoreBindingHelper.BindCoreMain)}}({{Identifier.section}}, {{Identifier.instance}}, typeof({{Identifier.TOptions}}), {{Identifier.configureBinder}}); """); EmitEndBlock(endBraceTrailingSource: ");"); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs index 41eeb8b657342d..7577e0c49de4d0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs @@ -24,12 +24,12 @@ private void EmitBindingExtensions_IServiceCollection() private void EmitConfigureMethods() { const string defaultNameExpr = "string.Empty"; - string configParam = $"{Identifier.IConfiguration} {Identifier.configuration}"; + string configParam = $"{Identifier.IConfiguration} {Identifier.config}"; if (ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Configure_T)) { EmitStartMethod(MethodsToGen_Extensions_ServiceCollection.Configure_T, configParam); - _writer.WriteLine($"return {Identifier.Configure}<{Identifier.TOptions}>({Identifier.services}, {defaultNameExpr}, {Identifier.configuration}, {Identifier.configureOptions}: null);"); + _writer.WriteLine($"return {Identifier.Configure}<{Identifier.TOptions}>({Identifier.services}, {defaultNameExpr}, {Identifier.config}, {Identifier.configureOptions}: null);"); EmitEndBlock(); } @@ -38,7 +38,7 @@ private void EmitConfigureMethods() EmitStartMethod( MethodsToGen_Extensions_ServiceCollection.Configure_T_name, paramList: $"string? {Identifier.name}, " + configParam); - _writer.WriteLine($"return {Identifier.Configure}<{Identifier.TOptions}>({Identifier.services}, {Identifier.name}, {Identifier.configuration}, {Identifier.configureOptions}: null);"); + _writer.WriteLine($"return {Identifier.Configure}<{Identifier.TOptions}>({Identifier.services}, {Identifier.name}, {Identifier.config}, {Identifier.configureOptions}: null);"); EmitEndBlock(); } @@ -47,22 +47,20 @@ private void EmitConfigureMethods() EmitStartMethod( MethodsToGen_Extensions_ServiceCollection.Configure_T_BinderOptions, paramList: configParam + $", {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions}"); - _writer.WriteLine($"return {Identifier.Configure}<{Identifier.TOptions}>({Identifier.services}, {defaultNameExpr}, {Identifier.configuration}, {Identifier.configureOptions});"); + _writer.WriteLine($"return {Identifier.Configure}<{Identifier.TOptions}>({Identifier.services}, {defaultNameExpr}, {Identifier.config}, {Identifier.configureOptions});"); EmitEndBlock(); } // Core Configure method that the other overloads call. // Like the others, it is public API that could be called directly by users. // So, it is always generated whenever a Configure overload is called. - string optionsNamespaceName = "Microsoft.Extensions.Options"; - EmitStartMethod(MethodsToGen_Extensions_ServiceCollection.Configure_T_name_BinderOptions, paramList: $"string? {Identifier.name}, " + configParam + $", {TypeDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions}"); EmitCheckForNullArgument_WithBlankLine(Identifier.services); - EmitCheckForNullArgument_WithBlankLine(Identifier.configuration); + EmitCheckForNullArgument_WithBlankLine(Identifier.config); _writer.WriteLine($$""" OptionsServiceCollectionExtensions.AddOptions({{Identifier.services}}); - {{Identifier.services}}.{{Identifier.AddSingleton}}<{{Identifier.IOptionsChangeTokenSource}}<{{Identifier.TOptions}}>>(new {{Identifier.ConfigurationChangeTokenSource}}<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.configuration}})); - return {{Identifier.services}}.{{Identifier.AddSingleton}}<{{optionsNamespaceName}}.IConfigureOptions<{{Identifier.TOptions}}>>(new {{optionsNamespaceName}}.ConfigureNamedOptions<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.obj}} => {{nameof(MethodsToGen_CoreBindingHelper.BindCoreMain)}}({{Identifier.configuration}}, {{Identifier.obj}}, typeof({{Identifier.TOptions}}), {{Identifier.configureOptions}}))); + {{Identifier.services}}.{{Identifier.AddSingleton}}<{{Identifier.IOptionsChangeTokenSource}}<{{Identifier.TOptions}}>>(new {{Identifier.ConfigurationChangeTokenSource}}<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.config}})); + return {{Identifier.services}}.{{Identifier.AddSingleton}}>(new ConfigureNamedOptions<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.instance}} => {{nameof(MethodsToGen_CoreBindingHelper.BindCoreMain)}}({{Identifier.config}}, {{Identifier.instance}}, typeof({{Identifier.TOptions}}), {{Identifier.configureOptions}}))); """); EmitEndBlock(); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/MethodsToGen.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/MethodsToGen.cs index 2c582b20e8ebd6..6165a3e6d46dcb 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/MethodsToGen.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/MethodsToGen.cs @@ -27,17 +27,17 @@ internal enum MethodsToGen_ConfigurationBinder None = 0x0, /// - /// Bind(IConfiguration, object). + /// Bind(IConfiguration, object?). /// Bind_instance = 0x1, /// - /// Bind(IConfiguration, object, Action). + /// Bind(IConfiguration, object?, Action?). /// Bind_instance_BinderOptions = 0x2, /// - /// Bind(IConfiguration, string, object). + /// Bind(IConfiguration, string, object?). /// Bind_key_instance = 0x4, @@ -47,17 +47,17 @@ internal enum MethodsToGen_ConfigurationBinder Get_T = 0x8, /// - /// Get(IConfiguration, Action). + /// Get(IConfiguration, Action?). /// Get_T_BinderOptions = 0x10, /// - /// Get(IConfiguration, Type). + /// Get(IConfiguration, Type). /// Get_TypeOf = 0x20, /// - /// Get(IConfiguration, Type, Action). + /// Get(IConfiguration, Type, Action?). /// Get_TypeOf_BinderOptions = 0x40, @@ -67,7 +67,7 @@ internal enum MethodsToGen_ConfigurationBinder GetValue_TypeOf_key = 0x80, /// - /// GetValue(IConfiguration, Type, object). + /// GetValue(IConfiguration, Type, object?). /// GetValue_TypeOf_key_defaultValue = 0x100, diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/ConfigurationBinder.cs index e24ce11fe4374c..bce30222493841 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/ConfigurationBinder.cs @@ -72,7 +72,7 @@ private void RegisterBindInvocation(BinderInvocation invocation) return; } - int objectIndex = overload switch + int instanceIndex = overload switch { MethodsToGen_ConfigurationBinder.Bind_instance => 1, MethodsToGen_ConfigurationBinder.Bind_instance_BinderOptions => 1, @@ -80,13 +80,13 @@ private void RegisterBindInvocation(BinderInvocation invocation) _ => throw new InvalidOperationException() }; - IArgumentOperation objectArg = operation.Arguments[objectIndex]; - if (objectArg.Parameter.Type.SpecialType != SpecialType.System_Object) + IArgumentOperation instanceArg = operation.Arguments[instanceIndex]; + if (instanceArg.Parameter.Type.SpecialType != SpecialType.System_Object) { return; } - ITypeSymbol? type = ResolveType(objectArg.Value)?.WithNullableAnnotation(NullableAnnotation.None); + ITypeSymbol? type = ResolveType(instanceArg.Value)?.WithNullableAnnotation(NullableAnnotation.None); if (!IsValidRootConfigType(type)) { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsBuilderConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsBuilderConfigurationExtensions.cs index a62e63c0d90d5e..f65c67a7878b1a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsBuilderConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsBuilderConfigurationExtensions.cs @@ -25,9 +25,11 @@ private void RegisterMethodInvocation_OptionsBuilderExt(BinderInvocation invocat return; } - TypeSpec typeSpec = GetTargetTypeForRootInvocation( - type: targetMethod.TypeArguments[0].WithNullableAnnotation(NullableAnnotation.None), - invocation.Location); + + ITypeSymbol? typeSymbol = targetMethod.TypeArguments[0].WithNullableAnnotation(NullableAnnotation.None); + // This would violate generic type constraint; any such invocation could not have been included in the initial parser. + Debug.Assert(typeSymbol?.IsValueType is not true); + TypeSpec typeSpec = GetTargetTypeForRootInvocation(typeSymbol, invocation.Location); if (typeSpec is null) { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs index c356b29a69efff..b811a8e6ae0eca 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs @@ -69,9 +69,10 @@ @params[1].Type.SpecialType is SpecialType.System_String && return; } - TypeSpec typeSpec = GetTargetTypeForRootInvocation( - type: targetMethod.TypeArguments[0].WithNullableAnnotation(NullableAnnotation.None), - invocation.Location); + ITypeSymbol? typeSymbol = targetMethod.TypeArguments[0].WithNullableAnnotation(NullableAnnotation.None); + // This would violate generic type constraint; any such invocation could not have been included in the initial parser. + Debug.Assert(typeSymbol?.IsValueType is not true); + TypeSpec typeSpec = GetTargetTypeForRootInvocation(typeSymbol, invocation.Location); if (typeSpec is null) { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ObjectSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ObjectSpec.cs index 8cc0ba68b49381..09008dde159ad8 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ObjectSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ObjectSpec.cs @@ -22,8 +22,6 @@ public ObjectSpec(INamedTypeSymbol type) : base(type) { } public List ConstructorParameters { get; } = new(); - public override bool NeedsMemberBinding => CanInitialize && - Properties.Values.Count > 0 && - Properties.Values.Any(p => p.ShouldBind()); + public override bool NeedsMemberBinding => Properties.Values.Any(p => p.ShouldBind()); } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs index 8651e4922e0d72..74365d8084aa3d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs @@ -91,6 +91,7 @@ public static class ConfigurationBinder Action? configureOptions) { ThrowHelper.ThrowIfNull(configuration); + ThrowHelper.ThrowIfNull(type); var options = new BinderOptions(); configureOptions?.Invoke(options); @@ -108,7 +109,10 @@ public static class ConfigurationBinder [RequiresDynamicCode(DynamicCodeWarningMessage)] [RequiresUnreferencedCode(InstanceGetTypeTrimmingWarningMessage)] public static void Bind(this IConfiguration configuration, string key, object? instance) - => configuration.GetSection(key).Bind(instance); + { + ThrowHelper.ThrowIfNull(configuration); + configuration.GetSection(key).Bind(instance); + } /// /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. @@ -200,6 +204,9 @@ public static void Bind(this IConfiguration configuration, object? instance, Act Type type, string key, object? defaultValue) { + ThrowHelper.ThrowIfNull(configuration); + ThrowHelper.ThrowIfNull(type); + IConfigurationSection section = configuration.GetSection(key); string? value = section.Value; if (value != null) @@ -305,125 +312,122 @@ private static void BindInstance( return; } - if (config != null) + if (config.GetChildren().Any()) { - if (config.GetChildren().Any()) + // for arrays and read-only list-like interfaces, we concatenate on to what is already there, if we can + if (type.IsArray || IsImmutableArrayCompatibleInterface(type)) { - // for arrays and read-only list-like interfaces, we concatenate on to what is already there, if we can - if (type.IsArray || IsImmutableArrayCompatibleInterface(type)) + if (!bindingPoint.IsReadOnly) { - if (!bindingPoint.IsReadOnly) - { - bindingPoint.SetValue(BindArray(type, (IEnumerable?)bindingPoint.Value, config, options)); - } - - // for getter-only collection properties that we can't add to, nothing more we can do - return; + bindingPoint.SetValue(BindArray(type, (IEnumerable?)bindingPoint.Value, config, options)); } - // ----------------------------------------------------------------------------------------------------------------------------- - // | bindingPoint | bindingPoint | - // Interface | Value | IsReadOnly | Behavior - // ----------------------------------------------------------------------------------------------------------------------------- - // ISet | not null | true/false | Use the Value instance to populate the configuration - // ISet | null | false | Create HashSet instance to populate the configuration - // ISet | null | true | nothing - // IReadOnlySet | null/not null | false | Create HashSet instance, copy over existing values, and populate the configuration - // IReadOnlySet | null/not null | true | nothing - // ----------------------------------------------------------------------------------------------------------------------------- - if (TypeIsASetInterface(type)) - { - if (!bindingPoint.IsReadOnly || bindingPoint.Value is not null) - { - object? newValue = BindSet(type, (IEnumerable?)bindingPoint.Value, config, options); - if (!bindingPoint.IsReadOnly && newValue != null) - { - bindingPoint.SetValue(newValue); - } - } - - return; - } + // for getter-only collection properties that we can't add to, nothing more we can do + return; + } - // ----------------------------------------------------------------------------------------------------------------------------- - // | bindingPoint | bindingPoint | - // Interface | Value | IsReadOnly | Behavior - // ----------------------------------------------------------------------------------------------------------------------------- - // IDictionary | not null | true/false | Use the Value instance to populate the configuration - // IDictionary | null | false | Create Dictionary instance to populate the configuration - // IDictionary | null | true | nothing - // IReadOnlyDictionary | null/not null | false | Create Dictionary instance, copy over existing values, and populate the configuration - // IReadOnlyDictionary | null/not null | true | nothing - // ----------------------------------------------------------------------------------------------------------------------------- - if (TypeIsADictionaryInterface(type)) + // ----------------------------------------------------------------------------------------------------------------------------- + // | bindingPoint | bindingPoint | + // Interface | Value | IsReadOnly | Behavior + // ----------------------------------------------------------------------------------------------------------------------------- + // ISet | not null | true/false | Use the Value instance to populate the configuration + // ISet | null | false | Create HashSet instance to populate the configuration + // ISet | null | true | nothing + // IReadOnlySet | null/not null | false | Create HashSet instance, copy over existing values, and populate the configuration + // IReadOnlySet | null/not null | true | nothing + // ----------------------------------------------------------------------------------------------------------------------------- + if (TypeIsASetInterface(type)) + { + if (!bindingPoint.IsReadOnly || bindingPoint.Value is not null) { - if (!bindingPoint.IsReadOnly || bindingPoint.Value is not null) + object? newValue = BindSet(type, (IEnumerable?)bindingPoint.Value, config, options); + if (!bindingPoint.IsReadOnly && newValue != null) { - object? newValue = BindDictionaryInterface(bindingPoint.Value, type, config, options); - if (!bindingPoint.IsReadOnly && newValue != null) - { - bindingPoint.SetValue(newValue); - } + bindingPoint.SetValue(newValue); } - - return; } - // If we don't have an instance, try to create one - if (bindingPoint.Value is null) + return; + } + + // ----------------------------------------------------------------------------------------------------------------------------- + // | bindingPoint | bindingPoint | + // Interface | Value | IsReadOnly | Behavior + // ----------------------------------------------------------------------------------------------------------------------------- + // IDictionary | not null | true/false | Use the Value instance to populate the configuration + // IDictionary | null | false | Create Dictionary instance to populate the configuration + // IDictionary | null | true | nothing + // IReadOnlyDictionary | null/not null | false | Create Dictionary instance, copy over existing values, and populate the configuration + // IReadOnlyDictionary | null/not null | true | nothing + // ----------------------------------------------------------------------------------------------------------------------------- + if (TypeIsADictionaryInterface(type)) + { + if (!bindingPoint.IsReadOnly || bindingPoint.Value is not null) { - // if the binding point doesn't let us set a new instance, there's nothing more we can do - if (bindingPoint.IsReadOnly) + object? newValue = BindDictionaryInterface(bindingPoint.Value, type, config, options); + if (!bindingPoint.IsReadOnly && newValue != null) { - return; + bindingPoint.SetValue(newValue); } + } - Type? interfaceGenericType = type.IsInterface && type.IsConstructedGenericType ? type.GetGenericTypeDefinition() : null; + return; + } - if (interfaceGenericType is not null && - (interfaceGenericType == typeof(ICollection<>) || interfaceGenericType == typeof(IList<>))) - { - // For ICollection and IList we bind them to mutable List type. - Type genericType = typeof(List<>).MakeGenericType(type.GenericTypeArguments); - bindingPoint.SetValue(Activator.CreateInstance(genericType)); - } - else - { - bindingPoint.SetValue(CreateInstance(type, config, options)); - } + // If we don't have an instance, try to create one + if (bindingPoint.Value is null) + { + // if the binding point doesn't let us set a new instance, there's nothing more we can do + if (bindingPoint.IsReadOnly) + { + return; } - Debug.Assert(bindingPoint.Value is not null); - - // At this point we know that we have a non-null bindingPoint.Value, we just have to populate the items - // using the IDictionary<> or ICollection<> interfaces, or properties using reflection. - Type? dictionaryInterface = FindOpenGenericInterface(typeof(IDictionary<,>), type); + Type? interfaceGenericType = type.IsInterface && type.IsConstructedGenericType ? type.GetGenericTypeDefinition() : null; - if (dictionaryInterface != null) + if (interfaceGenericType is not null && + (interfaceGenericType == typeof(ICollection<>) || interfaceGenericType == typeof(IList<>))) { - BindDictionary(bindingPoint.Value, dictionaryInterface, config, options); + // For ICollection and IList we bind them to mutable List type. + Type genericType = typeof(List<>).MakeGenericType(type.GenericTypeArguments); + bindingPoint.SetValue(Activator.CreateInstance(genericType)); } else { - Type? collectionInterface = FindOpenGenericInterface(typeof(ICollection<>), type); - if (collectionInterface != null) - { - BindCollection(bindingPoint.Value, collectionInterface, config, options); - } - else - { - BindProperties(bindingPoint.Value, config, options); - } + bindingPoint.SetValue(CreateInstance(type, config, options)); } } + + Debug.Assert(bindingPoint.Value is not null); + + // At this point we know that we have a non-null bindingPoint.Value, we just have to populate the items + // using the IDictionary<> or ICollection<> interfaces, or properties using reflection. + Type? dictionaryInterface = FindOpenGenericInterface(typeof(IDictionary<,>), type); + + if (dictionaryInterface != null) + { + BindDictionary(bindingPoint.Value, dictionaryInterface, config, options); + } else { - if (isParentCollection) + Type? collectionInterface = FindOpenGenericInterface(typeof(ICollection<>), type); + if (collectionInterface != null) + { + BindCollection(bindingPoint.Value, collectionInterface, config, options); + } + else { - bindingPoint.TrySetValue(CreateInstance(type, config, options)); + BindProperties(bindingPoint.Value, config, options); } } } + else + { + if (isParentCollection) + { + bindingPoint.TrySetValue(CreateInstance(type, config, options)); + } + } } [RequiresDynamicCode(DynamicCodeWarningMessage)] diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs index eea01092667e8d..a7e0474028172b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs @@ -2098,14 +2098,9 @@ public void CanBindToObjectMembers() TestBind(options => config.GetSection("Local").Bind(RemoteAuthenticationOptions.s_NonGenericField), obj => RemoteAuthenticationOptions.s_NonGenericField); // No null refs. -#if BUILDING_SOURCE_GENERATOR_TESTS - - Assert.Throws(() => config.GetSection("Local").Bind(new RemoteAuthenticationOptions().NullGenericProp)); - Assert.Throws(() => config.GetSection("Local").Bind(RemoteAuthenticationOptions.s_NullNonGenericField)); -#else config.GetSection("Local").Bind(new RemoteAuthenticationOptions().NullGenericProp); config.GetSection("Local").Bind(RemoteAuthenticationOptions.s_NullNonGenericField); -#endif + static void TestBind(Action> configure, Func, OidcProviderOptions> getBindedProp) { var obj = new RemoteAuthenticationOptions(); @@ -2121,5 +2116,81 @@ public void BinderSupportsObjCreationInput() // No diagnostic warning SYSLIB1104. configuration.Bind(new GraphWithUnsupportedMember()); } + + [Fact] + public void TestNullHandling_Get() + { + // Null configuration. + IConfiguration? configuration = null; + + Assert.Throws(() => configuration.Get()); + Assert.Throws(() => configuration.Get(_ => { })); + Assert.Throws(() => configuration.Get()); + Assert.Throws(() => configuration.Get(_ => { })); + + // Null Type. + configuration = TestHelpers.GetConfigurationFromJsonString(@"{""Longitude"":1,""Latitude"":2}"); +#pragma warning disable SYSLIB1104 // The target type for a binder call could not be determined + Assert.Throws(() => configuration.Get(type: null)); + Assert.Throws(() => configuration.Get(type: null, _ => { })); +#pragma warning restore SYSLIB1104 // The target type for a binder call could not be determined + } + + [Fact] + public void TestNullHandling_GetValue() + { + string key = "Longitude"; + + // Null configuration. + Test(configuration: null, key); + + // Null type. + IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{""Longitude"":1,""Latitude"":2}"); +#pragma warning disable SYSLIB1104 // The target type for a binder call could not be determined + Assert.Throws(() => configuration.GetValue(type: null, key)); + Assert.Throws(() => configuration.GetValue(type: null, key, defaultValue: null)); +#pragma warning restore SYSLIB1104 // The target type for a binder call could not be determined + + // Null key. + Test(configuration: configuration, key: null); + + void Test(IConfiguration? configuration, string? key) + { + Assert.Throws(() => configuration.GetValue(key)); + Assert.Throws(() => configuration.GetValue(key, defaultValue: null)); + Assert.Throws(() => configuration.GetValue(key)); + Assert.Throws(() => configuration.GetValue(key, defaultValue: default)); + TestUntypedOverloads(configuration: null, key); + } + + void TestUntypedOverloads(IConfiguration? configuration, string? key) + { + Assert.Throws(() => configuration.GetValue(typeof(GeolocationClass), key)); + Assert.Throws(() => configuration.GetValue(typeof(GeolocationClass), key, defaultValue: null)); + Assert.Throws(() => configuration.GetValue(typeof(GeolocationClass), key, new GeolocationClass())); + Assert.Throws(() => configuration.GetValue(typeof(Geolocation), key)); + Assert.Throws(() => configuration.GetValue(typeof(Geolocation), key, defaultValue: null)); + Assert.Throws(() => configuration.GetValue(typeof(Geolocation), key, default(Geolocation))); + } + } + + [Fact] + public void TestNullHandling_Bind() + { + // Null configuration. + IConfiguration? configuration = null; + GeolocationClass? location = new(); + Assert.Throws(() => configuration.Bind(location)); + Assert.Throws(() => configuration.Bind(location, _ => { })); + Assert.Throws(() => configuration.Bind("", location)); + + // Null object. + configuration = TestHelpers.GetConfigurationFromJsonString(@"{""Longitude"":1,""Latitude"":2}"); + location = null; + // Expect no exceptions. + configuration.Bind(location); + configuration.Bind(location, _ => { }); + configuration.Bind("", location); + } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt index 528847cfeb3a37..5f186e42e4da7d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt @@ -55,61 +55,61 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClassWithCustomCollections)) { - var obj = new Program.MyClassWithCustomCollections(); - BindCore(configuration, ref obj, binderOptions); - return obj; + var instance = new Program.MyClassWithCustomCollections(); + BindCore(configuration, ref instance, binderOptions); + return instance; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref Program.CustomDictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.CustomDictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = ParseInt(value, () => section.Path); + instance[section.Key] = ParseInt(value, () => section.Path); } } } - public static void BindCore(IConfiguration configuration, ref Program.CustomList obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.CustomList instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(value); + instance.Add(value); } } } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref ICollection obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref ICollection instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref IReadOnlyList obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref IReadOnlyList instance, BinderOptions? binderOptions) { - if (obj is not ICollection temp) + if (instance is not ICollection temp) { return; } @@ -123,31 +123,31 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = ParseInt(value, () => section.Path); + instance[section.Key] = ParseInt(value, () => section.Path); } } } - public static void BindCore(IConfiguration configuration, ref IDictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref IDictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = ParseInt(value, () => section.Path); + instance[section.Key] = ParseInt(value, () => section.Path); } } } - public static void BindCore(IConfiguration configuration, ref IReadOnlyDictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref IReadOnlyDictionary instance, BinderOptions? binderOptions) { - if (obj is not IDictionary temp) + if (instance is not IDictionary temp) { return; } @@ -161,40 +161,40 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClassWithCustomCollections obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClassWithCustomCollections instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClassWithCustomCollections), s_configKeys_ProgramMyClassWithCustomCollections, configuration, binderOptions); if (AsConfigWithChildren(configuration.GetSection("CustomDictionary")) is IConfigurationSection section1) { - Program.CustomDictionary? temp3 = obj.CustomDictionary; + Program.CustomDictionary? temp3 = instance.CustomDictionary; temp3 ??= new Program.CustomDictionary(); BindCore(section1, ref temp3, binderOptions); - obj.CustomDictionary = temp3; + instance.CustomDictionary = temp3; } if (AsConfigWithChildren(configuration.GetSection("CustomList")) is IConfigurationSection section4) { - Program.CustomList? temp6 = obj.CustomList; + Program.CustomList? temp6 = instance.CustomList; temp6 ??= new Program.CustomList(); BindCore(section4, ref temp6, binderOptions); - obj.CustomList = temp6; + instance.CustomList = temp6; } if (AsConfigWithChildren(configuration.GetSection("IReadOnlyList")) is IConfigurationSection section7) { - IReadOnlyList? temp9 = obj.IReadOnlyList; + IReadOnlyList? temp9 = instance.IReadOnlyList; temp9 = temp9 is null ? new List() : new List(temp9); BindCore(section7, ref temp9, binderOptions); - obj.IReadOnlyList = temp9; + instance.IReadOnlyList = temp9; } if (AsConfigWithChildren(configuration.GetSection("IReadOnlyDictionary")) is IConfigurationSection section10) { - IReadOnlyDictionary? temp12 = obj.IReadOnlyDictionary; + IReadOnlyDictionary? temp12 = instance.IReadOnlyDictionary; temp12 = temp12 is null ? new Dictionary() : temp12.ToDictionary(pair => pair.Key, pair => pair.Value); BindCore(section10, ref temp12, binderOptions); - obj.IReadOnlyDictionary = temp12; + instance.IReadOnlyDictionary = temp12; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt index 36ac12fd31f83d..8d1f02b4e62e11 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt @@ -32,55 +32,55 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region IConfiguration extensions. /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. [InterceptsLocationAttribute(@"src-0.cs", 13, 18)] - public static void Bind_ProgramMyClass(this IConfiguration configuration, object? obj) + public static void Bind_ProgramMyClass(this IConfiguration configuration, object? instance) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - if (obj is null) + if (instance is null) { - throw new ArgumentNullException(nameof(obj)); + return; } - var typedObj = (Program.MyClass)obj; + var typedObj = (Program.MyClass)instance; BindCore(configuration, ref typedObj, binderOptions: null); } /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. [InterceptsLocationAttribute(@"src-0.cs", 14, 24)] - public static void Bind_ProgramMyClass(this IConfiguration configuration, object? obj, Action? configureOptions) + public static void Bind_ProgramMyClass(this IConfiguration configuration, object? instance, Action? configureOptions) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - if (obj is null) + if (instance is null) { - throw new ArgumentNullException(nameof(obj)); + return; } - var typedObj = (Program.MyClass)obj; + var typedObj = (Program.MyClass)instance; BindCore(configuration, ref typedObj, GetBinderOptions(configureOptions)); } /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. [InterceptsLocationAttribute(@"src-0.cs", 15, 24)] - public static void Bind_ProgramMyClass(this IConfiguration configuration, string key, object? obj) + public static void Bind_ProgramMyClass(this IConfiguration configuration, string key, object? instance) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - if (obj is null) + if (instance is null) { - throw new ArgumentNullException(nameof(obj)); + return; } - var typedObj = (Program.MyClass)obj; + var typedObj = (Program.MyClass)instance; BindCore(configuration.GetSection(key), ref typedObj, binderOptions: null); } #endregion IConfiguration extensions. @@ -88,73 +88,73 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = value; + instance[section.Key] = value; } } } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (!(obj.TryGetValue(section.Key, out Program.MyClass2? element) && element is not null)) + if (!(instance.TryGetValue(section.Key, out Program.MyClass2? element) && element is not null)) { element = new Program.MyClass2(); } - obj[section.Key] = element; + instance[section.Key] = element; } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value1) { - obj.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section2) { - List? temp4 = obj.MyList; + List? temp4 = instance.MyList; temp4 ??= new List(); BindCore(section2, ref temp4, binderOptions); - obj.MyList = temp4; + instance.MyList = temp4; } if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section5) { - Dictionary? temp7 = obj.MyDictionary; + Dictionary? temp7 = instance.MyDictionary; temp7 ??= new Dictionary(); BindCore(section5, ref temp7, binderOptions); - obj.MyDictionary = temp7; + instance.MyDictionary = temp7; } if (AsConfigWithChildren(configuration.GetSection("MyComplexDictionary")) is IConfigurationSection section8) { - Dictionary? temp10 = obj.MyComplexDictionary; + Dictionary? temp10 = instance.MyComplexDictionary; temp10 ??= new Dictionary(); BindCore(section8, ref temp10, binderOptions); - obj.MyComplexDictionary = temp10; + instance.MyComplexDictionary = temp10; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt index 02fb06957bb3d5..f3008878ca3c56 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt @@ -32,19 +32,19 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region IConfiguration extensions. /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. [InterceptsLocationAttribute(@"src-0.cs", 12, 20)] - public static void Bind_ProgramMyClass(this IConfiguration configuration, object? obj) + public static void Bind_ProgramMyClass(this IConfiguration configuration, object? instance) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - if (obj is null) + if (instance is null) { - throw new ArgumentNullException(nameof(obj)); + return; } - var typedObj = (Program.MyClass)obj; + var typedObj = (Program.MyClass)instance; BindCore(configuration, ref typedObj, binderOptions: null); } #endregion IConfiguration extensions. @@ -52,73 +52,73 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = value; + instance[section.Key] = value; } } } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (!(obj.TryGetValue(section.Key, out Program.MyClass2? element) && element is not null)) + if (!(instance.TryGetValue(section.Key, out Program.MyClass2? element) && element is not null)) { element = new Program.MyClass2(); } - obj[section.Key] = element; + instance[section.Key] = element; } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value1) { - obj.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section2) { - List? temp4 = obj.MyList; + List? temp4 = instance.MyList; temp4 ??= new List(); BindCore(section2, ref temp4, binderOptions); - obj.MyList = temp4; + instance.MyList = temp4; } if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section5) { - Dictionary? temp7 = obj.MyDictionary; + Dictionary? temp7 = instance.MyDictionary; temp7 ??= new Dictionary(); BindCore(section5, ref temp7, binderOptions); - obj.MyDictionary = temp7; + instance.MyDictionary = temp7; } if (AsConfigWithChildren(configuration.GetSection("MyComplexDictionary")) is IConfigurationSection section8) { - Dictionary? temp10 = obj.MyComplexDictionary; + Dictionary? temp10 = instance.MyComplexDictionary; temp10 ??= new Dictionary(); BindCore(section8, ref temp10, binderOptions); - obj.MyComplexDictionary = temp10; + instance.MyComplexDictionary = temp10; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt index 4703980996b889..19b955b6ea8bff 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt @@ -32,19 +32,19 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region IConfiguration extensions. /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. [InterceptsLocationAttribute(@"src-0.cs", 12, 20)] - public static void Bind_ProgramMyClass(this IConfiguration configuration, object? obj, Action? configureOptions) + public static void Bind_ProgramMyClass(this IConfiguration configuration, object? instance, Action? configureOptions) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - if (obj is null) + if (instance is null) { - throw new ArgumentNullException(nameof(obj)); + return; } - var typedObj = (Program.MyClass)obj; + var typedObj = (Program.MyClass)instance; BindCore(configuration, ref typedObj, GetBinderOptions(configureOptions)); } #endregion IConfiguration extensions. @@ -52,73 +52,73 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = value; + instance[section.Key] = value; } } } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (!(obj.TryGetValue(section.Key, out Program.MyClass2? element) && element is not null)) + if (!(instance.TryGetValue(section.Key, out Program.MyClass2? element) && element is not null)) { element = new Program.MyClass2(); } - obj[section.Key] = element; + instance[section.Key] = element; } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value1) { - obj.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section2) { - List? temp4 = obj.MyList; + List? temp4 = instance.MyList; temp4 ??= new List(); BindCore(section2, ref temp4, binderOptions); - obj.MyList = temp4; + instance.MyList = temp4; } if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section5) { - Dictionary? temp7 = obj.MyDictionary; + Dictionary? temp7 = instance.MyDictionary; temp7 ??= new Dictionary(); BindCore(section5, ref temp7, binderOptions); - obj.MyDictionary = temp7; + instance.MyDictionary = temp7; } if (AsConfigWithChildren(configuration.GetSection("MyComplexDictionary")) is IConfigurationSection section8) { - Dictionary? temp10 = obj.MyComplexDictionary; + Dictionary? temp10 = instance.MyComplexDictionary; temp10 ??= new Dictionary(); BindCore(section8, ref temp10, binderOptions); - obj.MyComplexDictionary = temp10; + instance.MyComplexDictionary = temp10; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt index 99371296997168..8533828221175b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt @@ -32,19 +32,19 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region IConfiguration extensions. /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. [InterceptsLocationAttribute(@"src-0.cs", 12, 20)] - public static void Bind_ProgramMyClass(this IConfiguration configuration, string key, object? obj) + public static void Bind_ProgramMyClass(this IConfiguration configuration, string key, object? instance) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - if (obj is null) + if (instance is null) { - throw new ArgumentNullException(nameof(obj)); + return; } - var typedObj = (Program.MyClass)obj; + var typedObj = (Program.MyClass)instance; BindCore(configuration.GetSection(key), ref typedObj, binderOptions: null); } #endregion IConfiguration extensions. @@ -52,73 +52,73 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = value; + instance[section.Key] = value; } } } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (!(obj.TryGetValue(section.Key, out Program.MyClass2? element) && element is not null)) + if (!(instance.TryGetValue(section.Key, out Program.MyClass2? element) && element is not null)) { element = new Program.MyClass2(); } - obj[section.Key] = element; + instance[section.Key] = element; } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value1) { - obj.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section2) { - List? temp4 = obj.MyList; + List? temp4 = instance.MyList; temp4 ??= new List(); BindCore(section2, ref temp4, binderOptions); - obj.MyList = temp4; + instance.MyList = temp4; } if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section5) { - Dictionary? temp7 = obj.MyDictionary; + Dictionary? temp7 = instance.MyDictionary; temp7 ??= new Dictionary(); BindCore(section5, ref temp7, binderOptions); - obj.MyDictionary = temp7; + instance.MyDictionary = temp7; } if (AsConfigWithChildren(configuration.GetSection("MyComplexDictionary")) is IConfigurationSection section8) { - Dictionary? temp10 = obj.MyComplexDictionary; + Dictionary? temp10 = instance.MyComplexDictionary; temp10 ??= new Dictionary(); BindCore(section8, ref temp10, binderOptions); - obj.MyComplexDictionary = temp10; + instance.MyComplexDictionary = temp10; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt index 3e6ce1459b289a..4acbebff935bca 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt @@ -67,94 +67,94 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { - var obj = new Program.MyClass(); - BindCore(configuration, ref obj, binderOptions); - return obj; + var instance = new Program.MyClass(); + BindCore(configuration, ref instance, binderOptions); + return instance; } else if (type == typeof(Program.MyClass2)) { - var obj = new Program.MyClass2(); - BindCore(configuration, ref obj, binderOptions); - return obj; + var instance = new Program.MyClass2(); + BindCore(configuration, ref instance, binderOptions); + return instance; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref int[] obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref int[] instance, BinderOptions? binderOptions) { var temp2 = new List(); BindCore(configuration, ref temp2, binderOptions); - int originalCount = obj.Length; - Array.Resize(ref obj, originalCount + temp2.Count); - temp2.CopyTo(obj, originalCount); + int originalCount = instance.Length; + Array.Resize(ref instance, originalCount + temp2.Count); + temp2.CopyTo(instance, originalCount); } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = value; + instance[section.Key] = value; } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value5) { - obj.MyInt = ParseInt(value5, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value5, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section6) { - List? temp8 = obj.MyList; + List? temp8 = instance.MyList; temp8 ??= new List(); BindCore(section6, ref temp8, binderOptions); - obj.MyList = temp8; + instance.MyList = temp8; } if (AsConfigWithChildren(configuration.GetSection("MyArray")) is IConfigurationSection section9) { - int[]? temp11 = obj.MyArray; + int[]? temp11 = instance.MyArray; temp11 ??= new int[0]; BindCore(section9, ref temp11, binderOptions); - obj.MyArray = temp11; + instance.MyArray = temp11; } if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section12) { - Dictionary? temp14 = obj.MyDictionary; + Dictionary? temp14 = instance.MyDictionary; temp14 ??= new Dictionary(); BindCore(section12, ref temp14, binderOptions); - obj.MyDictionary = temp14; + instance.MyDictionary = temp14; } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value15) { - obj.MyInt = ParseInt(value15, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value15, () => configuration.GetSection("MyInt").Path); } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt index 85d0901de3ff60..fb5cf5e4b5ca31 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt @@ -54,78 +54,78 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { - var obj = new Program.MyClass(); - BindCore(configuration, ref obj, binderOptions); - return obj; + var instance = new Program.MyClass(); + BindCore(configuration, ref instance, binderOptions); + return instance; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref int[] obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref int[] instance, BinderOptions? binderOptions) { var temp1 = new List(); BindCore(configuration, ref temp1, binderOptions); - int originalCount = obj.Length; - Array.Resize(ref obj, originalCount + temp1.Count); - temp1.CopyTo(obj, originalCount); + int originalCount = instance.Length; + Array.Resize(ref instance, originalCount + temp1.Count); + temp1.CopyTo(instance, originalCount); } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = value; + instance[section.Key] = value; } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value4) { - obj.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) { - List? temp7 = obj.MyList; + List? temp7 = instance.MyList; temp7 ??= new List(); BindCore(section5, ref temp7, binderOptions); - obj.MyList = temp7; + instance.MyList = temp7; } if (AsConfigWithChildren(configuration.GetSection("MyArray")) is IConfigurationSection section8) { - int[]? temp10 = obj.MyArray; + int[]? temp10 = instance.MyArray; temp10 ??= new int[0]; BindCore(section8, ref temp10, binderOptions); - obj.MyArray = temp10; + instance.MyArray = temp10; } if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section11) { - Dictionary? temp13 = obj.MyDictionary; + Dictionary? temp13 = instance.MyDictionary; temp13 ??= new Dictionary(); BindCore(section11, ref temp13, binderOptions); - obj.MyDictionary = temp13; + instance.MyDictionary = temp13; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt index d394cc7b269f74..ac8e362b4e2e07 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt @@ -54,78 +54,78 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { - var obj = new Program.MyClass(); - BindCore(configuration, ref obj, binderOptions); - return obj; + var instance = new Program.MyClass(); + BindCore(configuration, ref instance, binderOptions); + return instance; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref int[] obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref int[] instance, BinderOptions? binderOptions) { var temp1 = new List(); BindCore(configuration, ref temp1, binderOptions); - int originalCount = obj.Length; - Array.Resize(ref obj, originalCount + temp1.Count); - temp1.CopyTo(obj, originalCount); + int originalCount = instance.Length; + Array.Resize(ref instance, originalCount + temp1.Count); + temp1.CopyTo(instance, originalCount); } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = value; + instance[section.Key] = value; } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value4) { - obj.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) { - List? temp7 = obj.MyList; + List? temp7 = instance.MyList; temp7 ??= new List(); BindCore(section5, ref temp7, binderOptions); - obj.MyList = temp7; + instance.MyList = temp7; } if (AsConfigWithChildren(configuration.GetSection("MyArray")) is IConfigurationSection section8) { - int[]? temp10 = obj.MyArray; + int[]? temp10 = instance.MyArray; temp10 ??= new int[0]; BindCore(section8, ref temp10, binderOptions); - obj.MyArray = temp10; + instance.MyArray = temp10; } if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section11) { - Dictionary? temp13 = obj.MyDictionary; + Dictionary? temp13 = instance.MyDictionary; temp13 ??= new Dictionary(); BindCore(section11, ref temp13, binderOptions); - obj.MyDictionary = temp13; + instance.MyDictionary = temp13; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt index 83cd88561310ab..5d0088b908162d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt @@ -54,21 +54,21 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass2)) { - var obj = new Program.MyClass2(); - BindCore(configuration, ref obj, binderOptions); - return obj; + var instance = new Program.MyClass2(); + BindCore(configuration, ref instance, binderOptions); + return instance; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value1) { - obj.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt index 91714c80cd0136..9da3a3a22e9b7c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt @@ -54,21 +54,21 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass2)) { - var obj = new Program.MyClass2(); - BindCore(configuration, ref obj, binderOptions); - return obj; + var instance = new Program.MyClass2(); + BindCore(configuration, ref instance, binderOptions); + return instance; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value1) { - obj.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt index 88b35037c22c3f..96e389be895602 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt @@ -34,7 +34,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region OptionsBuilder extensions. /// Registers the dependency injection container to bind against the obtained from the DI service provider. [InterceptsLocationAttribute(@"src-0.cs", 12, 24)] - public static OptionsBuilder BindConfiguration(this OptionsBuilder optionsBuilder, string configSectionPath, Action? configureOptions = null) where TOptions : class + public static OptionsBuilder BindConfiguration(this OptionsBuilder optionsBuilder, string configSectionPath, Action? configureBinder = null) where TOptions : class { if (optionsBuilder is null) { @@ -46,20 +46,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new ArgumentNullException(nameof(configSectionPath)); } - optionsBuilder.Configure((obj, configuration) => + optionsBuilder.Configure((instance, config) => { - if (obj is null) + if (config is null) { - throw new ArgumentNullException(nameof(obj)); + throw new ArgumentNullException(nameof(config)); } - if (configuration is null) - { - throw new ArgumentNullException(nameof(configuration)); - } - - IConfiguration section = string.Equals(string.Empty, configSectionPath, StringComparison.OrdinalIgnoreCase) ? configuration : configuration.GetSection(configSectionPath); - BindCoreMain(section, obj, typeof(TOptions), configureOptions); + IConfiguration section = string.Equals(string.Empty, configSectionPath, StringComparison.OrdinalIgnoreCase) ? config : config.GetSection(configSectionPath); + BindCoreMain(section, instance, typeof(TOptions), configureBinder); }); optionsBuilder.Services.AddSingleton, ConfigurationChangeTokenSource>(); @@ -70,16 +65,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList" }); - public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object instance, Type type, Action? configureOptions) { - if (configuration is null) + if (instance is null) { - throw new ArgumentNullException(nameof(configuration)); - } - - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); + return; } if (!HasValueOrChildren(configuration)) @@ -91,7 +81,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { - var temp = (Program.MyClass)obj; + var temp = (Program.MyClass)instance; BindCore(configuration, ref temp, binderOptions); return; } @@ -99,34 +89,34 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value2) { - obj.MyInt = ParseInt(value2, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value2, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section3) { - List? temp5 = obj.MyList; + List? temp5 = instance.MyList; temp5 ??= new List(); BindCore(section3, ref temp5, binderOptions); - obj.MyList = temp5; + instance.MyList = temp5; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt index ff590d8398f3a1..9755ab0df00086 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt @@ -34,57 +34,52 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region OptionsBuilder extensions. /// Registers a configuration instance which will bind against. [InterceptsLocationAttribute(@"src-0.cs", 15, 24)] - public static OptionsBuilder Bind(this OptionsBuilder optionsBuilder, IConfiguration configuration) where TOptions : class + public static OptionsBuilder Bind(this OptionsBuilder optionsBuilder, IConfiguration config) where TOptions : class { - return Bind(optionsBuilder, configuration, configureOptions: null); + return Bind(optionsBuilder, config, configureBinder: null); } /// Registers a configuration instance which will bind against. - public static OptionsBuilder Bind(this OptionsBuilder optionsBuilder, IConfiguration configuration, Action? configureOptions) where TOptions : class + public static OptionsBuilder Bind(this OptionsBuilder optionsBuilder, IConfiguration config, Action? configureBinder) where TOptions : class { if (optionsBuilder is null) { throw new ArgumentNullException(nameof(optionsBuilder)); } - Configure(optionsBuilder.Services, optionsBuilder.Name, configuration, configureOptions); + Configure(optionsBuilder.Services, optionsBuilder.Name, config, configureBinder); return optionsBuilder; } #endregion OptionsBuilder extensions. #region IServiceCollection extensions. /// Registers a configuration instance which TOptions will bind against. - public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration, Action? configureOptions) where TOptions : class + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration config, Action? configureOptions) where TOptions : class { if (services is null) { throw new ArgumentNullException(nameof(services)); } - if (configuration is null) + if (config is null) { - throw new ArgumentNullException(nameof(configuration)); + throw new ArgumentNullException(nameof(config)); } OptionsServiceCollectionExtensions.AddOptions(services); - services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); - return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions), configureOptions))); + services.AddSingleton>(new ConfigurationChangeTokenSource(name, config)); + return services.AddSingleton>(new ConfigureNamedOptions(name, instance => BindCoreMain(config, instance, typeof(TOptions), configureOptions))); } #endregion IServiceCollection extensions. #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList" }); - public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object instance, Type type, Action? configureOptions) { - if (configuration is null) + if (instance is null) { - throw new ArgumentNullException(nameof(configuration)); - } - - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); + return; } if (!HasValueOrChildren(configuration)) @@ -96,7 +91,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { - var temp = (Program.MyClass)obj; + var temp = (Program.MyClass)instance; BindCore(configuration, ref temp, binderOptions); return; } @@ -104,34 +99,34 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value2) { - obj.MyInt = ParseInt(value2, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value2, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section3) { - List? temp5 = obj.MyList; + List? temp5 = instance.MyList; temp5 ??= new List(); BindCore(section3, ref temp5, binderOptions); - obj.MyList = temp5; + instance.MyList = temp5; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt index b7b6ef86a4c056..141d2d41f77f83 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt @@ -34,51 +34,46 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region OptionsBuilder extensions. /// Registers a configuration instance which will bind against. [InterceptsLocationAttribute(@"src-0.cs", 15, 24)] - public static OptionsBuilder Bind(this OptionsBuilder optionsBuilder, IConfiguration configuration, Action? configureOptions) where TOptions : class + public static OptionsBuilder Bind(this OptionsBuilder optionsBuilder, IConfiguration config, Action? configureBinder) where TOptions : class { if (optionsBuilder is null) { throw new ArgumentNullException(nameof(optionsBuilder)); } - Configure(optionsBuilder.Services, optionsBuilder.Name, configuration, configureOptions); + Configure(optionsBuilder.Services, optionsBuilder.Name, config, configureBinder); return optionsBuilder; } #endregion OptionsBuilder extensions. #region IServiceCollection extensions. /// Registers a configuration instance which TOptions will bind against. - public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration, Action? configureOptions) where TOptions : class + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration config, Action? configureOptions) where TOptions : class { if (services is null) { throw new ArgumentNullException(nameof(services)); } - if (configuration is null) + if (config is null) { - throw new ArgumentNullException(nameof(configuration)); + throw new ArgumentNullException(nameof(config)); } OptionsServiceCollectionExtensions.AddOptions(services); - services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); - return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions), configureOptions))); + services.AddSingleton>(new ConfigurationChangeTokenSource(name, config)); + return services.AddSingleton>(new ConfigureNamedOptions(name, instance => BindCoreMain(config, instance, typeof(TOptions), configureOptions))); } #endregion IServiceCollection extensions. #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList" }); - public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object instance, Type type, Action? configureOptions) { - if (configuration is null) + if (instance is null) { - throw new ArgumentNullException(nameof(configuration)); - } - - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); + return; } if (!HasValueOrChildren(configuration)) @@ -90,7 +85,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { - var temp = (Program.MyClass)obj; + var temp = (Program.MyClass)instance; BindCore(configuration, ref temp, binderOptions); return; } @@ -98,34 +93,34 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value2) { - obj.MyInt = ParseInt(value2, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value2, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section3) { - List? temp5 = obj.MyList; + List? temp5 = instance.MyList; temp5 ??= new List(); BindCore(section3, ref temp5, binderOptions); - obj.MyList = temp5; + instance.MyList = temp5; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt index 1bf110454ec7ba..1fd82a86d72c0d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt @@ -32,19 +32,19 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region IConfiguration extensions. /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. [InterceptsLocationAttribute(@"src-0.cs", 13, 16)] - public static void Bind_ProgramMyClass(this IConfiguration configuration, object? obj) + public static void Bind_ProgramMyClass(this IConfiguration configuration, object? instance) { if (configuration is null) { throw new ArgumentNullException(nameof(configuration)); } - if (obj is null) + if (instance is null) { - throw new ArgumentNullException(nameof(obj)); + return; } - var typedObj = (Program.MyClass)obj; + var typedObj = (Program.MyClass)instance; BindCore(configuration, ref typedObj, binderOptions: null); } #endregion IConfiguration extensions. @@ -52,142 +52,142 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "Prop0", "Prop1", "Prop2", "Prop3", "Prop4", "Prop5", "Prop6", "Prop8", "Prop9", "Prop10", "Prop13", "Prop14", "Prop15", "Prop16", "Prop17", "Prop19", "Prop20", "Prop21", "Prop23", "Prop24", "Prop25", "Prop26", "Prop27", "Prop7", "Prop11", "Prop12", "Prop18", "Prop22" }); - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); if (configuration["Prop0"] is string value0) { - obj.Prop0 = ParseBool(value0, () => configuration.GetSection("Prop0").Path); + instance.Prop0 = ParseBool(value0, () => configuration.GetSection("Prop0").Path); } if (configuration["Prop1"] is string value1) { - obj.Prop1 = ParseByte(value1, () => configuration.GetSection("Prop1").Path); + instance.Prop1 = ParseByte(value1, () => configuration.GetSection("Prop1").Path); } if (configuration["Prop2"] is string value2) { - obj.Prop2 = ParseSbyte(value2, () => configuration.GetSection("Prop2").Path); + instance.Prop2 = ParseSbyte(value2, () => configuration.GetSection("Prop2").Path); } if (configuration["Prop3"] is string value3) { - obj.Prop3 = ParseChar(value3, () => configuration.GetSection("Prop3").Path); + instance.Prop3 = ParseChar(value3, () => configuration.GetSection("Prop3").Path); } if (configuration["Prop4"] is string value4) { - obj.Prop4 = ParseDouble(value4, () => configuration.GetSection("Prop4").Path); + instance.Prop4 = ParseDouble(value4, () => configuration.GetSection("Prop4").Path); } - obj.Prop5 = configuration["Prop5"]!; + instance.Prop5 = configuration["Prop5"]!; if (configuration["Prop6"] is string value6) { - obj.Prop6 = ParseInt(value6, () => configuration.GetSection("Prop6").Path); + instance.Prop6 = ParseInt(value6, () => configuration.GetSection("Prop6").Path); } if (configuration["Prop8"] is string value7) { - obj.Prop8 = ParseShort(value7, () => configuration.GetSection("Prop8").Path); + instance.Prop8 = ParseShort(value7, () => configuration.GetSection("Prop8").Path); } if (configuration["Prop9"] is string value8) { - obj.Prop9 = ParseLong(value8, () => configuration.GetSection("Prop9").Path); + instance.Prop9 = ParseLong(value8, () => configuration.GetSection("Prop9").Path); } if (configuration["Prop10"] is string value9) { - obj.Prop10 = ParseFloat(value9, () => configuration.GetSection("Prop10").Path); + instance.Prop10 = ParseFloat(value9, () => configuration.GetSection("Prop10").Path); } if (configuration["Prop13"] is string value10) { - obj.Prop13 = ParseUshort(value10, () => configuration.GetSection("Prop13").Path); + instance.Prop13 = ParseUshort(value10, () => configuration.GetSection("Prop13").Path); } if (configuration["Prop14"] is string value11) { - obj.Prop14 = ParseUint(value11, () => configuration.GetSection("Prop14").Path); + instance.Prop14 = ParseUint(value11, () => configuration.GetSection("Prop14").Path); } if (configuration["Prop15"] is string value12) { - obj.Prop15 = ParseUlong(value12, () => configuration.GetSection("Prop15").Path); + instance.Prop15 = ParseUlong(value12, () => configuration.GetSection("Prop15").Path); } - obj.Prop16 = configuration["Prop16"]!; + instance.Prop16 = configuration["Prop16"]!; if (configuration["Prop17"] is string value14) { - obj.Prop17 = ParseCultureInfo(value14, () => configuration.GetSection("Prop17").Path); + instance.Prop17 = ParseCultureInfo(value14, () => configuration.GetSection("Prop17").Path); } if (configuration["Prop19"] is string value15) { - obj.Prop19 = ParseDateTime(value15, () => configuration.GetSection("Prop19").Path); + instance.Prop19 = ParseDateTime(value15, () => configuration.GetSection("Prop19").Path); } if (configuration["Prop20"] is string value16) { - obj.Prop20 = ParseDateTimeOffset(value16, () => configuration.GetSection("Prop20").Path); + instance.Prop20 = ParseDateTimeOffset(value16, () => configuration.GetSection("Prop20").Path); } if (configuration["Prop21"] is string value17) { - obj.Prop21 = ParseDecimal(value17, () => configuration.GetSection("Prop21").Path); + instance.Prop21 = ParseDecimal(value17, () => configuration.GetSection("Prop21").Path); } if (configuration["Prop23"] is string value18) { - obj.Prop23 = ParseInt(value18, () => configuration.GetSection("Prop23").Path); + instance.Prop23 = ParseInt(value18, () => configuration.GetSection("Prop23").Path); } if (configuration["Prop24"] is string value19) { - obj.Prop24 = ParseDateTime(value19, () => configuration.GetSection("Prop24").Path); + instance.Prop24 = ParseDateTime(value19, () => configuration.GetSection("Prop24").Path); } if (configuration["Prop25"] is string value20) { - obj.Prop25 = ParseUri(value20, () => configuration.GetSection("Prop25").Path); + instance.Prop25 = ParseUri(value20, () => configuration.GetSection("Prop25").Path); } if (configuration["Prop26"] is string value21) { - obj.Prop26 = ParseVersion(value21, () => configuration.GetSection("Prop26").Path); + instance.Prop26 = ParseVersion(value21, () => configuration.GetSection("Prop26").Path); } if (configuration["Prop27"] is string value22) { - obj.Prop27 = ParseEnum(value22, () => configuration.GetSection("Prop27").Path); + instance.Prop27 = ParseEnum(value22, () => configuration.GetSection("Prop27").Path); } if (configuration["Prop7"] is string value23) { - obj.Prop7 = ParseInt128(value23, () => configuration.GetSection("Prop7").Path); + instance.Prop7 = ParseInt128(value23, () => configuration.GetSection("Prop7").Path); } if (configuration["Prop11"] is string value24) { - obj.Prop11 = ParseHalf(value24, () => configuration.GetSection("Prop11").Path); + instance.Prop11 = ParseHalf(value24, () => configuration.GetSection("Prop11").Path); } if (configuration["Prop12"] is string value25) { - obj.Prop12 = ParseUInt128(value25, () => configuration.GetSection("Prop12").Path); + instance.Prop12 = ParseUInt128(value25, () => configuration.GetSection("Prop12").Path); } if (configuration["Prop18"] is string value26) { - obj.Prop18 = ParseDateOnly(value26, () => configuration.GetSection("Prop18").Path); + instance.Prop18 = ParseDateOnly(value26, () => configuration.GetSection("Prop18").Path); } if (configuration["Prop22"] is string value27) { - obj.Prop22 = ParseByteArray(value27, () => configuration.GetSection("Prop22").Path); + instance.Prop22 = ParseByteArray(value27, () => configuration.GetSection("Prop22").Path); } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt index 7a956f99b57b13..0ff2de59156df9 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt @@ -33,27 +33,27 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region IServiceCollection extensions. /// Registers a configuration instance which TOptions will bind against. [InterceptsLocationAttribute(@"src-0.cs", 14, 18)] - public static IServiceCollection Configure(this IServiceCollection services, IConfiguration configuration) where TOptions : class + public static IServiceCollection Configure(this IServiceCollection services, IConfiguration config) where TOptions : class { - return Configure(services, string.Empty, configuration, configureOptions: null); + return Configure(services, string.Empty, config, configureOptions: null); } /// Registers a configuration instance which TOptions will bind against. - public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration, Action? configureOptions) where TOptions : class + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration config, Action? configureOptions) where TOptions : class { if (services is null) { throw new ArgumentNullException(nameof(services)); } - if (configuration is null) + if (config is null) { - throw new ArgumentNullException(nameof(configuration)); + throw new ArgumentNullException(nameof(config)); } OptionsServiceCollectionExtensions.AddOptions(services); - services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); - return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions), configureOptions))); + services.AddSingleton>(new ConfigurationChangeTokenSource(name, config)); + return services.AddSingleton>(new ConfigureNamedOptions(name, instance => BindCoreMain(config, instance, typeof(TOptions), configureOptions))); } #endregion IServiceCollection extensions. @@ -61,16 +61,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration private readonly static Lazy> s_configKeys_ProgramMyClass2 = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyInt" }); private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyList2", "MyDictionary" }); - public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object instance, Type type, Action? configureOptions) { - if (configuration is null) + if (instance is null) { - throw new ArgumentNullException(nameof(configuration)); - } - - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); + return; } if (!HasValueOrChildren(configuration)) @@ -82,7 +77,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { - var temp = (Program.MyClass)obj; + var temp = (Program.MyClass)instance; BindCore(configuration, ref temp, binderOptions); return; } @@ -90,81 +85,81 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value1) { - obj.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { var value = new Program.MyClass2(); BindCore(section, ref value, binderOptions); - obj.Add(value); + instance.Add(value); } } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = value; + instance[section.Key] = value; } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value4) { - obj.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) { - List? temp7 = obj.MyList; + List? temp7 = instance.MyList; temp7 ??= new List(); BindCore(section5, ref temp7, binderOptions); - obj.MyList = temp7; + instance.MyList = temp7; } if (AsConfigWithChildren(configuration.GetSection("MyList2")) is IConfigurationSection section8) { - List? temp10 = obj.MyList2; + List? temp10 = instance.MyList2; temp10 ??= new List(); BindCore(section8, ref temp10, binderOptions); - obj.MyList2 = temp10; + instance.MyList2 = temp10; } if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section11) { - Dictionary? temp13 = obj.MyDictionary; + Dictionary? temp13 = instance.MyDictionary; temp13 ??= new Dictionary(); BindCore(section11, ref temp13, binderOptions); - obj.MyDictionary = temp13; + instance.MyDictionary = temp13; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt index 399f6ffe35b935..7058edb884007f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt @@ -33,27 +33,27 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region IServiceCollection extensions. /// Registers a configuration instance which TOptions will bind against. [InterceptsLocationAttribute(@"src-0.cs", 14, 18)] - public static IServiceCollection Configure(this IServiceCollection services, IConfiguration configuration, Action? configureOptions) where TOptions : class + public static IServiceCollection Configure(this IServiceCollection services, IConfiguration config, Action? configureOptions) where TOptions : class { - return Configure(services, string.Empty, configuration, configureOptions); + return Configure(services, string.Empty, config, configureOptions); } /// Registers a configuration instance which TOptions will bind against. - public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration, Action? configureOptions) where TOptions : class + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration config, Action? configureOptions) where TOptions : class { if (services is null) { throw new ArgumentNullException(nameof(services)); } - if (configuration is null) + if (config is null) { - throw new ArgumentNullException(nameof(configuration)); + throw new ArgumentNullException(nameof(config)); } OptionsServiceCollectionExtensions.AddOptions(services); - services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); - return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions), configureOptions))); + services.AddSingleton>(new ConfigurationChangeTokenSource(name, config)); + return services.AddSingleton>(new ConfigureNamedOptions(name, instance => BindCoreMain(config, instance, typeof(TOptions), configureOptions))); } #endregion IServiceCollection extensions. @@ -61,16 +61,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration private readonly static Lazy> s_configKeys_ProgramMyClass2 = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyInt" }); private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyList2", "MyDictionary" }); - public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object instance, Type type, Action? configureOptions) { - if (configuration is null) + if (instance is null) { - throw new ArgumentNullException(nameof(configuration)); - } - - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); + return; } if (!HasValueOrChildren(configuration)) @@ -82,7 +77,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { - var temp = (Program.MyClass)obj; + var temp = (Program.MyClass)instance; BindCore(configuration, ref temp, binderOptions); return; } @@ -90,81 +85,81 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value1) { - obj.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { var value = new Program.MyClass2(); BindCore(section, ref value, binderOptions); - obj.Add(value); + instance.Add(value); } } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = value; + instance[section.Key] = value; } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value4) { - obj.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) { - List? temp7 = obj.MyList; + List? temp7 = instance.MyList; temp7 ??= new List(); BindCore(section5, ref temp7, binderOptions); - obj.MyList = temp7; + instance.MyList = temp7; } if (AsConfigWithChildren(configuration.GetSection("MyList2")) is IConfigurationSection section8) { - List? temp10 = obj.MyList2; + List? temp10 = instance.MyList2; temp10 ??= new List(); BindCore(section8, ref temp10, binderOptions); - obj.MyList2 = temp10; + instance.MyList2 = temp10; } if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section11) { - Dictionary? temp13 = obj.MyDictionary; + Dictionary? temp13 = instance.MyDictionary; temp13 ??= new Dictionary(); BindCore(section11, ref temp13, binderOptions); - obj.MyDictionary = temp13; + instance.MyDictionary = temp13; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt index 197e268561f7eb..a8f247779978ca 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt @@ -33,27 +33,27 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region IServiceCollection extensions. /// Registers a configuration instance which TOptions will bind against. [InterceptsLocationAttribute(@"src-0.cs", 14, 18)] - public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration) where TOptions : class + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration config) where TOptions : class { - return Configure(services, name, configuration, configureOptions: null); + return Configure(services, name, config, configureOptions: null); } /// Registers a configuration instance which TOptions will bind against. - public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration, Action? configureOptions) where TOptions : class + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration config, Action? configureOptions) where TOptions : class { if (services is null) { throw new ArgumentNullException(nameof(services)); } - if (configuration is null) + if (config is null) { - throw new ArgumentNullException(nameof(configuration)); + throw new ArgumentNullException(nameof(config)); } OptionsServiceCollectionExtensions.AddOptions(services); - services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); - return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions), configureOptions))); + services.AddSingleton>(new ConfigurationChangeTokenSource(name, config)); + return services.AddSingleton>(new ConfigureNamedOptions(name, instance => BindCoreMain(config, instance, typeof(TOptions), configureOptions))); } #endregion IServiceCollection extensions. @@ -61,16 +61,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration private readonly static Lazy> s_configKeys_ProgramMyClass2 = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyInt" }); private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyList2", "MyDictionary" }); - public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object instance, Type type, Action? configureOptions) { - if (configuration is null) + if (instance is null) { - throw new ArgumentNullException(nameof(configuration)); - } - - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); + return; } if (!HasValueOrChildren(configuration)) @@ -82,7 +77,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { - var temp = (Program.MyClass)obj; + var temp = (Program.MyClass)instance; BindCore(configuration, ref temp, binderOptions); return; } @@ -90,81 +85,81 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value1) { - obj.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { var value = new Program.MyClass2(); BindCore(section, ref value, binderOptions); - obj.Add(value); + instance.Add(value); } } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = value; + instance[section.Key] = value; } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value4) { - obj.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) { - List? temp7 = obj.MyList; + List? temp7 = instance.MyList; temp7 ??= new List(); BindCore(section5, ref temp7, binderOptions); - obj.MyList = temp7; + instance.MyList = temp7; } if (AsConfigWithChildren(configuration.GetSection("MyList2")) is IConfigurationSection section8) { - List? temp10 = obj.MyList2; + List? temp10 = instance.MyList2; temp10 ??= new List(); BindCore(section8, ref temp10, binderOptions); - obj.MyList2 = temp10; + instance.MyList2 = temp10; } if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section11) { - Dictionary? temp13 = obj.MyDictionary; + Dictionary? temp13 = instance.MyDictionary; temp13 ??= new Dictionary(); BindCore(section11, ref temp13, binderOptions); - obj.MyDictionary = temp13; + instance.MyDictionary = temp13; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt index 0cb5881950dee3..0cbd2fba049558 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt @@ -33,21 +33,21 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region IServiceCollection extensions. /// Registers a configuration instance which TOptions will bind against. [InterceptsLocationAttribute(@"src-0.cs", 14, 18)] - public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration configuration, Action? configureOptions) where TOptions : class + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration config, Action? configureOptions) where TOptions : class { if (services is null) { throw new ArgumentNullException(nameof(services)); } - if (configuration is null) + if (config is null) { - throw new ArgumentNullException(nameof(configuration)); + throw new ArgumentNullException(nameof(config)); } OptionsServiceCollectionExtensions.AddOptions(services); - services.AddSingleton>(new ConfigurationChangeTokenSource(name, configuration)); - return services.AddSingleton>(new Microsoft.Extensions.Options.ConfigureNamedOptions(name, obj => BindCoreMain(configuration, obj, typeof(TOptions), configureOptions))); + services.AddSingleton>(new ConfigurationChangeTokenSource(name, config)); + return services.AddSingleton>(new ConfigureNamedOptions(name, instance => BindCoreMain(config, instance, typeof(TOptions), configureOptions))); } #endregion IServiceCollection extensions. @@ -55,16 +55,11 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration private readonly static Lazy> s_configKeys_ProgramMyClass2 = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyInt" }); private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyList2", "MyDictionary" }); - public static void BindCoreMain(IConfiguration configuration, object obj, Type type, Action? configureOptions) + public static void BindCoreMain(IConfiguration configuration, object instance, Type type, Action? configureOptions) { - if (configuration is null) + if (instance is null) { - throw new ArgumentNullException(nameof(configuration)); - } - - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); + return; } if (!HasValueOrChildren(configuration)) @@ -76,7 +71,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { - var temp = (Program.MyClass)obj; + var temp = (Program.MyClass)instance; BindCore(configuration, ref temp, binderOptions); return; } @@ -84,81 +79,81 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj.Add(ParseInt(value, () => section.Path)); + instance.Add(ParseInt(value, () => section.Path)); } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); if (configuration["MyInt"] is string value1) { - obj.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } } - public static void BindCore(IConfiguration configuration, ref List obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { var value = new Program.MyClass2(); BindCore(section, ref value, binderOptions); - obj.Add(value); + instance.Add(value); } } - public static void BindCore(IConfiguration configuration, ref Dictionary obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { if (section.Value is string value) { - obj[section.Key] = value; + instance[section.Key] = value; } } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - obj.MyString = configuration["MyString"]!; + instance.MyString = configuration["MyString"]!; if (configuration["MyInt"] is string value4) { - obj.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) { - List? temp7 = obj.MyList; + List? temp7 = instance.MyList; temp7 ??= new List(); BindCore(section5, ref temp7, binderOptions); - obj.MyList = temp7; + instance.MyList = temp7; } if (AsConfigWithChildren(configuration.GetSection("MyList2")) is IConfigurationSection section8) { - List? temp10 = obj.MyList2; + List? temp10 = instance.MyList2; temp10 ??= new List(); BindCore(section8, ref temp10, binderOptions); - obj.MyList2 = temp10; + instance.MyList2 = temp10; } if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section11) { - Dictionary? temp13 = obj.MyDictionary; + Dictionary? temp13 = instance.MyDictionary; temp13 ??= new Dictionary(); BindCore(section11, ref temp13, binderOptions); - obj.MyDictionary = temp13; + instance.MyDictionary = temp13; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs index 68f8a66612e67f..33a4d04834b57a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs @@ -253,9 +253,9 @@ public class MyClass2 { } Assert.Single(r); string generatedSource = string.Join('\n', r[0].SourceText.Lines.Select(x => x.ToString())); - Assert.Contains("public static void Bind_ProgramMyClass0(this IConfiguration configuration, object? obj)", generatedSource); - Assert.Contains("public static void Bind_ProgramMyClass1(this IConfiguration configuration, object? obj, Action? configureOptions)", generatedSource); - Assert.Contains("public static void Bind_ProgramMyClass2(this IConfiguration configuration, string key, object? obj)", generatedSource); + Assert.Contains("public static void Bind_ProgramMyClass0(this IConfiguration configuration, object? instance)", generatedSource); + Assert.Contains("public static void Bind_ProgramMyClass1(this IConfiguration configuration, object? instance, Action? configureOptions)", generatedSource); + Assert.Contains("public static void Bind_ProgramMyClass2(this IConfiguration configuration, string key, object? instance)", generatedSource); Assert.Empty(d); } diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Common/ConfigurationExtensionsTests.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Common/ConfigurationExtensionsTests.cs index 95cee559072f07..8c76472a2c339b 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Common/ConfigurationExtensionsTests.cs +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/Common/ConfigurationExtensionsTests.cs @@ -12,6 +12,61 @@ public partial class ConfigurationExtensionsTests { private static IConfiguration s_emptyConfig { get; } = new ConfigurationBuilder().Build(); + [Fact] + public void TestNullHandling_OptionsBuilderExt_Bind() + { + // Null options builder. + OptionsBuilder? optionsBuilder = null; + Assert.Throws(() => optionsBuilder!.Bind(s_emptyConfig)); + Assert.Throws(() => optionsBuilder!.Bind(s_emptyConfig, _ => { })); + + // Null configuration. + optionsBuilder = CreateOptionsBuilder(); + Assert.Throws(() => optionsBuilder.Bind(config: null!)); + Assert.Throws(() => optionsBuilder.Bind(config: null!, _ => { })); + + // Null configureBinder. + optionsBuilder.Bind(s_emptyConfig, configureBinder: null); + } + + [Fact] + public void TestNullHandling_OptionsBuilderExt_BindConfiguration() + { + // Null options builder. + string configSectionPath = "FakeSectionPath"; + OptionsBuilder? optionsBuilder = null; + Assert.Throws(() => optionsBuilder!.BindConfiguration(configSectionPath)); + + // Null config section path. + optionsBuilder = CreateOptionsBuilder(); + Assert.Throws(() => optionsBuilder.BindConfiguration(configSectionPath: null!)); + + // Null configureBinder. + optionsBuilder.BindConfiguration(configSectionPath, configureBinder: null); + } + + [Fact] + public void TestNullHandling_IServiceCollectionExt_Configure() + { + // Null services + IServiceCollection? services = null; + string name = "Name"; + Assert.Throws(() => services!.Configure(s_emptyConfig)); + Assert.Throws(() => services!.Configure(name, s_emptyConfig)); + + // Null config. + services = new ServiceCollection(); + Assert.Throws(() => services.Configure(config: null!)); + Assert.Throws(() => services.Configure(name, config: null!)); + + // Null name. + services.Configure(name: null!, s_emptyConfig); + + // Null configureBinder. + services.Configure(s_emptyConfig, configureBinder: null); + services.Configure(name, s_emptyConfig, configureBinder: null); + } + private static OptionsBuilder CreateOptionsBuilder() { var services = new ServiceCollection(); diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/UnitTests/Microsoft.Extensions.Options.ConfigurationExtensions.UnitTests.csproj b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/UnitTests/Microsoft.Extensions.Options.ConfigurationExtensions.UnitTests.csproj index 3a5db72bf30f7d..512e0018a400c0 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/UnitTests/Microsoft.Extensions.Options.ConfigurationExtensions.UnitTests.csproj +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/UnitTests/Microsoft.Extensions.Options.ConfigurationExtensions.UnitTests.csproj @@ -16,10 +16,11 @@ + - + \ No newline at end of file From 9c422ed36a6f68a1940cc737d4a173bafd27467c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 31 Aug 2023 15:26:43 -0700 Subject: [PATCH 121/783] [release/8.0] Fix nullable annotation for Validator.TryValidateValue and ValidateValue (#91293) * Fix nullable annotation for Validator.TryValidateValue and ValidateValue * Revert Options source generator nullable annotation changes for Validator.TryValidateValue (#91305) * Fix nullable annotation for Validator.ValidateValue ref source (#91351) --------- Co-authored-by: Jeff Handley --- .../ref/System.ComponentModel.Annotations.cs | 4 ++-- .../System/ComponentModel/DataAnnotations/Validator.cs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs b/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs index 542845070d0c38..c9e82b8cece0c7 100644 --- a/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs +++ b/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs @@ -387,14 +387,14 @@ public static partial class Validator public static bool TryValidateObject(object instance, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.ICollection? validationResults, bool validateAllProperties) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The Type of validationContext.ObjectType cannot be statically discovered.")] public static bool TryValidateProperty(object? value, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.ICollection? validationResults) { throw null; } - public static bool TryValidateValue(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.ICollection? validationResults, System.Collections.Generic.IEnumerable validationAttributes) { throw null; } + public static bool TryValidateValue(object? value, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.ICollection? validationResults, System.Collections.Generic.IEnumerable validationAttributes) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The Type of instance cannot be statically discovered and the Type's properties can be trimmed.")] public static void ValidateObject(object instance, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The Type of instance cannot be statically discovered and the Type's properties can be trimmed.")] public static void ValidateObject(object instance, System.ComponentModel.DataAnnotations.ValidationContext validationContext, bool validateAllProperties) { } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The Type of validationContext.ObjectType cannot be statically discovered.")] public static void ValidateProperty(object? value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) { } - public static void ValidateValue(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.IEnumerable validationAttributes) { } + public static void ValidateValue(object? value, System.ComponentModel.DataAnnotations.ValidationContext validationContext, System.Collections.Generic.IEnumerable validationAttributes) { } } } namespace System.ComponentModel.DataAnnotations.Schema diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Validator.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Validator.cs index 3913a1df4c3fe7..d6719673011117 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Validator.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/Validator.cs @@ -171,7 +171,7 @@ public static bool TryValidateObject(object instance, ValidationContext validati /// then all validators will be evaluated. /// /// - /// The value to test. It cannot be null. + /// The value to test. /// /// Describes the object being validated and provides services and context for the /// validators. @@ -182,7 +182,7 @@ public static bool TryValidateObject(object instance, ValidationContext validati /// against. /// /// true if the object is valid, false if any validation errors are encountered. - public static bool TryValidateValue(object value, ValidationContext validationContext, + public static bool TryValidateValue(object? value, ValidationContext validationContext, ICollection? validationResults, IEnumerable validationAttributes) { ArgumentNullException.ThrowIfNull(validationAttributes); @@ -303,12 +303,12 @@ public static void ValidateObject(object instance, ValidationContext validationC /// first. /// /// - /// The value to test. It cannot be null. + /// The value to test. /// Describes the object being tested. /// The list of s to validate against this instance. /// When is null. /// When is found to be invalid. - public static void ValidateValue(object value, ValidationContext validationContext, + public static void ValidateValue(object? value, ValidationContext validationContext, IEnumerable validationAttributes) { ArgumentNullException.ThrowIfNull(validationContext); From 399f37c6812f71066d944c5319164126def16204 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 31 Aug 2023 15:27:06 -0700 Subject: [PATCH 122/783] [release/8.0] [DependencyInjection] introduce feature switch to disable S.R.E (#91352) * [DependencyInjection] introduce feature switch to disable S.R.E When recording a new AOT profile for .NET MAUI apps running on Android, we noticed that System.Reflection.Emit work was being done on a background thread. The call seen in `dotnet-trace` output: 11.32ms microsoft.extensions.dependencyinjection!Microsoft.Extensions.DependencyInjection.ServiceLookup.ILEmitResolverBuilder.GenerateMethodBody(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite,System.Reflection.Emit.ILGenerator) .NET Android apps are unique in that there is a JIT, `RuntimeFeature.IsDynamicCodeCompiled` is true, System.Reflection.Emit is possible -- S.R.E is however, not great for startup performance. Starting threads on Android during startup can also be slow, as Android will commonly put all but a single core to sleep for battery saving purposes. We try to avoid starting threads on startup for "hello world" applications on Android. To solve this for now, introduce a new feature flag: Microsoft.Extensions.DependencyInjection.DisableDynamicEngine Which, we will provide a value in either the Android or .NET MAUI optional workload via an MSBuild property. To test, I put this in my app's `.csproj` file: Customers *could* opt to change this flag, but we don't think it will particularly useful. An example of services realized by .NET MAUI at startup, via some logging added: 08-25 13:21:55.647 16530 16530 I DOTNET : RealizeService called: System.Collections.Generic.IEnumerable`1[Microsoft.Maui.Hosting.IMauiInitializeService] 08-25 13:21:55.664 16530 16530 I DOTNET : RealizeService called: System.Collections.Generic.IEnumerable`1[Microsoft.Maui.Hosting.IMauiInitializeScopedService] 08-25 13:21:55.665 16530 16530 I DOTNET : RealizeService called: Microsoft.Maui.Dispatching.IDispatcher 08-25 13:21:55.668 16530 16530 I DOTNET : RealizeService called: System.Collections.Generic.IEnumerable`1[Microsoft.Maui.LifecycleEvents.LifecycleEventRegistration] 08-25 13:21:56.057 16530 16530 I DOTNET : RealizeService called: System.Collections.Generic.IEnumerable`1[Microsoft.Maui.Hosting.HandlerMauiAppBuilderExtensions+HandlerRegistration] 08-25 13:21:56.115 16530 16530 I DOTNET : RealizeService called: Microsoft.Extensions.DependencyInjection.IServiceScopeFactory 08-25 13:21:56.670 16530 16530 I DOTNET : RealizeService called: Microsoft.Maui.Controls.HideSoftInputOnTappedChangedManager 08-25 13:21:56.712 16530 16530 I DOTNET : RealizeService called: System.Collections.Generic.IEnumerable`1[Microsoft.Maui.Hosting.ImageSourcesMauiAppBuilderExtensions+ImageSourceRegistration] 08-25 13:21:57.700 16530 16530 I DOTNET : RealizeService using S.R.E: Microsoft.Maui.Controls.HideSoftInputOnTappedChangedManager `HideSoftInputOnTappedChangedManager` would be realized once per page, which would not be a huge payoff to use S.R.E for. So the only way the S.R.E codepath could be useful on Android would be if the customer is registering lots of services themselves. They might be better off just using `new()` in that case? An example of the startup time Android reports with the new flag on/off: DisableDynamicEngine=false 08-25 14:31:37.462 2090 2330 I ActivityTaskManager: Displayed com.companyname.testmaui/crc643c09abdeec717b83.MainActivity: +733ms 08-25 14:31:39.394 2090 2330 I ActivityTaskManager: Displayed com.companyname.testmaui/crc643c09abdeec717b83.MainActivity: +737ms 08-25 14:31:41.326 2090 2330 I ActivityTaskManager: Displayed com.companyname.testmaui/crc643c09abdeec717b83.MainActivity: +730ms DisableDynamicEngine=true 08-25 14:32:20.233 2090 2330 I ActivityTaskManager: Displayed com.companyname.testmaui/crc643c09abdeec717b83.MainActivity: +724ms 08-25 14:32:22.137 2090 2330 I ActivityTaskManager: Displayed com.companyname.testmaui/crc643c09abdeec717b83.MainActivity: +727ms 08-25 14:32:24.042 2090 2330 I ActivityTaskManager: Displayed com.companyname.testmaui/crc643c09abdeec717b83.MainActivity: +716ms This was a `dotnet new maui` project, using dotnet/maui/main on a Pixel 5 device. * Update docs/workflow/trimming/feature-switches.md Co-authored-by: Eric Erhardt --------- Co-authored-by: Jonathan Peppers Co-authored-by: Jonathan Peppers Co-authored-by: Eric Erhardt --- docs/workflow/trimming/feature-switches.md | 1 + .../src/ILLink/ILLink.Substitutions.xml | 3 +++ .../src/ServiceProvider.cs | 5 ++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/workflow/trimming/feature-switches.md b/docs/workflow/trimming/feature-switches.md index 87d8fa4c5ec425..7fa3045547e0f0 100644 --- a/docs/workflow/trimming/feature-switches.md +++ b/docs/workflow/trimming/feature-switches.md @@ -27,6 +27,7 @@ configurations but their defaults might vary as any SDK can set the defaults dif | MetadataUpdaterSupport | System.Reflection.Metadata.MetadataUpdater.IsSupported | Metadata update related code to be trimmed when set to false | | _EnableConsumingManagedCodeFromNativeHosting | System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting | Getting a managed function from native hosting is disabled when set to false and related functionality can be trimmed. | | VerifyDependencyInjectionOpenGenericServiceTrimmability | Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability | When set to true, DependencyInjection will verify trimming annotations applied to open generic services are correct | +| DisableDependencyInjectionDynamicEngine | Microsoft.Extensions.DependencyInjection.DisableDynamicEngine | When set to true, DependencyInjection will avoid using System.Reflection.Emit when realizing services | | NullabilityInfoContextSupport | System.Reflection.NullabilityInfoContext.IsSupported | Nullable attributes can be trimmed when set to false | | DynamicCodeSupport | System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported | Changes RuntimeFeature.IsDynamicCodeSupported to false to allow testing AOT-safe fallback code without publishing for Native AOT. | | _AggressiveAttributeTrimming | System.AggressiveAttributeTrimming | When set to true, aggressively trims attributes to allow for the most size savings possible, even if it could result in runtime behavior changes | diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ILLink/ILLink.Substitutions.xml b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ILLink/ILLink.Substitutions.xml index eb381de19d6153..6aa354ee23683c 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ILLink/ILLink.Substitutions.xml +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ILLink/ILLink.Substitutions.xml @@ -3,5 +3,8 @@ + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs index aa178741fc4516..ff5efbe98cf334 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs @@ -37,6 +37,9 @@ public sealed class ServiceProvider : IServiceProvider, IKeyedServiceProvider, I internal static bool VerifyOpenGenericServiceTrimmability { get; } = AppContext.TryGetSwitch("Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability", out bool verifyOpenGenerics) ? verifyOpenGenerics : false; + internal static bool DisableDynamicEngine { get; } = + AppContext.TryGetSwitch("Microsoft.Extensions.DependencyInjection.DisableDynamicEngine", out bool disableDynamicEngine) ? disableDynamicEngine : false; + internal static bool VerifyAotCompatibility => #if NETFRAMEWORK || NETSTANDARD2_0 false; @@ -246,7 +249,7 @@ private ServiceProviderEngine GetEngine() #if NETFRAMEWORK || NETSTANDARD2_0 engine = CreateDynamicEngine(); #else - if (RuntimeFeature.IsDynamicCodeCompiled) + if (RuntimeFeature.IsDynamicCodeCompiled && !DisableDynamicEngine) { engine = CreateDynamicEngine(); } From cd8b2cb89f51c6e780e868f27fe0fd8ef43454d9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 12:24:29 -0600 Subject: [PATCH 123/783] [release/8.0] [Mono] Fix offset calculation for nested struct, when pinvoke is enabled (#91417) * Fix offset calculation for nested struct * Add a test for nested struct with pinvoke * Move and update test with real c++ implementation * Exclude newly added test from wasm * Disable interop tests on android and apple devices --------- Co-authored-by: Fan Yang --- src/mono/mono/mini/mini-amd64.c | 4 +- .../PInvoke/GameControllerButtonBind.cs | 63 +++++++++++++++++++ .../PInvoke/MarshalStructAsParamDLL.cpp | 5 ++ .../PInvoke/MarshalStructAsParamDLL.h | 23 +++++++ .../StructMarshalling/PInvoke/NestedStruct.cs | 27 ++++++++ .../PInvoke/NestedStruct.csproj | 14 +++++ src/tests/issues.targets | 12 ++++ 7 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 src/tests/Interop/StructMarshalling/PInvoke/GameControllerButtonBind.cs create mode 100644 src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.cs create mode 100644 src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.csproj diff --git a/src/mono/mono/mini/mini-amd64.c b/src/mono/mono/mini/mini-amd64.c index 1a2f9fff59d34e..e03b142feef1f3 100644 --- a/src/mono/mono/mini/mini-amd64.c +++ b/src/mono/mono/mini/mini-amd64.c @@ -357,7 +357,7 @@ collect_field_info_nested (MonoClass *klass, GArray *fields_array, int offset, g g_assert(info); for (guint32 i = 0; i < info->num_fields; ++i) { if (MONO_TYPE_ISSTRUCT (info->fields [i].field->type)) { - collect_field_info_nested (mono_class_from_mono_type_internal (info->fields [i].field->type), fields_array, info->fields [i].offset, pinvoke, unicode); + collect_field_info_nested (mono_class_from_mono_type_internal (info->fields [i].field->type), fields_array, (offset + info->fields [i].offset), pinvoke, unicode); } else { guint32 align; StructFieldInfo f; @@ -367,7 +367,7 @@ collect_field_info_nested (MonoClass *klass, GArray *fields_array, int offset, g info->fields [i].mspec, &align, TRUE, unicode); f.offset = offset + info->fields [i].offset; - if (i == info->num_fields - 1 && f.size + f.offset < info->native_size) { + if ((i == info->num_fields - 1) && ((f.size + f.offset) < info->native_size)) { /* This can happen with .pack directives eg. 'fixed' arrays */ if (MONO_TYPE_IS_PRIMITIVE (f.type)) { /* Replicate the last field to fill out the remaining place, since the code in add_valuetype () needs type information */ diff --git a/src/tests/Interop/StructMarshalling/PInvoke/GameControllerButtonBind.cs b/src/tests/Interop/StructMarshalling/PInvoke/GameControllerButtonBind.cs new file mode 100644 index 00000000000000..a65994f2307a3f --- /dev/null +++ b/src/tests/Interop/StructMarshalling/PInvoke/GameControllerButtonBind.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using System.Text; + +public unsafe partial struct GameControllerButtonBind +{ + public GameControllerButtonBind + ( + GameControllerBindType? bindType = null, + GameControllerButtonBindValue? value = null + ) : this() + { + if (bindType is not null) + { + BindType = bindType.Value; + } + + if (value is not null) + { + Value = value.Value; + } + } + + public GameControllerBindType BindType; + + public GameControllerButtonBindValue Value; +} + +public enum GameControllerBindType : int +{ + ControllerBindtypeNone = 0x0, + ControllerBindtypeButton = 0x1, + ControllerBindtypeAxis = 0x2, + ControllerBindtypeHat = 0x3, + None = 0x0, + Button = 0x1, + Axis = 0x2, + Hat = 0x3, +} + +[StructLayout(LayoutKind.Explicit)] +public unsafe partial struct GameControllerButtonBindValue +{ + [FieldOffset(0)] + public int Button; + + [FieldOffset(0)] + public int Axis; + + [FieldOffset(0)] + public GameControllerButtonBindValueHat Hat; +} + +public unsafe partial struct GameControllerButtonBindValueHat +{ + public int Hat; + + public int HatMask; +} diff --git a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp index 9278650d20dce8..e19eec7feb0737 100644 --- a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp +++ b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp @@ -1297,3 +1297,8 @@ extern "C" DLL_EXPORT Int32CLongStruct STDMETHODCALLTYPE AddCLongs(Int32CLongStr { return { lhs.i + rhs.i, lhs.l + rhs.l }; } + +extern "C" DLL_EXPORT SDL_GameControllerBindType STDMETHODCALLTYPE getBindType(SDL_GameControllerButtonBind button) +{ + return button.bindType; +} diff --git a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h index c85b1e6f62dc05..17844b8c365263 100644 --- a/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h +++ b/src/tests/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h @@ -974,3 +974,26 @@ struct Int32CLongStruct int32_t i; long l; }; + +typedef enum +{ + SDL_CONTROLLER_BINDTYPE_NONE = 0, + SDL_CONTROLLER_BINDTYPE_BUTTON, + SDL_CONTROLLER_BINDTYPE_AXIS, + SDL_CONTROLLER_BINDTYPE_HAT +} SDL_GameControllerBindType; + +typedef struct SDL_GameControllerButtonBind +{ + SDL_GameControllerBindType bindType; + union + { + int button; + int axis; + struct { + int hat; + int hat_mask; + } hat; + } value; + +} SDL_GameControllerButtonBind; diff --git a/src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.cs b/src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.cs new file mode 100644 index 00000000000000..870e75bff62525 --- /dev/null +++ b/src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using Xunit; + +public class Managed +{ + [DllImport("MarshalStructAsParam")] + static extern GameControllerBindType getBindType (GameControllerButtonBind button); + + public static int Main() + { + GameControllerButtonBind button = new GameControllerButtonBind(GameControllerBindType.ControllerBindtypeAxis, null); + if (getBindType(button) == GameControllerBindType.ControllerBindtypeAxis) + { + Console.WriteLine("\nTEST PASSED!"); + return 100; + } + else + { + Console.WriteLine("\nTEST FAILED!"); + return 1; + } + } +} diff --git a/src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.csproj b/src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.csproj new file mode 100644 index 00000000000000..0b0d4aa0836435 --- /dev/null +++ b/src/tests/Interop/StructMarshalling/PInvoke/NestedStruct.csproj @@ -0,0 +1,14 @@ + + + exe + true + + + + + + + + + + diff --git a/src/tests/issues.targets b/src/tests/issues.targets index e9485d290e2d5d..7ec7dc726f34ef 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -2939,6 +2939,9 @@ https://github.com/dotnet/runtime/issues/64127 + + https://github.com/dotnet/runtime/issues/64127 + https://github.com/dotnet/runtime/issues/64127 @@ -3492,6 +3495,15 @@ https://github.com/dotnet/runtime/issues/67359 + + https://github.com/dotnet/runtime/issues/91388 + + + https://github.com/dotnet/runtime/issues/91388 + + + https://github.com/dotnet/runtime/issues/91388 + From ee2405677e1eb5c91d46cd58d2aa04b9506e2296 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 12:30:15 -0600 Subject: [PATCH 124/783] [release/8.0] Options Source Gen Fixes (#91432) * Options Source Gen Fixes * Remove unnecessary interpolated string usage * Address the feedback * Remove repeated word in the comment --------- Co-authored-by: Tarek Mahmoud Sayed --- .../gen/Emitter.cs | 85 ++- ...Extensions.Options.SourceGeneration.csproj | 1 + .../gen/Parser.cs | 7 + .../gen/SymbolHolder.cs | 5 +- .../gen/SymbolLoader.cs | 27 +- .../tests/SourceGeneration.Unit.Tests/Main.cs | 17 +- .../OptionsRuntimeTests.cs | 45 +- .../Baselines/NetCoreApp/Validators.g.cs | 658 ++++++++---------- .../Baselines/NetFX/Validators.g.cs | 658 ++++++++---------- 9 files changed, 740 insertions(+), 763 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs b/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs index adbaa874ad7f37..9e0cb659a6c94a 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs @@ -3,10 +3,12 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.DotnetRuntime.Extensions; namespace Microsoft.Extensions.Options.Generators { @@ -25,6 +27,7 @@ internal sealed class Emitter : EmitterBase private string _staticValidationAttributeHolderClassFQN; private string _staticValidatorHolderClassFQN; private string _modifier; + private string _TryGetValueNullableAnnotation; private sealed record StaticFieldInfo(string FieldTypeFQN, int FieldOrder, string FieldName, IList InstantiationLines); @@ -37,13 +40,14 @@ public Emitter(Compilation compilation, bool emitPreamble = true) : base(emitPre else { _modifier = "internal"; - string suffix = $"_{new Random().Next():X8}"; + string suffix = $"_{GetNonRandomizedHashCode(compilation.SourceModule.Name):X8}"; _staticValidationAttributeHolderClassName += suffix; _staticValidatorHolderClassName += suffix; } _staticValidationAttributeHolderClassFQN = $"global::{StaticFieldHolderClassesNamespace}.{_staticValidationAttributeHolderClassName}"; _staticValidatorHolderClassFQN = $"global::{StaticFieldHolderClassesNamespace}.{_staticValidatorHolderClassName}"; + _TryGetValueNullableAnnotation = GetNullableAnnotationStringForTryValidateValueToUseInGeneratedCode(compilation); } public string Emit( @@ -65,6 +69,31 @@ public string Emit( return Capture(); } + /// + /// Returns the nullable annotation string to use in the code generation according to the first parameter of + /// is nullable annotated. + /// + /// The to consider for analysis. + /// "!" if the first parameter is not nullable annotated, otherwise an empty string. + /// + /// In .NET 8.0 we have changed the nullable annotation on first parameter of the method cref="System.ComponentModel.DataAnnotations.Validator.TryValidateValue(object, ValidationContext, ICollection{ValidationResult}, IEnumerable{ValidationAttribute})"/> + /// The source generator need to detect if we need to append "!" to the first parameter of the method call when running on down-level versions. + /// + private static string GetNullableAnnotationStringForTryValidateValueToUseInGeneratedCode(Compilation compilation) + { + INamedTypeSymbol? validatorTypeSymbol = compilation.GetBestTypeByMetadataName("System.ComponentModel.DataAnnotations.Validator"); + if (validatorTypeSymbol is not null) + { + ImmutableArray members = validatorTypeSymbol.GetMembers("TryValidateValue"); + if (members.Length == 1 && members[0] is IMethodSymbol tryValidateValueMethod) + { + return tryValidateValueMethod.Parameters[0].NullableAnnotation == NullableAnnotation.NotAnnotated ? "!" : string.Empty; + } + } + + return "!"; + } + private void GenValidatorType(ValidatorType vt, ref Dictionary staticValidationAttributesDict, ref Dictionary staticValidatorsDict) { if (vt.Namespace.Length > 0) @@ -161,7 +190,7 @@ private void GenModelSelfValidationIfNecessary(ValidatedModel modelToValidate) { if (modelToValidate.SelfValidates) { - OutLn($"builder.AddResults(((global::System.ComponentModel.DataAnnotations.IValidatableObject)options).Validate(context));"); + OutLn($"(builder ??= new()).AddResults(((global::System.ComponentModel.DataAnnotations.IValidatableObject)options).Validate(context));"); OutLn(); } } @@ -182,8 +211,7 @@ private void GenModelValidationMethod( OutLn($"public {(makeStatic ? "static " : string.Empty)}global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, {modelToValidate.Name} options)"); OutOpenBrace(); - OutLn($"var baseName = (string.IsNullOrEmpty(name) ? \"{modelToValidate.SimpleName}\" : name) + \".\";"); - OutLn($"var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder();"); + OutLn($"global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null;"); OutLn($"var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options);"); int capacity = modelToValidate.MembersToValidate.Max(static vm => vm.ValidationAttributes.Count); @@ -199,33 +227,33 @@ private void GenModelValidationMethod( { if (vm.ValidationAttributes.Count > 0) { - GenMemberValidation(vm, ref staticValidationAttributesDict, cleanListsBeforeUse); + GenMemberValidation(vm, modelToValidate.SimpleName, ref staticValidationAttributesDict, cleanListsBeforeUse); cleanListsBeforeUse = true; OutLn(); } if (vm.TransValidatorType is not null) { - GenTransitiveValidation(vm, ref staticValidatorsDict); + GenTransitiveValidation(vm, modelToValidate.SimpleName, ref staticValidatorsDict); OutLn(); } if (vm.EnumerationValidatorType is not null) { - GenEnumerationValidation(vm, ref staticValidatorsDict); + GenEnumerationValidation(vm, modelToValidate.SimpleName, ref staticValidatorsDict); OutLn(); } } GenModelSelfValidationIfNecessary(modelToValidate); - OutLn($"return builder.Build();"); + OutLn($"return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build();"); OutCloseBrace(); } - private void GenMemberValidation(ValidatedMember vm, ref Dictionary staticValidationAttributesDict, bool cleanListsBeforeUse) + private void GenMemberValidation(ValidatedMember vm, string modelName, ref Dictionary staticValidationAttributesDict, bool cleanListsBeforeUse) { OutLn($"context.MemberName = \"{vm.Name}\";"); - OutLn($"context.DisplayName = baseName + \"{vm.Name}\";"); + OutLn($"context.DisplayName = string.IsNullOrEmpty(name) ? \"{modelName}.{vm.Name}\" : $\"{{name}}.{vm.Name}\";"); if (cleanListsBeforeUse) { @@ -239,9 +267,9 @@ private void GenMemberValidation(ValidatedMember vm, ref Dictionary staticValidatorsDict) + private void GenTransitiveValidation(ValidatedMember vm, string modelName, ref Dictionary staticValidatorsDict) { string callSequence; if (vm.TransValidateTypeIsSynthetic) @@ -321,20 +349,22 @@ private void GenTransitiveValidation(ValidatedMember vm, ref Dictionary staticValidatorsDict) + private void GenEnumerationValidation(ValidatedMember vm, string modelName, ref Dictionary staticValidatorsDict) { var valueAccess = (vm.IsValueType && vm.IsNullable) ? ".Value" : string.Empty; var enumeratedValueAccess = (vm.EnumeratedIsNullable && vm.EnumeratedIsValueType) ? ".Value" : string.Empty; @@ -365,14 +395,16 @@ private void GenEnumerationValidation(ValidatedMember vm, ref Dictionary + /// Returns a non-randomized hash code for the given string. + /// We always return a positive value. + /// + internal static int GetNonRandomizedHashCode(string s) + { + uint result = 2166136261u; + foreach (char c in s) + { + result = (c ^ result) * 16777619; + } + return Math.Abs((int)result); + } } } diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Microsoft.Extensions.Options.SourceGeneration.csproj b/src/libraries/Microsoft.Extensions.Options/gen/Microsoft.Extensions.Options.SourceGeneration.csproj index 41ceaf6739c333..5571341b06060e 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Microsoft.Extensions.Options.SourceGeneration.csproj +++ b/src/libraries/Microsoft.Extensions.Options/gen/Microsoft.Extensions.Options.SourceGeneration.csproj @@ -20,6 +20,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs b/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs index 0c8e216e488c7f..1ecd82cbe74c07 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs @@ -240,6 +240,13 @@ private static bool HasOpenGenerics(ITypeSymbol type, out string genericType) type = ((INamedTypeSymbol)type).TypeArguments[0]; } + // Check first if the type is IEnumerable interface + if (SymbolEqualityComparer.Default.Equals(type.OriginalDefinition, _symbolHolder.GenericIEnumerableSymbol)) + { + return ((INamedTypeSymbol)type).TypeArguments[0]; + } + + // Check first if the type implement IEnumerable interface foreach (var implementingInterface in type.AllInterfaces) { if (SymbolEqualityComparer.Default.Equals(implementingInterface.OriginalDefinition, _compilation.GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T))) diff --git a/src/libraries/Microsoft.Extensions.Options/gen/SymbolHolder.cs b/src/libraries/Microsoft.Extensions.Options/gen/SymbolHolder.cs index c78106e1bc4a27..55d382e4036219 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/SymbolHolder.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/SymbolHolder.cs @@ -14,7 +14,8 @@ internal sealed record class SymbolHolder( INamedTypeSymbol DataTypeAttributeSymbol, INamedTypeSymbol ValidateOptionsSymbol, INamedTypeSymbol IValidatableObjectSymbol, + INamedTypeSymbol GenericIEnumerableSymbol, INamedTypeSymbol TypeSymbol, - INamedTypeSymbol? ValidateObjectMembersAttributeSymbol, - INamedTypeSymbol? ValidateEnumeratedItemsAttributeSymbol); + INamedTypeSymbol ValidateObjectMembersAttributeSymbol, + INamedTypeSymbol ValidateEnumeratedItemsAttributeSymbol); } diff --git a/src/libraries/Microsoft.Extensions.Options/gen/SymbolLoader.cs b/src/libraries/Microsoft.Extensions.Options/gen/SymbolLoader.cs index 6f805e91a05858..94035cedacbf98 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/SymbolLoader.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/SymbolLoader.cs @@ -15,19 +15,11 @@ internal static class SymbolLoader internal const string TypeOfType = "System.Type"; internal const string ValidateObjectMembersAttribute = "Microsoft.Extensions.Options.ValidateObjectMembersAttribute"; internal const string ValidateEnumeratedItemsAttribute = "Microsoft.Extensions.Options.ValidateEnumeratedItemsAttribute"; + internal const string GenericIEnumerableType = "System.Collections.Generic.IEnumerable`1"; public static bool TryLoad(Compilation compilation, out SymbolHolder? symbolHolder) { - INamedTypeSymbol? GetSymbol(string metadataName, bool optional = false) - { - var symbol = compilation.GetTypeByMetadataName(metadataName); - if (symbol == null && !optional) - { - return null; - } - - return symbol; - } + INamedTypeSymbol? GetSymbol(string metadataName) => compilation.GetTypeByMetadataName(metadataName); // required var optionsValidatorSymbol = GetSymbol(OptionsValidatorAttribute); @@ -35,7 +27,10 @@ public static bool TryLoad(Compilation compilation, out SymbolHolder? symbolHold var dataTypeAttributeSymbol = GetSymbol(DataTypeAttribute); var ivalidatableObjectSymbol = GetSymbol(IValidatableObjectType); var validateOptionsSymbol = GetSymbol(IValidateOptionsType); + var genericIEnumerableSymbol = GetSymbol(GenericIEnumerableType); var typeSymbol = GetSymbol(TypeOfType); + var validateObjectMembersAttribute = GetSymbol(ValidateObjectMembersAttribute); + var validateEnumeratedItemsAttribute = GetSymbol(ValidateEnumeratedItemsAttribute); #pragma warning disable S1067 // Expressions should not be too complex if (optionsValidatorSymbol == null || @@ -43,7 +38,10 @@ public static bool TryLoad(Compilation compilation, out SymbolHolder? symbolHold dataTypeAttributeSymbol == null || ivalidatableObjectSymbol == null || validateOptionsSymbol == null || - typeSymbol == null) + genericIEnumerableSymbol == null || + typeSymbol == null || + validateObjectMembersAttribute == null || + validateEnumeratedItemsAttribute == null) { symbolHolder = default; return false; @@ -56,11 +54,10 @@ public static bool TryLoad(Compilation compilation, out SymbolHolder? symbolHold dataTypeAttributeSymbol, validateOptionsSymbol, ivalidatableObjectSymbol, + genericIEnumerableSymbol, typeSymbol, - - // optional - GetSymbol(ValidateObjectMembersAttribute, optional: true), - GetSymbol(ValidateEnumeratedItemsAttribute, optional: true)); + validateObjectMembersAttribute, + validateEnumeratedItemsAttribute); return true; } diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs index f3e0513a885f22..ca0db51c121024 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs @@ -70,31 +70,30 @@ partial struct MyOptionsValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::HelloWorld.MyOptions options) { - var baseName = (string.IsNullOrEmpty(name) ? "MyOptions" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val1"; - context.DisplayName = baseName + "Val1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.Val1" : $"{name}.Val1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val2"; - context.DisplayName = baseName + "Val2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.Val2" : $"{name}.Val2"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs index 1ac4618014ba92..9a5de0e759f8a6 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs @@ -25,10 +25,15 @@ public void TestValidationSuccessResults() { Tall = 10, Id = "1", - Children = new() + Children1 = new() { - new ChildOptions() { Name = "C1" }, - new ChildOptions() { Name = "C2" } + new ChildOptions() { Name = "C1-1" }, + new ChildOptions() { Name = "C1-2" } + }, + Children2 = new List() + { + new ChildOptions() { Name = "C2-1" }, + new ChildOptions() { Name = "C2-2" } }, NestedList = new() { @@ -126,12 +131,19 @@ public void TestValidationWithEnumeration() { Tall = 10, Id = "1", - Children = new() + Children1 = new() { new ChildOptions(), new ChildOptions(), new ChildOptions() - } + }, + Children2 = new List() + { + new ChildOptions(), + new ChildOptions(), + new ChildOptions() + }, + } }; @@ -142,9 +154,12 @@ public void TestValidationWithEnumeration() Assert.True(result1.Failed); Assert.Equal(new List { - "Name: The MyOptions.Nested.Children[0].Name field is required.", - "Name: The MyOptions.Nested.Children[1].Name field is required.", - "Name: The MyOptions.Nested.Children[2].Name field is required.", + "Name: The MyOptions.Nested.Children1[0].Name field is required.", + "Name: The MyOptions.Nested.Children1[1].Name field is required.", + "Name: The MyOptions.Nested.Children1[2].Name field is required.", + "Name: The MyOptions.Nested.Children2[0].Name field is required.", + "Name: The MyOptions.Nested.Children2[1].Name field is required.", + "Name: The MyOptions.Nested.Children2[2].Name field is required.", }, result1.Failures); @@ -152,9 +167,12 @@ public void TestValidationWithEnumeration() Assert.True(result2.Failed); Assert.Equal(new List { - "DataAnnotation validation failed for 'MyOptions.Nested.Children[0]' members: 'Name' with the error: 'The Name field is required.'.", - "DataAnnotation validation failed for 'MyOptions.Nested.Children[1]' members: 'Name' with the error: 'The Name field is required.'.", - "DataAnnotation validation failed for 'MyOptions.Nested.Children[2]' members: 'Name' with the error: 'The Name field is required.'.", + "DataAnnotation validation failed for 'MyOptions.Nested.Children1[0]' members: 'Name' with the error: 'The Name field is required.'.", + "DataAnnotation validation failed for 'MyOptions.Nested.Children1[1]' members: 'Name' with the error: 'The Name field is required.'.", + "DataAnnotation validation failed for 'MyOptions.Nested.Children1[2]' members: 'Name' with the error: 'The Name field is required.'.", + "DataAnnotation validation failed for 'MyOptions.Nested.Children2[0]' members: 'Name' with the error: 'The Name field is required.'.", + "DataAnnotation validation failed for 'MyOptions.Nested.Children2[1]' members: 'Name' with the error: 'The Name field is required.'.", + "DataAnnotation validation failed for 'MyOptions.Nested.Children2[2]' members: 'Name' with the error: 'The Name field is required.'.", }, result2.Failures); } @@ -219,7 +237,10 @@ public class NestedOptions public string? Id { get; set; } [ValidateEnumeratedItems] - public List? Children { get; set; } + public List? Children1 { get; set; } + + [ValidateEnumeratedItems] + public IEnumerable? Children2 { get; set; } #pragma warning disable SYSLIB1211 // Source gen does static analysis for circular reference. We need to disable it for this test. [ValidateEnumeratedItems] diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs index a467ed2dd6c007..cc1ebda6414e6b 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs @@ -14,22 +14,21 @@ internal sealed partial class __ThirdModelNoNamespaceValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::ThirdModelNoNamespace options) { - var baseName = (string.IsNullOrEmpty(name) ? "ThirdModelNoNamespace" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "ThirdModelNoNamespace.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } partial class FirstValidatorNoNamespace @@ -43,32 +42,31 @@ partial class FirstValidatorNoNamespace [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::FirstModelNoNamespace options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModelNoNamespace" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModelNoNamespace.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P2 is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V1.Validate(baseName + "P2", options.P2)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V1.Validate(string.IsNullOrEmpty(name) ? "FirstModelNoNamespace.P2" : $"{name}.P2", options.P2)); } if (options.P3 is not null) { - builder.AddResult(global::__ThirdModelNoNamespaceValidator__.Validate(baseName + "P3", options.P3)); + (builder ??= new()).AddResult(global::__ThirdModelNoNamespaceValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModelNoNamespace.P3" : $"{name}.P3", options.P3)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } partial class SecondValidatorNoNamespace @@ -82,22 +80,21 @@ partial class SecondValidatorNoNamespace [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::SecondModelNoNamespace options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModelNoNamespace" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P4"; - context.DisplayName = baseName + "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModelNoNamespace.P4" : $"{name}.P4"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } namespace CustomAttr @@ -113,31 +110,30 @@ partial class FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::CustomAttr.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "P2"; - context.DisplayName = baseName + "P2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A4); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -155,22 +151,21 @@ internal sealed partial class __SecondModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Enumeration.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P6"; - context.DisplayName = baseName + "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P6" : $"{name}.P6"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -188,21 +183,20 @@ internal sealed partial class __ThirdModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Enumeration.ThirdModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "ThirdModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Value"; - context.DisplayName = baseName + "Value"; + context.DisplayName = string.IsNullOrEmpty(name) ? "ThirdModel.Value" : $"{name}.Value"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A5); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Value!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Value, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -219,8 +213,7 @@ partial struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Enumeration.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); if (options.P1 is not null) @@ -230,11 +223,11 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__SecondModelValidator__.Validate(baseName + $"P1[{count}]", o)); + (builder ??= new()).AddResult(global::Enumeration.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P1[{count}]" : $"{name}.P1[{count}]", o)); } else { - builder.AddError(baseName + $"P1[{count}] is null"); + (builder ??= new()).AddError(string.IsNullOrEmpty(name) ? $"FirstModel.P1[{count}] is null" : $"{name}.P1[{count}] is null"); } count++; } @@ -247,11 +240,11 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V2.Validate(baseName + $"P2[{count}]", o)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V2.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P2[{count}]" : $"{name}.P2[{count}]", o)); } else { - builder.AddError(baseName + $"P2[{count}] is null"); + (builder ??= new()).AddError(string.IsNullOrEmpty(name) ? $"FirstModel.P2[{count}] is null" : $"{name}.P2[{count}] is null"); } count++; } @@ -264,7 +257,7 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__SecondModelValidator__.Validate(baseName + $"P3[{count}]", o)); + (builder ??= new()).AddResult(global::Enumeration.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P3[{count}]" : $"{name}.P3[{count}]", o)); } count++; } @@ -275,7 +268,7 @@ partial struct FirstValidator var count = 0; foreach (var o in options.P4) { - builder.AddResult(global::Enumeration.__ThirdModelValidator__.Validate(baseName + $"P4[{count++}]", o)); + (builder ??= new()).AddResult(global::Enumeration.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P4[{count++}] is null" : $"{name}.P4[{count++}] is null", o)); } } @@ -286,7 +279,7 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__ThirdModelValidator__.Validate(baseName + $"P5[{count}]", o.Value)); + (builder ??= new()).AddResult(global::Enumeration.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P5[{count}]" : $"{name}.P5[{count}]", o.Value)); } count++; } @@ -299,7 +292,7 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__ThirdModelValidator__.Validate(baseName + $"P51[{count}]", o.Value)); + (builder ??= new()).AddResult(global::Enumeration.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P51[{count}]" : $"{name}.P51[{count}]", o.Value)); } count++; } @@ -312,11 +305,11 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__SecondModelValidator__.Validate(baseName + $"P6[{count}]", o)); + (builder ??= new()).AddResult(global::Enumeration.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P6[{count}]" : $"{name}.P6[{count}]", o)); } else { - builder.AddError(baseName + $"P6[{count}] is null"); + (builder ??= new()).AddError(string.IsNullOrEmpty(name) ? $"FirstModel.P6[{count}] is null" : $"{name}.P6[{count}] is null"); } count++; } @@ -328,11 +321,11 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__SecondModelValidator__.Validate(baseName + $"P7[{count}]", o)); + (builder ??= new()).AddResult(global::Enumeration.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P7[{count}]" : $"{name}.P7[{count}]", o)); } else { - builder.AddError(baseName + $"P7[{count}] is null"); + (builder ??= new()).AddError(string.IsNullOrEmpty(name) ? $"FirstModel.P7[{count}] is null" : $"{name}.P7[{count}] is null"); } count++; } @@ -345,17 +338,17 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__SecondModelValidator__.Validate(baseName + $"P8[{count}]", o)); + (builder ??= new()).AddResult(global::Enumeration.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P8[{count}]" : $"{name}.P8[{count}]", o)); } else { - builder.AddError(baseName + $"P8[{count}] is null"); + (builder ??= new()).AddError(string.IsNullOrEmpty(name) ? $"FirstModel.P8[{count}] is null" : $"{name}.P8[{count}] is null"); } count++; } } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -372,22 +365,21 @@ partial struct SecondValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Enumeration.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P6"; - context.DisplayName = baseName + "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P6" : $"{name}.P6"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -404,22 +396,21 @@ partial struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::FileScopedNamespace.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -436,21 +427,20 @@ partial struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::FunnyStrings.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A6); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -468,22 +458,21 @@ internal sealed partial class __SecondModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Generics.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P4"; - context.DisplayName = baseName + "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P4" : $"{name}.P4"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -500,27 +489,26 @@ partial class FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Generics.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P3 is not null) { - builder.AddResult(global::Generics.__SecondModelValidator__.Validate(baseName + "P3", options.P3)); + (builder ??= new()).AddResult(global::Generics.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P3" : $"{name}.P3", options.P3)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -537,27 +525,26 @@ partial struct MultiValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::MultiModelValidator.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P2 is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V3.Validate(baseName + "P2", options.P2)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V3.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2", options.P2)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } /// /// Validates a specific named options instance (or all when is ). @@ -568,22 +555,21 @@ partial struct MultiValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::MultiModelValidator.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P3"; - context.DisplayName = baseName + "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P3" : $"{name}.P3"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -601,22 +587,21 @@ internal sealed partial class __ThirdModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.ThirdModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "ThirdModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P6"; - context.DisplayName = baseName + "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "ThirdModel.P6" : $"{name}.P6"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -635,22 +620,21 @@ partial record struct FifthValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -672,34 +656,33 @@ partial struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P2 is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V4.Validate(baseName + "P2", options.P2)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V4.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2", options.P2)); } - builder.AddResult(global::Nested.__ThirdModelValidator__.Validate(baseName + "P3", options.P3)); + (builder ??= new()).AddResult(global::Nested.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P3" : $"{name}.P3", options.P3)); if (options.P4 is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V5.Validate(baseName + "P4", options.P4)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V5.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P4" : $"{name}.P4", options.P4)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -720,22 +703,21 @@ partial struct FourthValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -757,22 +739,21 @@ partial struct SecondValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -795,22 +776,21 @@ partial struct ThirdValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -829,22 +809,21 @@ partial class FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RandomMembers.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -862,22 +841,21 @@ internal sealed partial class __ThirdModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RecordTypes.ThirdModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "ThirdModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P6"; - context.DisplayName = baseName + "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "ThirdModel.P6" : $"{name}.P6"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -894,34 +872,33 @@ partial record struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RecordTypes.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P2 is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V6.Validate(baseName + "P2", options.P2)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V6.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2", options.P2)); } if (options.P3 is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V7.Validate(baseName + "P3", options.P3)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V7.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P3" : $"{name}.P3", options.P3)); } - builder.AddResult(global::RecordTypes.__ThirdModelValidator__.Validate(baseName + "P4", options.P4)); + (builder ??= new()).AddResult(global::RecordTypes.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P4" : $"{name}.P4", options.P4)); - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -938,22 +915,21 @@ partial record struct SecondValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RecordTypes.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -970,22 +946,21 @@ partial record class ThirdValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RecordTypes.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1003,26 +978,25 @@ internal sealed partial class __SecondModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RepeatedTypes.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "P4"; - context.DisplayName = baseName + "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P4" : $"{name}.P4"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P4 is not null) { - builder.AddResult(global::RepeatedTypes.__ThirdModelValidator__.Validate(baseName + "P4", options.P4)); + (builder ??= new()).AddResult(global::RepeatedTypes.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? "SecondModel.P4" : $"{name}.P4", options.P4)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1040,22 +1014,21 @@ internal sealed partial class __ThirdModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RepeatedTypes.ThirdModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "ThirdModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "ThirdModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1072,56 +1045,55 @@ partial class FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RepeatedTypes.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P1 is not null) { - builder.AddResult(global::RepeatedTypes.__SecondModelValidator__.Validate(baseName + "P1", options.P1)); + (builder ??= new()).AddResult(global::RepeatedTypes.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1", options.P1)); } context.MemberName = "P2"; - context.DisplayName = baseName + "P2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P2 is not null) { - builder.AddResult(global::RepeatedTypes.__SecondModelValidator__.Validate(baseName + "P2", options.P2)); + (builder ??= new()).AddResult(global::RepeatedTypes.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2", options.P2)); } context.MemberName = "P3"; - context.DisplayName = baseName + "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P3" : $"{name}.P3"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P3 is not null) { - builder.AddResult(global::RepeatedTypes.__ThirdModelValidator__.Validate(baseName + "P3", options.P3)); + (builder ??= new()).AddResult(global::RepeatedTypes.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P3" : $"{name}.P3", options.P3)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1138,23 +1110,22 @@ partial struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::SelfValidation.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - builder.AddResults(((global::System.ComponentModel.DataAnnotations.IValidatableObject)options).Validate(context)); + (builder ??= new()).AddResults(((global::System.ComponentModel.DataAnnotations.IValidatableObject)options).Validate(context)); - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1172,21 +1143,20 @@ internal sealed partial class __RangeAttributeModelDoubleValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RangeAttributeModelDouble options) { - var baseName = (string.IsNullOrEmpty(name) ? "RangeAttributeModelDouble" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RangeAttributeModelDouble.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A7); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1204,21 +1174,20 @@ internal sealed partial class __RequiredAttributeModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RequiredAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "RequiredAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RequiredAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1236,36 +1205,35 @@ internal sealed partial class __TypeWithoutOptionsValidatorValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.TypeWithoutOptionsValidator options) { - var baseName = (string.IsNullOrEmpty(name) ? "TypeWithoutOptionsValidator" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val1"; - context.DisplayName = baseName + "Val1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "TypeWithoutOptionsValidator.Val1" : $"{name}.Val1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val2"; - context.DisplayName = baseName + "Val2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "TypeWithoutOptionsValidator.Val2" : $"{name}.Val2"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A8); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.YetAnotherComplexVal is not null) { - builder.AddResult(global::TestClasses.OptionsValidation.__RangeAttributeModelDoubleValidator__.Validate(baseName + "YetAnotherComplexVal", options.YetAnotherComplexVal)); + (builder ??= new()).AddResult(global::TestClasses.OptionsValidation.__RangeAttributeModelDoubleValidator__.Validate(string.IsNullOrEmpty(name) ? "TypeWithoutOptionsValidator.YetAnotherComplexVal" : $"{name}.YetAnotherComplexVal", options.YetAnotherComplexVal)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1282,31 +1250,30 @@ partial class AttributePropertyModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.AttributePropertyModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "AttributePropertyModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val1"; - context.DisplayName = baseName + "Val1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "AttributePropertyModel.Val1" : $"{name}.Val1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A9); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val2"; - context.DisplayName = baseName + "Val2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "AttributePropertyModel.Val2" : $"{name}.Val2"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A10); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1323,21 +1290,20 @@ partial class ComplexModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.ComplexModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "ComplexModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); if (options.ComplexVal is not null) { - builder.AddResult(global::TestClasses.OptionsValidation.__RequiredAttributeModelValidator__.Validate(baseName + "ComplexVal", options.ComplexVal)); + (builder ??= new()).AddResult(global::TestClasses.OptionsValidation.__RequiredAttributeModelValidator__.Validate(string.IsNullOrEmpty(name) ? "ComplexModel.ComplexVal" : $"{name}.ComplexVal", options.ComplexVal)); } if (options.ValWithoutOptionsValidator is not null) { - builder.AddResult(global::TestClasses.OptionsValidation.__TypeWithoutOptionsValidatorValidator__.Validate(baseName + "ValWithoutOptionsValidator", options.ValWithoutOptionsValidator)); + (builder ??= new()).AddResult(global::TestClasses.OptionsValidation.__TypeWithoutOptionsValidatorValidator__.Validate(string.IsNullOrEmpty(name) ? "ComplexModel.ValWithoutOptionsValidator" : $"{name}.ValWithoutOptionsValidator", options.ValWithoutOptionsValidator)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1354,21 +1320,20 @@ partial class CustomTypeCustomValidationAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.CustomTypeCustomValidationAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "CustomTypeCustomValidationAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "CustomTypeCustomValidationAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A11); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1385,21 +1350,20 @@ partial class CustomValidationAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.CustomValidationAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "CustomValidationAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "CustomValidationAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A12); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1416,21 +1380,20 @@ partial class DataTypeAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.DataTypeAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "DataTypeAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "DataTypeAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A13); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1447,41 +1410,40 @@ partial class DerivedModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.DerivedModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "DerivedModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "DerivedVal"; - context.DisplayName = baseName + "DerivedVal"; + context.DisplayName = string.IsNullOrEmpty(name) ? "DerivedModel.DerivedVal" : $"{name}.DerivedVal"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.DerivedVal!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.DerivedVal, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "VirtualValWithAttr"; - context.DisplayName = baseName + "VirtualValWithAttr"; + context.DisplayName = string.IsNullOrEmpty(name) ? "DerivedModel.VirtualValWithAttr" : $"{name}.VirtualValWithAttr"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.VirtualValWithAttr!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.VirtualValWithAttr, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "DerivedModel.Val" : $"{name}.Val"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1498,21 +1460,20 @@ partial class EmailAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.EmailAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "EmailAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "EmailAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A14); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1529,41 +1490,40 @@ partial class LeafModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.LeafModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "LeafModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "VirtualValWithoutAttr"; - context.DisplayName = baseName + "VirtualValWithoutAttr"; + context.DisplayName = string.IsNullOrEmpty(name) ? "LeafModel.VirtualValWithoutAttr" : $"{name}.VirtualValWithoutAttr"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.VirtualValWithoutAttr!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.VirtualValWithoutAttr, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "DerivedVal"; - context.DisplayName = baseName + "DerivedVal"; + context.DisplayName = string.IsNullOrEmpty(name) ? "LeafModel.DerivedVal" : $"{name}.DerivedVal"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.DerivedVal!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.DerivedVal, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "LeafModel.Val" : $"{name}.Val"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1580,52 +1540,51 @@ partial class MultipleAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.MultipleAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "MultipleAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "Val1"; - context.DisplayName = baseName + "Val1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MultipleAttributeModel.Val1" : $"{name}.Val1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A15); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val2"; - context.DisplayName = baseName + "Val2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MultipleAttributeModel.Val2" : $"{name}.Val2"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A16); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val3"; - context.DisplayName = baseName + "Val3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MultipleAttributeModel.Val3" : $"{name}.Val3"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A17); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val3!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val3, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val4"; - context.DisplayName = baseName + "Val4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MultipleAttributeModel.Val4" : $"{name}.Val4"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A18); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val4!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val4, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1642,21 +1601,20 @@ partial class RangeAttributeModelDateValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RangeAttributeModelDate options) { - var baseName = (string.IsNullOrEmpty(name) ? "RangeAttributeModelDate" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RangeAttributeModelDate.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A19); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1673,21 +1631,20 @@ partial class RangeAttributeModelDoubleValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RangeAttributeModelDouble options) { - var baseName = (string.IsNullOrEmpty(name) ? "RangeAttributeModelDouble" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RangeAttributeModelDouble.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A7); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1704,21 +1661,20 @@ partial class RangeAttributeModelIntValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RangeAttributeModelInt options) { - var baseName = (string.IsNullOrEmpty(name) ? "RangeAttributeModelInt" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RangeAttributeModelInt.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A16); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1735,21 +1691,20 @@ partial class RegularExpressionAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RegularExpressionAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "RegularExpressionAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RegularExpressionAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A20); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1766,21 +1721,20 @@ partial class RequiredAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RequiredAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "RequiredAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RequiredAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1798,22 +1752,21 @@ internal sealed partial class __SecondModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::ValueTypes.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P4"; - context.DisplayName = baseName + "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P4" : $"{name}.P4"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1830,34 +1783,33 @@ partial struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::ValueTypes.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P2 is not null) { - builder.AddResult(global::ValueTypes.__SecondModelValidator__.Validate(baseName + "P2", options.P2.Value)); + (builder ??= new()).AddResult(global::ValueTypes.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2", options.P2.Value)); } - builder.AddResult(global::ValueTypes.__SecondModelValidator__.Validate(baseName + "P3", options.P3)); + (builder ??= new()).AddResult(global::ValueTypes.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P3" : $"{name}.P3", options.P3)); if (options.P4 is not null) { - builder.AddResult(global::ValueTypes.__SecondModelValidator__.Validate(baseName + "P4", options.P4.Value)); + (builder ??= new()).AddResult(global::ValueTypes.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P4" : $"{name}.P4", options.P4.Value)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs index 9c68710f2a5ec2..ebdcb1ad6d6ba7 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs @@ -14,22 +14,21 @@ internal sealed partial class __ThirdModelNoNamespaceValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::ThirdModelNoNamespace options) { - var baseName = (string.IsNullOrEmpty(name) ? "ThirdModelNoNamespace" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "ThirdModelNoNamespace.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } partial class FirstValidatorNoNamespace @@ -43,32 +42,31 @@ partial class FirstValidatorNoNamespace [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::FirstModelNoNamespace options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModelNoNamespace" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModelNoNamespace.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P2 is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V1.Validate(baseName + "P2", options.P2)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V1.Validate(string.IsNullOrEmpty(name) ? "FirstModelNoNamespace.P2" : $"{name}.P2", options.P2)); } if (options.P3 is not null) { - builder.AddResult(global::__ThirdModelNoNamespaceValidator__.Validate(baseName + "P3", options.P3)); + (builder ??= new()).AddResult(global::__ThirdModelNoNamespaceValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModelNoNamespace.P3" : $"{name}.P3", options.P3)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } partial class SecondValidatorNoNamespace @@ -82,22 +80,21 @@ partial class SecondValidatorNoNamespace [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::SecondModelNoNamespace options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModelNoNamespace" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P4"; - context.DisplayName = baseName + "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModelNoNamespace.P4" : $"{name}.P4"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } namespace CustomAttr @@ -113,31 +110,30 @@ partial class FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::CustomAttr.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "P2"; - context.DisplayName = baseName + "P2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A4); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -155,22 +151,21 @@ internal sealed partial class __SecondModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Enumeration.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P6"; - context.DisplayName = baseName + "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P6" : $"{name}.P6"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -188,21 +183,20 @@ internal sealed partial class __ThirdModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Enumeration.ThirdModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "ThirdModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Value"; - context.DisplayName = baseName + "Value"; + context.DisplayName = string.IsNullOrEmpty(name) ? "ThirdModel.Value" : $"{name}.Value"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A5); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Value!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Value, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -219,8 +213,7 @@ partial struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Enumeration.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); if (options.P1 is not null) @@ -230,11 +223,11 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__SecondModelValidator__.Validate(baseName + $"P1[{count}]", o)); + (builder ??= new()).AddResult(global::Enumeration.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P1[{count}]" : $"{name}.P1[{count}]", o)); } else { - builder.AddError(baseName + $"P1[{count}] is null"); + (builder ??= new()).AddError(string.IsNullOrEmpty(name) ? $"FirstModel.P1[{count}] is null" : $"{name}.P1[{count}] is null"); } count++; } @@ -247,11 +240,11 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V2.Validate(baseName + $"P2[{count}]", o)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V2.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P2[{count}]" : $"{name}.P2[{count}]", o)); } else { - builder.AddError(baseName + $"P2[{count}] is null"); + (builder ??= new()).AddError(string.IsNullOrEmpty(name) ? $"FirstModel.P2[{count}] is null" : $"{name}.P2[{count}] is null"); } count++; } @@ -264,7 +257,7 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__SecondModelValidator__.Validate(baseName + $"P3[{count}]", o)); + (builder ??= new()).AddResult(global::Enumeration.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P3[{count}]" : $"{name}.P3[{count}]", o)); } count++; } @@ -275,7 +268,7 @@ partial struct FirstValidator var count = 0; foreach (var o in options.P4) { - builder.AddResult(global::Enumeration.__ThirdModelValidator__.Validate(baseName + $"P4[{count++}]", o)); + (builder ??= new()).AddResult(global::Enumeration.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P4[{count++}] is null" : $"{name}.P4[{count++}] is null", o)); } } @@ -286,7 +279,7 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__ThirdModelValidator__.Validate(baseName + $"P5[{count}]", o.Value)); + (builder ??= new()).AddResult(global::Enumeration.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P5[{count}]" : $"{name}.P5[{count}]", o.Value)); } count++; } @@ -299,7 +292,7 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__ThirdModelValidator__.Validate(baseName + $"P51[{count}]", o.Value)); + (builder ??= new()).AddResult(global::Enumeration.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P51[{count}]" : $"{name}.P51[{count}]", o.Value)); } count++; } @@ -312,11 +305,11 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__SecondModelValidator__.Validate(baseName + $"P6[{count}]", o)); + (builder ??= new()).AddResult(global::Enumeration.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P6[{count}]" : $"{name}.P6[{count}]", o)); } else { - builder.AddError(baseName + $"P6[{count}] is null"); + (builder ??= new()).AddError(string.IsNullOrEmpty(name) ? $"FirstModel.P6[{count}] is null" : $"{name}.P6[{count}] is null"); } count++; } @@ -328,11 +321,11 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__SecondModelValidator__.Validate(baseName + $"P7[{count}]", o)); + (builder ??= new()).AddResult(global::Enumeration.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P7[{count}]" : $"{name}.P7[{count}]", o)); } else { - builder.AddError(baseName + $"P7[{count}] is null"); + (builder ??= new()).AddError(string.IsNullOrEmpty(name) ? $"FirstModel.P7[{count}] is null" : $"{name}.P7[{count}] is null"); } count++; } @@ -345,17 +338,17 @@ partial struct FirstValidator { if (o is not null) { - builder.AddResult(global::Enumeration.__SecondModelValidator__.Validate(baseName + $"P8[{count}]", o)); + (builder ??= new()).AddResult(global::Enumeration.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? $"FirstModel.P8[{count}]" : $"{name}.P8[{count}]", o)); } else { - builder.AddError(baseName + $"P8[{count}] is null"); + (builder ??= new()).AddError(string.IsNullOrEmpty(name) ? $"FirstModel.P8[{count}] is null" : $"{name}.P8[{count}] is null"); } count++; } } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -372,22 +365,21 @@ partial struct SecondValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Enumeration.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P6"; - context.DisplayName = baseName + "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P6" : $"{name}.P6"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -404,22 +396,21 @@ partial struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::FileScopedNamespace.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -436,21 +427,20 @@ partial struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::FunnyStrings.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A6); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -468,22 +458,21 @@ internal sealed partial class __SecondModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Generics.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P4"; - context.DisplayName = baseName + "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P4" : $"{name}.P4"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -500,27 +489,26 @@ partial class FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Generics.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P3 is not null) { - builder.AddResult(global::Generics.__SecondModelValidator__.Validate(baseName + "P3", options.P3)); + (builder ??= new()).AddResult(global::Generics.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P3" : $"{name}.P3", options.P3)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -537,27 +525,26 @@ partial struct MultiValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::MultiModelValidator.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P2 is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V3.Validate(baseName + "P2", options.P2)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V3.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2", options.P2)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } /// /// Validates a specific named options instance (or all when is ). @@ -568,22 +555,21 @@ partial struct MultiValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::MultiModelValidator.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P3"; - context.DisplayName = baseName + "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P3" : $"{name}.P3"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -601,22 +587,21 @@ internal sealed partial class __ThirdModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.ThirdModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "ThirdModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P6"; - context.DisplayName = baseName + "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "ThirdModel.P6" : $"{name}.P6"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -635,22 +620,21 @@ partial record struct FifthValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -672,34 +656,33 @@ partial struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P2 is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V4.Validate(baseName + "P2", options.P2)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V4.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2", options.P2)); } - builder.AddResult(global::Nested.__ThirdModelValidator__.Validate(baseName + "P3", options.P3)); + (builder ??= new()).AddResult(global::Nested.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P3" : $"{name}.P3", options.P3)); if (options.P4 is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V5.Validate(baseName + "P4", options.P4)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V5.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P4" : $"{name}.P4", options.P4)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -720,22 +703,21 @@ partial struct FourthValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -757,22 +739,21 @@ partial struct SecondValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -795,22 +776,21 @@ partial struct ThirdValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -829,22 +809,21 @@ partial class FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RandomMembers.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -862,22 +841,21 @@ internal sealed partial class __ThirdModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RecordTypes.ThirdModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "ThirdModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P6"; - context.DisplayName = baseName + "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "ThirdModel.P6" : $"{name}.P6"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -894,34 +872,33 @@ partial record struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RecordTypes.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P2 is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V6.Validate(baseName + "P2", options.P2)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V6.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2", options.P2)); } if (options.P3 is not null) { - builder.AddResult(global::__OptionValidationStaticInstances.__Validators.V7.Validate(baseName + "P3", options.P3)); + (builder ??= new()).AddResult(global::__OptionValidationStaticInstances.__Validators.V7.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P3" : $"{name}.P3", options.P3)); } - builder.AddResult(global::RecordTypes.__ThirdModelValidator__.Validate(baseName + "P4", options.P4)); + (builder ??= new()).AddResult(global::RecordTypes.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P4" : $"{name}.P4", options.P4)); - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -938,22 +915,21 @@ partial record struct SecondValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RecordTypes.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -970,22 +946,21 @@ partial record class ThirdValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RecordTypes.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1003,26 +978,25 @@ internal sealed partial class __SecondModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RepeatedTypes.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "P4"; - context.DisplayName = baseName + "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P4" : $"{name}.P4"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P4 is not null) { - builder.AddResult(global::RepeatedTypes.__ThirdModelValidator__.Validate(baseName + "P4", options.P4)); + (builder ??= new()).AddResult(global::RepeatedTypes.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? "SecondModel.P4" : $"{name}.P4", options.P4)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1040,22 +1014,21 @@ internal sealed partial class __ThirdModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RepeatedTypes.ThirdModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "ThirdModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P5"; - context.DisplayName = baseName + "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "ThirdModel.P5" : $"{name}.P5"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1072,56 +1045,55 @@ partial class FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RepeatedTypes.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P1 is not null) { - builder.AddResult(global::RepeatedTypes.__SecondModelValidator__.Validate(baseName + "P1", options.P1)); + (builder ??= new()).AddResult(global::RepeatedTypes.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1", options.P1)); } context.MemberName = "P2"; - context.DisplayName = baseName + "P2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P2 is not null) { - builder.AddResult(global::RepeatedTypes.__SecondModelValidator__.Validate(baseName + "P2", options.P2)); + (builder ??= new()).AddResult(global::RepeatedTypes.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2", options.P2)); } context.MemberName = "P3"; - context.DisplayName = baseName + "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P3" : $"{name}.P3"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P3 is not null) { - builder.AddResult(global::RepeatedTypes.__ThirdModelValidator__.Validate(baseName + "P3", options.P3)); + (builder ??= new()).AddResult(global::RepeatedTypes.__ThirdModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P3" : $"{name}.P3", options.P3)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1138,23 +1110,22 @@ partial struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::SelfValidation.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - builder.AddResults(((global::System.ComponentModel.DataAnnotations.IValidatableObject)options).Validate(context)); + (builder ??= new()).AddResults(((global::System.ComponentModel.DataAnnotations.IValidatableObject)options).Validate(context)); - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1172,21 +1143,20 @@ internal sealed partial class __RangeAttributeModelDoubleValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RangeAttributeModelDouble options) { - var baseName = (string.IsNullOrEmpty(name) ? "RangeAttributeModelDouble" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RangeAttributeModelDouble.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A7); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1204,21 +1174,20 @@ internal sealed partial class __RequiredAttributeModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RequiredAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "RequiredAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RequiredAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1236,36 +1205,35 @@ internal sealed partial class __TypeWithoutOptionsValidatorValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.TypeWithoutOptionsValidator options) { - var baseName = (string.IsNullOrEmpty(name) ? "TypeWithoutOptionsValidator" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val1"; - context.DisplayName = baseName + "Val1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "TypeWithoutOptionsValidator.Val1" : $"{name}.Val1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val2"; - context.DisplayName = baseName + "Val2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "TypeWithoutOptionsValidator.Val2" : $"{name}.Val2"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A8); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.YetAnotherComplexVal is not null) { - builder.AddResult(global::TestClasses.OptionsValidation.__RangeAttributeModelDoubleValidator__.Validate(baseName + "YetAnotherComplexVal", options.YetAnotherComplexVal)); + (builder ??= new()).AddResult(global::TestClasses.OptionsValidation.__RangeAttributeModelDoubleValidator__.Validate(string.IsNullOrEmpty(name) ? "TypeWithoutOptionsValidator.YetAnotherComplexVal" : $"{name}.YetAnotherComplexVal", options.YetAnotherComplexVal)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1282,31 +1250,30 @@ partial class AttributePropertyModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.AttributePropertyModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "AttributePropertyModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val1"; - context.DisplayName = baseName + "Val1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "AttributePropertyModel.Val1" : $"{name}.Val1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A9); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val2"; - context.DisplayName = baseName + "Val2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "AttributePropertyModel.Val2" : $"{name}.Val2"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A10); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1323,21 +1290,20 @@ partial class ComplexModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.ComplexModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "ComplexModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); if (options.ComplexVal is not null) { - builder.AddResult(global::TestClasses.OptionsValidation.__RequiredAttributeModelValidator__.Validate(baseName + "ComplexVal", options.ComplexVal)); + (builder ??= new()).AddResult(global::TestClasses.OptionsValidation.__RequiredAttributeModelValidator__.Validate(string.IsNullOrEmpty(name) ? "ComplexModel.ComplexVal" : $"{name}.ComplexVal", options.ComplexVal)); } if (options.ValWithoutOptionsValidator is not null) { - builder.AddResult(global::TestClasses.OptionsValidation.__TypeWithoutOptionsValidatorValidator__.Validate(baseName + "ValWithoutOptionsValidator", options.ValWithoutOptionsValidator)); + (builder ??= new()).AddResult(global::TestClasses.OptionsValidation.__TypeWithoutOptionsValidatorValidator__.Validate(string.IsNullOrEmpty(name) ? "ComplexModel.ValWithoutOptionsValidator" : $"{name}.ValWithoutOptionsValidator", options.ValWithoutOptionsValidator)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1354,21 +1320,20 @@ partial class CustomTypeCustomValidationAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.CustomTypeCustomValidationAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "CustomTypeCustomValidationAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "CustomTypeCustomValidationAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A11); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1385,21 +1350,20 @@ partial class CustomValidationAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.CustomValidationAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "CustomValidationAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "CustomValidationAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A12); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1416,21 +1380,20 @@ partial class DataTypeAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.DataTypeAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "DataTypeAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "DataTypeAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A13); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1447,41 +1410,40 @@ partial class DerivedModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.DerivedModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "DerivedModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "DerivedVal"; - context.DisplayName = baseName + "DerivedVal"; + context.DisplayName = string.IsNullOrEmpty(name) ? "DerivedModel.DerivedVal" : $"{name}.DerivedVal"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.DerivedVal!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.DerivedVal, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "VirtualValWithAttr"; - context.DisplayName = baseName + "VirtualValWithAttr"; + context.DisplayName = string.IsNullOrEmpty(name) ? "DerivedModel.VirtualValWithAttr" : $"{name}.VirtualValWithAttr"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.VirtualValWithAttr!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.VirtualValWithAttr, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "DerivedModel.Val" : $"{name}.Val"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1498,21 +1460,20 @@ partial class EmailAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.EmailAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "EmailAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "EmailAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A14); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1529,41 +1490,40 @@ partial class LeafModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.LeafModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "LeafModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "VirtualValWithoutAttr"; - context.DisplayName = baseName + "VirtualValWithoutAttr"; + context.DisplayName = string.IsNullOrEmpty(name) ? "LeafModel.VirtualValWithoutAttr" : $"{name}.VirtualValWithoutAttr"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.VirtualValWithoutAttr!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.VirtualValWithoutAttr, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "DerivedVal"; - context.DisplayName = baseName + "DerivedVal"; + context.DisplayName = string.IsNullOrEmpty(name) ? "LeafModel.DerivedVal" : $"{name}.DerivedVal"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.DerivedVal!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.DerivedVal, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "LeafModel.Val" : $"{name}.Val"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1580,52 +1540,51 @@ partial class MultipleAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.MultipleAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "MultipleAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "Val1"; - context.DisplayName = baseName + "Val1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MultipleAttributeModel.Val1" : $"{name}.Val1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A15); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val2"; - context.DisplayName = baseName + "Val2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MultipleAttributeModel.Val2" : $"{name}.Val2"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A16); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val3"; - context.DisplayName = baseName + "Val3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MultipleAttributeModel.Val3" : $"{name}.Val3"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A17); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val3!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val3, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } context.MemberName = "Val4"; - context.DisplayName = baseName + "Val4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MultipleAttributeModel.Val4" : $"{name}.Val4"; validationResults.Clear(); validationAttributes.Clear(); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A18); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val4!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val4, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1642,21 +1601,20 @@ partial class RangeAttributeModelDateValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RangeAttributeModelDate options) { - var baseName = (string.IsNullOrEmpty(name) ? "RangeAttributeModelDate" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RangeAttributeModelDate.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A8); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1673,21 +1631,20 @@ partial class RangeAttributeModelDoubleValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RangeAttributeModelDouble options) { - var baseName = (string.IsNullOrEmpty(name) ? "RangeAttributeModelDouble" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RangeAttributeModelDouble.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A7); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1704,21 +1661,20 @@ partial class RangeAttributeModelIntValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RangeAttributeModelInt options) { - var baseName = (string.IsNullOrEmpty(name) ? "RangeAttributeModelInt" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RangeAttributeModelInt.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A16); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1735,21 +1691,20 @@ partial class RegularExpressionAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RegularExpressionAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "RegularExpressionAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RegularExpressionAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A19); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1766,21 +1721,20 @@ partial class RequiredAttributeModelValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RequiredAttributeModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "RequiredAttributeModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(1); context.MemberName = "Val"; - context.DisplayName = baseName + "Val"; + context.DisplayName = string.IsNullOrEmpty(name) ? "RequiredAttributeModel.Val" : $"{name}.Val"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1798,22 +1752,21 @@ internal sealed partial class __SecondModelValidator__ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::ValueTypes.SecondModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "SecondModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P4"; - context.DisplayName = baseName + "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P4" : $"{name}.P4"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } @@ -1830,34 +1783,33 @@ partial struct FirstValidator [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::ValueTypes.FirstModel options) { - var baseName = (string.IsNullOrEmpty(name) ? "FirstModel" : name) + "."; - var builder = new global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder(); + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); var validationResults = new global::System.Collections.Generic.List(); var validationAttributes = new global::System.Collections.Generic.List(2); context.MemberName = "P1"; - context.DisplayName = baseName + "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P1" : $"{name}.P1"; validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1!, context, validationResults, validationAttributes)) + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) { - builder.AddResults(validationResults); + (builder ??= new()).AddResults(validationResults); } if (options.P2 is not null) { - builder.AddResult(global::ValueTypes.__SecondModelValidator__.Validate(baseName + "P2", options.P2.Value)); + (builder ??= new()).AddResult(global::ValueTypes.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2", options.P2.Value)); } - builder.AddResult(global::ValueTypes.__SecondModelValidator__.Validate(baseName + "P3", options.P3)); + (builder ??= new()).AddResult(global::ValueTypes.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P3" : $"{name}.P3", options.P3)); if (options.P4 is not null) { - builder.AddResult(global::ValueTypes.__SecondModelValidator__.Validate(baseName + "P4", options.P4.Value)); + (builder ??= new()).AddResult(global::ValueTypes.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P4" : $"{name}.P4", options.P4.Value)); } - return builder.Build(); + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } } From dc652c10e9ea4c6c9fffab50647b0b2350377dba Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 12:31:41 -0600 Subject: [PATCH 125/783] [release/8.0] [nodejs] Remove experimental wasm arguments from template (#91401) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove experimental wasm arguments from template and add them to features.md * Fix WBT * Use lowercase host in runtimeconfig.template.json * Override runtimeconfig only for wasmconsole --------- Co-authored-by: Marek Fišera Co-authored-by: Marek Safar --- .../Wasm.Build.Tests/WasmTemplateTestBase.cs | 36 +++++++++++++++---- src/mono/wasm/features.md | 18 ++++++++++ .../console/runtimeconfig.template.json | 8 ++--- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs index 6280a022c1a424..a7ae3fba70ed30 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs @@ -3,7 +3,9 @@ #nullable enable +using System; using System.IO; +using System.Text.Json.Nodes; using Xunit.Abstractions; namespace Wasm.Build.Tests; @@ -45,18 +47,38 @@ public string CreateWasmTemplateProject(string id, string template = "wasmbrowse if (runAnalyzers) extraProperties += "true"; - // TODO: Can be removed after updated templates propagate in. - string extraItems = string.Empty; - if (template == "wasmbrowser") - extraItems += ""; - else - extraItems += ""; + if (template == "wasmconsole") + { + UpdateRuntimeconfigTemplateForNode(_projectDir); + } - AddItemsPropertiesToProject(projectfile, extraProperties, extraItems); + AddItemsPropertiesToProject(projectfile, extraProperties); return projectfile; } + private static void UpdateRuntimeconfigTemplateForNode(string projectDir) + { + // TODO: Can be removed once Node >= 20 + + string runtimeconfigTemplatePath = Path.Combine(projectDir, "runtimeconfig.template.json"); + string runtimeconfigTemplateContent = File.ReadAllText(runtimeconfigTemplatePath); + var runtimeconfigTemplate = JsonObject.Parse(runtimeconfigTemplateContent); + if (runtimeconfigTemplate == null) + throw new Exception($"Unable to parse runtimeconfigtemplate at '{runtimeconfigTemplatePath}'"); + + var perHostConfigs = runtimeconfigTemplate?["wasmHostProperties"]?["perHostConfig"]?.AsArray(); + if (perHostConfigs == null || perHostConfigs.Count == 0 || perHostConfigs[0] == null) + throw new Exception($"Unable to find perHostConfig in runtimeconfigtemplate at '{runtimeconfigTemplatePath}'"); + + perHostConfigs[0]!["host-args"] = new JsonArray( + "--experimental-wasm-simd", + "--experimental-wasm-eh" + ); + + File.WriteAllText(runtimeconfigTemplatePath, runtimeconfigTemplate!.ToString()); + } + public (string projectDir, string buildOutput) BuildTemplateProject(BuildArgs buildArgs, string id, BuildProjectOptions buildProjectOptions) diff --git a/src/mono/wasm/features.md b/src/mono/wasm/features.md index c131002dde7968..d3d85f2e570a9e 100644 --- a/src/mono/wasm/features.md +++ b/src/mono/wasm/features.md @@ -292,6 +292,24 @@ A WebAssembly application that works well on desktop PCs browser may take minute ### Shell environments - NodeJS & V8 While our primary target is web browsers, we have partial support for Node.JS v14 sufficient to pass most of our automated tests. We also have partial support for the D8 command-line shell, version 11 or higher, sufficient to pass most of our automated tests. Both of these environments may lack support for features that are available in the browser. +#### NodeJS < 20 +Until node version 20, you may need to pass these arguments when running the application `--experimental-wasm-simd --experimental-wasm-eh`. When you run the application using `dotnet run`, you can add these to the runtimeconfig template + +```json +"wasmHostProperties": { + "perHostConfig": [ + { + "name": "node", + ... + "host-args": [ + "--experimental-wasm-simd", // 👈 Enable SIMD support + "--experimental-wasm-eh" // 👈 Enable exception handling support + ] + } + ] +} +``` + ## Choosing the right platform target Every end user has different needs, so the right platform for every application may differ. diff --git a/src/mono/wasm/templates/templates/console/runtimeconfig.template.json b/src/mono/wasm/templates/templates/console/runtimeconfig.template.json index 49721faa0baa4d..a056e67f11cf9a 100644 --- a/src/mono/wasm/templates/templates/console/runtimeconfig.template.json +++ b/src/mono/wasm/templates/templates/console/runtimeconfig.template.json @@ -4,12 +4,8 @@ { "name": "node", "js-path": "main.mjs", - "Host": "nodejs", - "host-args": [ - "--experimental-wasm-simd", - "--experimental-wasm-eh" - ] + "host": "nodejs" } ] } -} +} \ No newline at end of file From 4d6f6bc30fcd1423992023865e50044a32f018d1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 12:33:48 -0600 Subject: [PATCH 126/783] Fix arm64/arm32 cross-DAC (#91438) The precode code was incorrectly using the HOST_ARM64, HOST_ARM, etc. defines instead of the TARGET_ ones. This means the cross-DAC was using the wrong architectures *Precode::Type codes. Co-authored-by: Mike McLaughlin --- src/coreclr/vm/precode.h | 50 ++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/coreclr/vm/precode.h b/src/coreclr/vm/precode.h index d7f6b4cac1a74d..158c1ab08f5545 100644 --- a/src/coreclr/vm/precode.h +++ b/src/coreclr/vm/precode.h @@ -11,7 +11,7 @@ #define PRECODE_ALIGNMENT sizeof(void*) -#if defined(HOST_AMD64) +#if defined(TARGET_AMD64) #define OFFSETOF_PRECODE_TYPE 0 #define OFFSETOF_PRECODE_TYPE_CALL_OR_JMP 5 @@ -19,7 +19,7 @@ #define SIZEOF_PRECODE_BASE 16 -#elif defined(HOST_X86) +#elif defined(TARGET_X86) EXTERN_C VOID STDCALL PrecodeRemotingThunk(); @@ -29,27 +29,27 @@ EXTERN_C VOID STDCALL PrecodeRemotingThunk(); #define SIZEOF_PRECODE_BASE 8 -#elif defined(HOST_ARM64) +#elif defined(TARGET_ARM64) #define SIZEOF_PRECODE_BASE CODE_SIZE_ALIGN #define OFFSETOF_PRECODE_TYPE 0 -#elif defined(HOST_ARM) +#elif defined(TARGET_ARM) #define SIZEOF_PRECODE_BASE CODE_SIZE_ALIGN #define OFFSETOF_PRECODE_TYPE 3 -#elif defined(HOST_LOONGARCH64) +#elif defined(TARGET_LOONGARCH64) #define SIZEOF_PRECODE_BASE CODE_SIZE_ALIGN #define OFFSETOF_PRECODE_TYPE 0 -#elif defined(HOST_RISCV64) +#elif defined(TARGET_RISCV64) #define SIZEOF_PRECODE_BASE CODE_SIZE_ALIGN #define OFFSETOF_PRECODE_TYPE 0 -#endif // HOST_AMD64 +#endif // TARGET_AMD64 #ifndef DACCESS_COMPILE // Given an address in a slot, figure out if the prestub will be called @@ -61,14 +61,14 @@ BOOL DoesSlotCallPrestub(PCODE pCode); // Invalid precode type struct InvalidPrecode { -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(TARGET_AMD64) || defined(TARGET_X86) // int3 static const int Type = 0xCC; -#elif defined(HOST_ARM64) || defined(HOST_ARM) +#elif defined(TARGET_ARM64) || defined(TARGET_ARM) static const int Type = 0; -#elif defined(HOST_LOONGARCH64) +#elif defined(TARGET_LOONGARCH64) static const int Type = 0xff; -#elif defined(HOST_RISCV64) +#elif defined(TARGET_RISCV64) static const int Type = 0xff; #endif }; @@ -90,25 +90,25 @@ extern "C" void StubPrecodeCode_End(); // Regular precode struct StubPrecode { -#if defined(HOST_AMD64) +#if defined(TARGET_AMD64) static const BYTE Type = 0x4C; static const SIZE_T CodeSize = 24; -#elif defined(HOST_X86) +#elif defined(TARGET_X86) static const BYTE Type = 0xA1; static const SIZE_T CodeSize = 24; -#elif defined(HOST_ARM64) +#elif defined(TARGET_ARM64) static const int Type = 0x4A; static const SIZE_T CodeSize = 24; -#elif defined(HOST_ARM) +#elif defined(TARGET_ARM) static const int Type = 0xCF; static const SIZE_T CodeSize = 12; -#elif defined(HOST_LOONGARCH64) +#elif defined(TARGET_LOONGARCH64) static const int Type = 0x4; static const SIZE_T CodeSize = 24; -#elif defined(HOST_RISCV64) +#elif defined(TARGET_RISCV64) static const int Type = 0x17; static const SIZE_T CodeSize = 24; -#endif // HOST_AMD64 +#endif // TARGET_AMD64 BYTE m_code[CodeSize]; @@ -224,31 +224,31 @@ extern "C" void FixupPrecodeCode_End(); // The fixup precode is simple jump once patched. It does not have the two instruction overhead of regular precode. struct FixupPrecode { -#if defined(HOST_AMD64) +#if defined(TARGET_AMD64) static const int Type = 0xFF; static const SIZE_T CodeSize = 24; static const int FixupCodeOffset = 6; -#elif defined(HOST_X86) +#elif defined(TARGET_X86) static const int Type = 0xFF; static const SIZE_T CodeSize = 24; static const int FixupCodeOffset = 6; -#elif defined(HOST_ARM64) +#elif defined(TARGET_ARM64) static const int Type = 0x0B; static const SIZE_T CodeSize = 24; static const int FixupCodeOffset = 8; -#elif defined(HOST_ARM) +#elif defined(TARGET_ARM) static const int Type = 0xFF; static const SIZE_T CodeSize = 12; static const int FixupCodeOffset = 4 + THUMB_CODE; -#elif defined(HOST_LOONGARCH64) +#elif defined(TARGET_LOONGARCH64) static const int Type = 0x3; static const SIZE_T CodeSize = 32; static const int FixupCodeOffset = 12; -#elif defined(HOST_RISCV64) +#elif defined(TARGET_RISCV64) static const int Type = 0x97; static const SIZE_T CodeSize = 32; static const int FixupCodeOffset = 10; -#endif // HOST_AMD64 +#endif // TARGET_AMD64 BYTE m_code[CodeSize]; From 2134e6210b5eb944c834744877d8d06401b1c845 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 12:34:35 -0600 Subject: [PATCH 127/783] Fix runtime dispatch to static virtuals on interface types (#91440) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were not generating information about static virtuals on interface types. Information about default interface methods normally goes to the class, but if the T we're dispatching on is an interface, this information wasn't generated. The fix is to put this information into dispatch maps and sealed vtables, same way we do for classes. The test shows what the problem is - if we change `IBar` to be a class, things would work even before this PR. Co-authored-by: Michal Strehovský --- .../Common/MetadataVirtualMethodAlgorithm.cs | 9 ++- .../Compiler/DependencyAnalysis/EETypeNode.cs | 19 ++--- .../InterfaceDispatchMapNode.cs | 34 +++++++-- .../DependencyAnalysis/SealedVTableNode.cs | 14 +++- .../Compiler/VirtualMethodCallHelper.cs | 5 +- .../SmokeTests/UnitTests/Interfaces.cs | 73 +++++++++++++++++++ 6 files changed, 132 insertions(+), 22 deletions(-) diff --git a/src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs b/src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs index 8d2b8a4e3fd3fe..330296b18dbfa4 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs @@ -614,6 +614,8 @@ private static MethodDesc ResolveInterfaceMethodToVirtualMethodOnType(MethodDesc { Debug.Assert(!interfaceMethod.Signature.IsStatic); + // This would be a default interface method resolution. The algorithm below would sort of work, but doesn't handle + // things like diamond cases and it's better not to let it resolve as such. if (currentType.IsInterface) return null; @@ -781,7 +783,7 @@ private static DefaultInterfaceMethodResolution ResolveInterfaceMethodToDefaultI // If we're asking about an interface, include the interface in the list. consideredInterfaces = new DefType[currentType.RuntimeInterfaces.Length + 1]; Array.Copy(currentType.RuntimeInterfaces, consideredInterfaces, currentType.RuntimeInterfaces.Length); - consideredInterfaces[consideredInterfaces.Length - 1] = (DefType)currentType.InstantiateAsOpen(); + consideredInterfaces[consideredInterfaces.Length - 1] = currentType.IsGenericDefinition ? (DefType)currentType.InstantiateAsOpen() : currentType; } foreach (MetadataType runtimeInterface in consideredInterfaces) @@ -921,6 +923,11 @@ public static IEnumerable EnumAllVirtualSlots(MetadataType type) /// MethodDesc of the resolved virtual static method, null when not found (runtime lookup must be used) public static MethodDesc ResolveInterfaceMethodToStaticVirtualMethodOnType(MethodDesc interfaceMethod, MetadataType currentType) { + // This would be a default interface method resolution. The algorithm below would sort of work, but doesn't handle + // things like diamond cases and it's better not to let it resolve as such. + if (currentType.IsInterface) + return null; + // Search for match on a per-level in the type hierarchy for (MetadataType typeToCheck = currentType; typeToCheck != null; typeToCheck = typeToCheck.MetadataBaseType) { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs index 1e9f7679b44cc3..61520b4bfadaff 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs @@ -372,16 +372,8 @@ public sealed override IEnumerable GetConditionalSt DefType defType = _type.GetClosestDefType(); - // Interfaces don't have vtables and we don't need to track their slot use. - // The only exception are those interfaces that provide IDynamicInterfaceCastable implementations; - // those have slots and we dispatch on them. - bool needsDependenciesForVirtualMethodImpls = !defType.IsInterface - || ((MetadataType)defType).IsDynamicInterfaceCastableImplementation(); - // If we're producing a full vtable, none of the dependencies are conditional. - needsDependenciesForVirtualMethodImpls &= !factory.VTable(defType).HasFixedSlots; - - if (needsDependenciesForVirtualMethodImpls) + if (!factory.VTable(defType).HasFixedSlots) { bool isNonInterfaceAbstractType = !defType.IsInterface && ((MetadataType)defType).IsAbstract; @@ -436,6 +428,12 @@ public sealed override IEnumerable GetConditionalSt ((System.Collections.IStructuralEquatable)defType.RuntimeInterfaces).Equals(_type.RuntimeInterfaces, EqualityComparer.Default)); + // Interfaces don't have vtables and we don't need to track their instance method slot use. + // The only exception are those interfaces that provide IDynamicInterfaceCastable implementations; + // those have slots and we dispatch on them. + bool needsDependenciesForInstanceInterfaceMethodImpls = !defType.IsInterface + || ((MetadataType)defType).IsDynamicInterfaceCastableImplementation(); + // Add conditional dependencies for interface methods the type implements. For example, if the type T implements // interface IFoo which has a method M1, add a dependency on T.M1 dependent on IFoo.M1 being called, since it's // possible for any IFoo object to actually be an instance of T. @@ -456,6 +454,9 @@ public sealed override IEnumerable GetConditionalSt bool isStaticInterfaceMethod = interfaceMethod.Signature.IsStatic; + if (!isStaticInterfaceMethod && !needsDependenciesForInstanceInterfaceMethodImpls) + continue; + MethodDesc implMethod = isStaticInterfaceMethod ? defType.ResolveInterfaceMethodToStaticVirtualMethodOnType(interfaceMethod) : defType.ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs index 38104d7ab015c9..c2ac4568c748c9 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs @@ -73,7 +73,7 @@ public static bool MightHaveInterfaceDispatchMap(TypeDesc type, NodeFactory fact if (!type.IsArray && !type.IsDefType) return false; - // Interfaces don't have a dispatch map because we dispatch them based on the + // Interfaces don't have a dispatch map for instance methods because we dispatch them based on the // dispatch map of the implementing class. // The only exception are IDynamicInterfaceCastable scenarios that dispatch // using the interface dispatch map. @@ -83,8 +83,9 @@ public static bool MightHaveInterfaceDispatchMap(TypeDesc type, NodeFactory fact // wasn't marked as [DynamicInterfaceCastableImplementation]" and "we couldn't find an // implementation". We don't want to use the custom attribute for that at runtime because // that's reflection and this should work without reflection. - if (type.IsInterface) - return ((MetadataType)type).IsDynamicInterfaceCastableImplementation(); + bool isInterface = type.IsInterface; + if (isInterface && ((MetadataType)type).IsDynamicInterfaceCastableImplementation()) + return true; DefType declType = type.GetClosestDefType(); @@ -112,6 +113,11 @@ public static bool MightHaveInterfaceDispatchMap(TypeDesc type, NodeFactory fact Debug.Assert(declMethod.IsVirtual); + // Only static methods get placed in dispatch maps of interface types (modulo + // IDynamicInterfaceCastable we already handled above). + if (isInterface && !declMethod.Signature.IsStatic) + continue; + if (interfaceOnDefinitionType != null) declMethod = factory.TypeSystemContext.GetMethodForInstantiatedType(declMethod.GetTypicalMethodDefinition(), interfaceOnDefinitionType); @@ -154,6 +160,10 @@ private void EmitDispatchMap(ref ObjectDataBuilder builder, NodeFactory factory) var staticImplementations = new List<(int InterfaceIndex, int InterfaceMethodSlot, int ImplMethodSlot, int Context)>(); var staticDefaultImplementations = new List<(int InterfaceIndex, int InterfaceMethodSlot, int ImplMethodSlot, int Context)>(); + bool isInterface = declType.IsInterface; + bool needsEntriesForInstanceInterfaceMethodImpls = !isInterface + || ((MetadataType)declType).IsDynamicInterfaceCastableImplementation(); + // Resolve all the interfaces, but only emit non-static and non-default implementations for (int interfaceIndex = 0; interfaceIndex < declTypeRuntimeInterfaces.Length; interfaceIndex++) { @@ -166,6 +176,10 @@ private void EmitDispatchMap(ref ObjectDataBuilder builder, NodeFactory factory) for (int interfaceMethodSlot = 0; interfaceMethodSlot < virtualSlots.Count; interfaceMethodSlot++) { MethodDesc declMethod = virtualSlots[interfaceMethodSlot]; + + if (!declMethod.Signature.IsStatic && !needsEntriesForInstanceInterfaceMethodImpls) + continue; + if(!interfaceType.IsTypeDefinition) declMethod = factory.TypeSystemContext.GetMethodForInstantiatedType(declMethod.GetTypicalMethodDefinition(), (InstantiatedType)interfaceDefinitionType); @@ -244,9 +258,17 @@ private void EmitDispatchMap(ref ObjectDataBuilder builder, NodeFactory factory) // For default interface methods, the generic context is acquired by indexing // into the interface list of the owning type. Debug.Assert(providingInterfaceDefinitionType != null); - int indexOfInterface = Array.IndexOf(declTypeDefinitionRuntimeInterfaces, providingInterfaceDefinitionType); - Debug.Assert(indexOfInterface >= 0); - genericContext = StaticVirtualMethodContextSource.ContextFromFirstInterface + indexOfInterface; + if (declTypeDefinition.HasSameTypeDefinition(providingInterfaceDefinitionType) && + providingInterfaceDefinitionType == declTypeDefinition.InstantiateAsOpen()) + { + genericContext = StaticVirtualMethodContextSource.ContextFromThisClass; + } + else + { + int indexOfInterface = Array.IndexOf(declTypeDefinitionRuntimeInterfaces, providingInterfaceDefinitionType); + Debug.Assert(indexOfInterface >= 0); + genericContext = StaticVirtualMethodContextSource.ContextFromFirstInterface + indexOfInterface; + } } staticDefaultImplementations.Add(( interfaceIndex, diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs index bb67f884264dd3..a8460e80d0b413 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs @@ -108,17 +108,21 @@ public bool BuildSealedVTableSlots(NodeFactory factory, bool relocsOnly) _sealedVTableEntries = new List(); - // Interfaces don't have any virtual slots with the exception of interfaces that provide + // Interfaces don't have any instance virtual slots with the exception of interfaces that provide // IDynamicInterfaceCastable implementation. // Normal interface don't need one because the dispatch is done at the class level. // For IDynamicInterfaceCastable, we don't have an implementing class. - if (_type.IsInterface && !((MetadataType)_type).IsDynamicInterfaceCastableImplementation()) - return true; + bool isInterface = declType.IsInterface; + bool needsEntriesForInstanceInterfaceMethodImpls = !isInterface + || ((MetadataType)declType).IsDynamicInterfaceCastableImplementation(); IReadOnlyList virtualSlots = factory.VTable(declType).Slots; for (int i = 0; i < virtualSlots.Count; i++) { + if (!virtualSlots[i].Signature.IsStatic && !needsEntriesForInstanceInterfaceMethodImpls) + continue; + MethodDesc implMethod = declType.FindVirtualFunctionTargetMethodOnObjectType(virtualSlots[i]); if (implMethod.CanMethodBeInSealedVTable()) @@ -143,6 +147,10 @@ public bool BuildSealedVTableSlots(NodeFactory factory, bool relocsOnly) for (int interfaceMethodSlot = 0; interfaceMethodSlot < virtualSlots.Count; interfaceMethodSlot++) { MethodDesc declMethod = virtualSlots[interfaceMethodSlot]; + + if (!declMethod.Signature.IsStatic && !needsEntriesForInstanceInterfaceMethodImpls) + continue; + if (!interfaceType.IsTypeDefinition) declMethod = factory.TypeSystemContext.GetMethodForInstantiatedType(declMethod.GetTypicalMethodDefinition(), (InstantiatedType)interfaceDefinitionType); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/VirtualMethodCallHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/VirtualMethodCallHelper.cs index a9de1fce5e3a52..ec398d37433966 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/VirtualMethodCallHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/VirtualMethodCallHelper.cs @@ -93,9 +93,8 @@ private static int GetNumberOfSlotsInCurrentType(NodeFactory factory, TypeDesc i { if (implType.IsInterface) { - // We normally don't need to ask about vtable slots of interfaces. It's not wrong to ask - // that question, but we currently only ask it for IDynamicInterfaceCastable implementations. - Debug.Assert(((MetadataType)implType).IsDynamicInterfaceCastableImplementation()); + // Interface types don't have physically assigned virtual slots, so the number of slots + // is always 0. They may have sealed slots. return (implType.HasGenericDictionarySlot() && countDictionarySlots) ? 1 : 0; } diff --git a/src/tests/nativeaot/SmokeTests/UnitTests/Interfaces.cs b/src/tests/nativeaot/SmokeTests/UnitTests/Interfaces.cs index f163dbba5ba6c7..7ad4f974bbb09c 100644 --- a/src/tests/nativeaot/SmokeTests/UnitTests/Interfaces.cs +++ b/src/tests/nativeaot/SmokeTests/UnitTests/Interfaces.cs @@ -52,6 +52,8 @@ public static int Run() TestMoreConstraints.Run(); TestSimpleNonGeneric.Run(); TestSimpleGeneric.Run(); + TestDefaultDynamicStaticNonGeneric.Run(); + TestDefaultDynamicStaticGeneric.Run(); TestDynamicStaticGenericVirtualMethods.Run(); return Pass; @@ -1502,6 +1504,77 @@ public static void Run() } } + class TestDefaultDynamicStaticNonGeneric + { + interface IFoo + { + abstract static string ImHungryGiveMeCookie(); + } + + interface IBar : IFoo + { + static string IFoo.ImHungryGiveMeCookie() => "IBar"; + } + + class Baz : IBar + { + } + + class Gen where T : IFoo + { + public static string GrabCookie() => T.ImHungryGiveMeCookie(); + } + + public static void Run() + { + var r = (string)typeof(Gen<>).MakeGenericType(typeof(Baz)).GetMethod("GrabCookie").Invoke(null, Array.Empty()); + if (r != "IBar") + throw new Exception(r); + + r = (string)typeof(Gen<>).MakeGenericType(typeof(IBar)).GetMethod("GrabCookie").Invoke(null, Array.Empty()); + if (r != "IBar") + throw new Exception(r); + } + } + + class TestDefaultDynamicStaticGeneric + { + class Atom1 { } + class Atom2 { } + + interface IFoo + { + abstract static string ImHungryGiveMeCookie(); + } + + interface IBar : IFoo + { + static string IFoo.ImHungryGiveMeCookie() => $"IBar<{typeof(T).Name}>"; + } + + class Baz : IBar + { + } + + class Gen where T : IFoo + { + public static string GrabCookie() => T.ImHungryGiveMeCookie(); + } + + public static void Run() + { + Activator.CreateInstance(typeof(Baz<>).MakeGenericType(typeof(Atom1))); + + var r = (string)typeof(Gen<>).MakeGenericType(typeof(Baz<>).MakeGenericType(typeof(Atom1))).GetMethod("GrabCookie").Invoke(null, Array.Empty()); + if (r != "IBar") + throw new Exception(r); + + r = (string)typeof(Gen<>).MakeGenericType(typeof(IBar<>).MakeGenericType(typeof(Atom2))).GetMethod("GrabCookie").Invoke(null, Array.Empty()); + if (r != "IBar") + throw new Exception(r); + } + } + class TestDynamicStaticGenericVirtualMethods { interface IEntry From 62b57fcc780640032a3c385015633419a736508f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 12:38:59 -0600 Subject: [PATCH 128/783] Fix LDTOKEN of methods that have modifiers (#91439) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we started generating custom modifiers into metadata format to support new function pointer APIs in #85504, we should have also added it to native layout format. We currently have a mismatch. This is a low risk bugfix to ignore modifiers on the metadata side. We'll want to do a full fix to actually emit and compare this. Tracked in a .NET 9 bug at #91381. No regression test because I spent too much time being puzzled at why https://github.com/Handlebars-Net/Handlebars.Net/blob/50614fd844e5360eb10e76154aa74da4d7bf12ce/source/Handlebars/Helpers/IHelperDescriptor.cs#L13 is generated as a custom modifier (`[in] !TOptions& modreq([netstandard]System.Runtime.InteropServices.InAttribute) options`) whereas if I do it, I get `[in] !T& 'value'` with a custom attribute. We'll want to write a proper set of tests with ambiguities for the bug I opened anyway. Co-authored-by: Michal Strehovský --- ...derEnvironment.MetadataSignatureParsing.cs | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.MetadataSignatureParsing.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.MetadataSignatureParsing.cs index 07674dded3541c..1a1cd76cc4ddfd 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.MetadataSignatureParsing.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.MetadataSignatureParsing.cs @@ -173,12 +173,23 @@ internal static NativeParser GetNativeParserForSignature(RuntimeSignature signat private bool CompareTypeSigWithType(ref NativeParser parser, TypeManagerHandle moduleHandle, Handle typeHandle) { - while (typeHandle.HandleType == HandleType.TypeSpecification) + while (typeHandle.HandleType == HandleType.TypeSpecification + || typeHandle.HandleType == HandleType.ModifiedType) { - typeHandle = typeHandle - .ToTypeSpecificationHandle(_metadataReader) - .GetTypeSpecification(_metadataReader) - .Signature; + if (typeHandle.HandleType == HandleType.TypeSpecification) + { + typeHandle = typeHandle + .ToTypeSpecificationHandle(_metadataReader) + .GetTypeSpecification(_metadataReader) + .Signature; + } + else + { + typeHandle = typeHandle + .ToModifiedTypeHandle(_metadataReader) + .GetModifiedType(_metadataReader) + .Type; + } } // startOffset lets us backtrack to the TypeSignatureKind for external types since the TypeLoader From ed4863553c6c16087fab627c1020dc5531118dfb Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 15:15:06 -0600 Subject: [PATCH 129/783] Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230831.4 (#91462) optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23430.6 -> To Version 1.0.0-prerelease.23431.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index fe4d19e4449095..32f9f3c8c6fc41 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -334,21 +334,21 @@ https://github.com/dotnet/arcade 804d586c07a6c598551a2913f0958680cb9135a9 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 3fbd3234f952f4c410e35701d0b66272d27cfb6c + 07f1da26c7bd97db0defad5e38bed5e514eb960e - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 3fbd3234f952f4c410e35701d0b66272d27cfb6c + 07f1da26c7bd97db0defad5e38bed5e514eb960e - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 3fbd3234f952f4c410e35701d0b66272d27cfb6c + 07f1da26c7bd97db0defad5e38bed5e514eb960e - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 3fbd3234f952f4c410e35701d0b66272d27cfb6c + 07f1da26c7bd97db0defad5e38bed5e514eb960e https://github.com/dotnet/hotreload-utils @@ -384,13 +384,13 @@ d10b02ae5cc670609d920a672985ed4456bdd6b6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 3fbd3234f952f4c410e35701d0b66272d27cfb6c + 07f1da26c7bd97db0defad5e38bed5e514eb960e - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 3fbd3234f952f4c410e35701d0b66272d27cfb6c + 07f1da26c7bd97db0defad5e38bed5e514eb960e diff --git a/eng/Versions.props b/eng/Versions.props index 93153b418cab7c..5b7fc280e32618 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -156,12 +156,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23430.6 - 1.0.0-prerelease.23430.6 - 1.0.0-prerelease.23430.6 - 1.0.0-prerelease.23430.6 - 1.0.0-prerelease.23430.6 - 1.0.0-prerelease.23430.6 + 1.0.0-prerelease.23431.4 + 1.0.0-prerelease.23431.4 + 1.0.0-prerelease.23431.4 + 1.0.0-prerelease.23431.4 + 1.0.0-prerelease.23431.4 + 1.0.0-prerelease.23431.4 16.11.27-beta1.23180.1 2.0.0-beta4.23307.1 From 7c8fc57534e27c4cb52663e097208e3ed0cdc21e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 15:25:51 -0600 Subject: [PATCH 130/783] [release/8.0] Update dependencies from dotnet/emsdk dotnet/arcade (#91423) * Update dependencies from https://github.com/dotnet/emsdk build 20230831.1 Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rc.1.23415.5 -> To Version 8.0.0-rc.2.23431.1 Dependency coherency updates runtime.linux-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.win-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.win-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.osx-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.osx-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.win-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.win-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.osx-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.osx-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.osx-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.osx-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.osx-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.osx-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools From Version 16.0.5-alpha.1.23408.1 -> To Version 16.0.5-alpha.1.23423.1 (parent: Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport * Update dependencies from https://github.com/dotnet/arcade build 20230831.2 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23429.1 -> To Version 8.0.0-beta.23431.2 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 196 +++++++++++++++---------------- eng/Versions.props | 92 +++++++-------- eng/common/cross/toolchain.cmake | 2 +- global.json | 6 +- 4 files changed, 148 insertions(+), 148 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 32f9f3c8c6fc41..5c942861fff1de 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -12,69 +12,69 @@ https://github.com/dotnet/wcf 7f504aabb1988e9a093c1e74d8040bd52feb2f01 - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d https://github.com/dotnet/command-line-api @@ -90,9 +90,9 @@ fa5acbd2ccba88c9d46ce0dd8f5310f9d3c5c46d - + https://github.com/dotnet/emsdk - 66dbaefff04250dc72849f0172e0c53bcfb3ab38 + 300725997600f884161d74f9889251ba842e44f5 @@ -107,9 +107,9 @@ - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 @@ -117,69 +117,69 @@ 194f32828726c3f1f63f79f3dc09b9e99c157b11 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 https://github.com/dotnet/runtime-assets @@ -233,61 +233,61 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d - + https://github.com/dotnet/llvm-project - 9b77c16a6061fb1160ec12bd307badb4c58dff98 + 08a449c9a9bf593b29fc05de2f424e6882320e5d https://github.com/dotnet/runtime @@ -330,9 +330,9 @@ https://github.com/dotnet/xharness 480b9159eb7e69b182a87581d5a336e97e0b6dae - + https://github.com/dotnet/arcade - 804d586c07a6c598551a2913f0958680cb9135a9 + ec030fdef9faf8b2bd6f5f422545e8d8f7054e48 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index 5b7fc280e32618..4413d948f571ce 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -85,21 +85,21 @@ 8.0.100-preview.7.23329.3 - 8.0.0-beta.23429.1 - 8.0.0-beta.23429.1 - 8.0.0-beta.23429.1 - 8.0.0-beta.23429.1 - 8.0.0-beta.23429.1 - 2.5.1-beta.23429.1 - 8.0.0-beta.23429.1 - 8.0.0-beta.23429.1 - 8.0.0-beta.23429.1 - 8.0.0-beta.23429.1 - 8.0.0-beta.23429.1 - 8.0.0-beta.23429.1 - 8.0.0-beta.23429.1 - 8.0.0-beta.23429.1 - 8.0.0-beta.23429.1 + 8.0.0-beta.23431.2 + 8.0.0-beta.23431.2 + 8.0.0-beta.23431.2 + 8.0.0-beta.23431.2 + 8.0.0-beta.23431.2 + 2.5.1-beta.23431.2 + 8.0.0-beta.23431.2 + 8.0.0-beta.23431.2 + 8.0.0-beta.23431.2 + 8.0.0-beta.23431.2 + 8.0.0-beta.23431.2 + 8.0.0-beta.23431.2 + 8.0.0-beta.23431.2 + 8.0.0-beta.23431.2 + 8.0.0-beta.23431.2 6.0.0-preview.1.102 @@ -108,14 +108,14 @@ 8.0.0-rc.1.23406.6 8.0.0-preview.7.23325.2 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 6.0.0 1.1.1 @@ -222,38 +222,38 @@ 2.2.2 8.0.0-alpha.1.23412.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 - 8.0.0-rc.1.23415.5 + 8.0.0-rc.2.23431.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda 1.0.0-v3.14.0.5722 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 - 16.0.5-alpha.1.23408.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23423.1 3.1.7 1.0.406601 diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake index a88d643c8a765e..0998e875e5f78d 100644 --- a/eng/common/cross/toolchain.cmake +++ b/eng/common/cross/toolchain.cmake @@ -207,6 +207,7 @@ elseif(ILLUMOS) set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lssp") elseif(HAIKU) set(CMAKE_SYSROOT "${CROSS_ROOTFS}") + set(CMAKE_PROGRAM_PATH "${CMAKE_PROGRAM_PATH};${CROSS_ROOTFS}/cross-tools-x86_64/bin") set(TOOLSET_PREFIX ${TOOLCHAIN}-) function(locate_toolchain_exec exec var) @@ -217,7 +218,6 @@ elseif(HAIKU) endif() find_program(EXEC_LOCATION_${exec} - PATHS "${CROSS_ROOTFS}/cross-tools-x86_64/bin" NAMES "${TOOLSET_PREFIX}${exec}${CLR_CMAKE_COMPILER_FILE_NAME_VERSION}" "${TOOLSET_PREFIX}${exec}") diff --git a/global.json b/global.json index bdd818850a3add..dddad47ca24240 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.100-preview.7.23376.3" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23429.1", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23429.1", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23429.1", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23431.2", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23431.2", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23431.2", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From 3a811f41acfd65a9f0e53e85d533f49d9a444be1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 15:26:37 -0600 Subject: [PATCH 131/783] [release/8.0] Update dependencies from dotnet/roslyn (#91420) * Update dependencies from https://github.com/dotnet/roslyn build 20230831.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23430.6 -> To Version 4.8.0-3.23431.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230831.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23430.6 -> To Version 4.8.0-3.23431.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230831.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23430.6 -> To Version 4.8.0-3.23431.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230831.7 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23430.6 -> To Version 4.8.0-3.23431.7 * Update dependencies from https://github.com/dotnet/roslyn build 20230901.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23430.6 -> To Version 4.8.0-3.23451.1 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5c942861fff1de..f54a2c3557aa74 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - 0a5289acaadde17d768b8f69dbc35aeec74cc4f8 + 3686f3061a9202260a0de4d06e91855b0fa21e8c - + https://github.com/dotnet/roslyn - 0a5289acaadde17d768b8f69dbc35aeec74cc4f8 + 3686f3061a9202260a0de4d06e91855b0fa21e8c - + https://github.com/dotnet/roslyn - 0a5289acaadde17d768b8f69dbc35aeec74cc4f8 + 3686f3061a9202260a0de4d06e91855b0fa21e8c https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index 4413d948f571ce..b1746d96b3472f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -42,9 +42,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23430.6 - 4.8.0-3.23430.6 - 4.8.0-3.23430.6 + 4.8.0-3.23451.1 + 4.8.0-3.23451.1 + 4.8.0-3.23451.1 8.0.100-preview.7.23329.3 - 8.0.0-beta.23431.2 - 8.0.0-beta.23431.2 - 8.0.0-beta.23431.2 - 8.0.0-beta.23431.2 - 8.0.0-beta.23431.2 - 2.5.1-beta.23431.2 - 8.0.0-beta.23431.2 - 8.0.0-beta.23431.2 - 8.0.0-beta.23431.2 - 8.0.0-beta.23431.2 - 8.0.0-beta.23431.2 - 8.0.0-beta.23431.2 - 8.0.0-beta.23431.2 - 8.0.0-beta.23431.2 - 8.0.0-beta.23431.2 + 8.0.0-beta.23451.1 + 8.0.0-beta.23451.1 + 8.0.0-beta.23451.1 + 8.0.0-beta.23451.1 + 8.0.0-beta.23451.1 + 2.5.1-beta.23451.1 + 8.0.0-beta.23451.1 + 8.0.0-beta.23451.1 + 8.0.0-beta.23451.1 + 8.0.0-beta.23451.1 + 8.0.0-beta.23451.1 + 8.0.0-beta.23451.1 + 8.0.0-beta.23451.1 + 8.0.0-beta.23451.1 + 8.0.0-beta.23451.1 6.0.0-preview.1.102 @@ -209,15 +209,15 @@ 8.0.100-rc.1.23415.5 1.1.2-beta1.23323.1 - 7.0.0-preview-20221010.1 + 8.0.0-preview-20230828.1 8.0.0-rc.1.23406.6 - 0.11.4-alpha.23428.2 + 0.11.4-alpha.23454.2 8.0.0-rc.1.23406.6 - 8.0.0-rc.2.23421.2 + 8.0.0-rc.2.23454.2 2.2.2 8.0.0-alpha.1.23412.1 @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.0-rc.2.23431.1 + 8.0.0-rc.2.23455.4 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda diff --git a/global.json b/global.json index dddad47ca24240..6d208cff376c28 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.100-preview.7.23376.3" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23431.2", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23431.2", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23431.2", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23451.1", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23451.1", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23451.1", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From 1222f14d02818cfab597fa2a17c8664fe6cb39be Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 11:42:13 -0700 Subject: [PATCH 136/783] Enable output compilation validation in binder gen unit tests (#91602) Co-authored-by: Layomi Akinrinade --- .../tests/SourceGenerators/RoslynTestUtils.cs | 2 +- .../gen/Helpers/Emitter/Helpers.cs | 2 +- ...onfigurationServiceCollectionExtensions.cs | 5 +- .../Baselines/Collections.generated.txt | 2 +- .../ConfigurationBinder/Bind.generated.txt | 6 +- .../Bind_Instance.generated.txt | 2 +- .../Bind_Instance_BinderOptions.generated.txt | 2 +- .../Bind_Key_Instance.generated.txt | 2 +- .../ConfigurationBinder/Get.generated.txt | 8 +- .../GetValue.generated.txt | 8 +- .../GetValue_T_Key.generated.txt | 2 +- .../GetValue_T_Key_DefaultValue.generated.txt | 2 +- .../GetValue_TypeOf_Key.generated.txt | 2 +- ...alue_TypeOf_Key_DefaultValue.generated.txt | 2 +- .../ConfigurationBinder/Get_T.generated.txt | 2 +- .../Get_T_BinderOptions.generated.txt | 2 +- .../Get_TypeOf.generated.txt | 2 +- .../Get_TypeOf_BinderOptions.generated.txt | 2 +- .../BindConfiguration.generated.txt | 2 +- .../OptionsBuilder/Bind_T.generated.txt | 2 +- .../Bind_T_BinderOptions.generated.txt | 2 +- .../Baselines/Primitives.generated.txt | 25 ++- .../Configure_T.generated.txt | 3 +- .../Configure_T_BinderOptions.generated.txt | 3 +- .../Configure_T_name.generated.txt | 3 +- ...nfigure_T_name_BinderOptions.generated.txt | 3 +- .../GeneratorTests.Baselines.Options.cs | 2 +- .../GeneratorTests.Baselines.cs | 53 ++---- .../GeneratorTests.Helpers.cs | 171 ++++++++++++++++++ .../SourceGenerationTests/GeneratorTests.cs | 97 +--------- ...ation.Binder.SourceGeneration.Tests.csproj | 1 + 31 files changed, 245 insertions(+), 177 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs diff --git a/src/libraries/Common/tests/SourceGenerators/RoslynTestUtils.cs b/src/libraries/Common/tests/SourceGenerators/RoslynTestUtils.cs index 2b4568a79eaba0..e67289721d8af9 100644 --- a/src/libraries/Common/tests/SourceGenerators/RoslynTestUtils.cs +++ b/src/libraries/Common/tests/SourceGenerators/RoslynTestUtils.cs @@ -91,7 +91,7 @@ public static async Task AssertNoDiagnostic(this Project proj, params string[] i } } - private static Project WithDocuments(this Project project, IEnumerable sources, IEnumerable? sourceNames = null) + public static Project WithDocuments(this Project project, IEnumerable sources, IEnumerable? sourceNames = null) { int count = 0; Project result = project; diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs index 909272c7678447..60ce9f681e077f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs @@ -142,7 +142,7 @@ private void EmitInterceptsLocationAnnotations(List inf { foreach (InterceptorLocationInfo info in infoList) { - _writer.WriteLine($@"[{Identifier.InterceptsLocation}Attribute(@""{info.FilePath}"", {info.LineNumber}, {info.CharacterNumber})]"); + _writer.WriteLine($@"[{Identifier.InterceptsLocation}(@""{info.FilePath}"", {info.LineNumber}, {info.CharacterNumber})]"); } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs index b811a8e6ae0eca..d89b124b0695fb 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs @@ -85,9 +85,12 @@ @params[1].Type.SpecialType is SpecialType.System_String && private void RegisterTypeForMethodGen(MethodsToGen_Extensions_ServiceCollection overload, TypeSpec typeSpec) { + RegisterTypeForBindCoreMainGen(typeSpec); + _sourceGenSpec.MethodsToGen_ServiceCollectionExt |= overload; _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.DependencyInjection"); - RegisterTypeForBindCoreMainGen(typeSpec); + // Emitting refs to IOptionsChangeTokenSource, ConfigurationChangeTokenSource, IConfigureOptions<>, ConfigureNamedOptions<>. + _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.Options"); } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt index 5f186e42e4da7d..775d9052ded435 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt @@ -32,7 +32,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Attempts to bind the configuration instance to a new instance of type T. - [InterceptsLocationAttribute(@"src-0.cs", 12, 17)] + [InterceptsLocation(@"src-0.cs", 12, 17)] public static T? Get(this IConfiguration configuration) => (T?)(GetCore(configuration, typeof(T), configureOptions: null) ?? default(T)); #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt index 8d1f02b4e62e11..e5b37775cffd4b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt @@ -31,7 +31,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - [InterceptsLocationAttribute(@"src-0.cs", 13, 18)] + [InterceptsLocation(@"src-0.cs", 12, 14)] public static void Bind_ProgramMyClass(this IConfiguration configuration, object? instance) { if (configuration is null) @@ -49,7 +49,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - [InterceptsLocationAttribute(@"src-0.cs", 14, 24)] + [InterceptsLocation(@"src-0.cs", 13, 20)] public static void Bind_ProgramMyClass(this IConfiguration configuration, object? instance, Action? configureOptions) { if (configuration is null) @@ -67,7 +67,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - [InterceptsLocationAttribute(@"src-0.cs", 15, 24)] + [InterceptsLocation(@"src-0.cs", 14, 20)] public static void Bind_ProgramMyClass(this IConfiguration configuration, string key, object? instance) { if (configuration is null) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt index f3008878ca3c56..fc35d29e693349 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt @@ -31,7 +31,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - [InterceptsLocationAttribute(@"src-0.cs", 12, 20)] + [InterceptsLocation(@"src-0.cs", 12, 20)] public static void Bind_ProgramMyClass(this IConfiguration configuration, object? instance) { if (configuration is null) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt index 19b955b6ea8bff..0d3eb884c966e2 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt @@ -31,7 +31,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - [InterceptsLocationAttribute(@"src-0.cs", 12, 20)] + [InterceptsLocation(@"src-0.cs", 12, 20)] public static void Bind_ProgramMyClass(this IConfiguration configuration, object? instance, Action? configureOptions) { if (configuration is null) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt index 8533828221175b..392533daea462f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt @@ -31,7 +31,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - [InterceptsLocationAttribute(@"src-0.cs", 12, 20)] + [InterceptsLocation(@"src-0.cs", 12, 20)] public static void Bind_ProgramMyClass(this IConfiguration configuration, string key, object? instance) { if (configuration is null) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt index 4acbebff935bca..d0faaa8fc91513 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt @@ -31,19 +31,19 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Attempts to bind the configuration instance to a new instance of type T. - [InterceptsLocationAttribute(@"src-0.cs", 12, 38)] + [InterceptsLocation(@"src-0.cs", 12, 38)] public static T? Get(this IConfiguration configuration) => (T?)(GetCore(configuration, typeof(T), configureOptions: null) ?? default(T)); /// Attempts to bind the configuration instance to a new instance of type T. - [InterceptsLocationAttribute(@"src-0.cs", 14, 36)] + [InterceptsLocation(@"src-0.cs", 14, 36)] public static T? Get(this IConfiguration configuration, Action? configureOptions) => (T?)(GetCore(configuration, typeof(T), configureOptions) ?? default(T)); /// Attempts to bind the configuration instance to a new instance of type T. - [InterceptsLocationAttribute(@"src-0.cs", 13, 36)] + [InterceptsLocation(@"src-0.cs", 13, 56)] public static object? Get(this IConfiguration configuration, Type type) => GetCore(configuration, type, configureOptions: null); /// Attempts to bind the configuration instance to a new instance of type T. - [InterceptsLocationAttribute(@"src-0.cs", 15, 36)] + [InterceptsLocation(@"src-0.cs", 15, 47)] public static object? Get(this IConfiguration configuration, Type type, Action? configureOptions) => GetCore(configuration, type, configureOptions); #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue.generated.txt index e4bcaf6a9b7c95..bf7e64bd31f90c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue.generated.txt @@ -30,19 +30,19 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Extracts the value with the specified key and converts it to the specified type. - [InterceptsLocationAttribute(@"src-0.cs", 13, 18)] + [InterceptsLocation(@"src-0.cs", 13, 18)] public static T? GetValue(this IConfiguration configuration, string key) => (T?)(BindingExtensions.GetValueCore(configuration, typeof(T), key) ?? default(T)); /// Extracts the value with the specified key and converts it to the specified type. - [InterceptsLocationAttribute(@"src-0.cs", 16, 24)] + [InterceptsLocation(@"src-0.cs", 16, 24)] public static T? GetValue(this IConfiguration configuration, string key, T defaultValue) => (T?)(BindingExtensions.GetValueCore(configuration, typeof(T), key) ?? defaultValue); /// Extracts the value with the specified key and converts it to the specified type. - [InterceptsLocationAttribute(@"src-0.cs", 14, 24)] + [InterceptsLocation(@"src-0.cs", 14, 24)] public static object? GetValue(this IConfiguration configuration, Type type, string key) => BindingExtensions.GetValueCore(configuration, type, key); /// Extracts the value with the specified key and converts it to the specified type. - [InterceptsLocationAttribute(@"src-0.cs", 17, 24)] + [InterceptsLocation(@"src-0.cs", 17, 24)] public static object? GetValue(this IConfiguration configuration, Type type, string key, object? defaultValue) => BindingExtensions.GetValueCore(configuration, type, key) ?? defaultValue; #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key.generated.txt index 2438cf530ca4ce..b86915b78303b2 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key.generated.txt @@ -30,7 +30,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Extracts the value with the specified key and converts it to the specified type. - [InterceptsLocationAttribute(@"src-0.cs", 10, 20)] + [InterceptsLocation(@"src-0.cs", 10, 20)] public static T? GetValue(this IConfiguration configuration, string key) => (T?)(BindingExtensions.GetValueCore(configuration, typeof(T), key) ?? default(T)); #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key_DefaultValue.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key_DefaultValue.generated.txt index e6db24d522f3c9..697f710dff3027 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key_DefaultValue.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_T_Key_DefaultValue.generated.txt @@ -30,7 +30,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Extracts the value with the specified key and converts it to the specified type. - [InterceptsLocationAttribute(@"src-0.cs", 12, 20)] + [InterceptsLocation(@"src-0.cs", 12, 20)] public static T? GetValue(this IConfiguration configuration, string key, T defaultValue) => (T?)(BindingExtensions.GetValueCore(configuration, typeof(T), key) ?? defaultValue); #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key.generated.txt index a36f9fafebcff8..b5a22e71ccefbf 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key.generated.txt @@ -30,7 +30,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Extracts the value with the specified key and converts it to the specified type. - [InterceptsLocationAttribute(@"src-0.cs", 10, 20)] + [InterceptsLocation(@"src-0.cs", 10, 20)] public static object? GetValue(this IConfiguration configuration, Type type, string key) => BindingExtensions.GetValueCore(configuration, type, key); #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key_DefaultValue.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key_DefaultValue.generated.txt index 356f6bb1a933e2..4a4564796e562f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key_DefaultValue.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/GetValue_TypeOf_Key_DefaultValue.generated.txt @@ -30,7 +30,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Extracts the value with the specified key and converts it to the specified type. - [InterceptsLocationAttribute(@"src-0.cs", 11, 20)] + [InterceptsLocation(@"src-0.cs", 11, 20)] public static object? GetValue(this IConfiguration configuration, Type type, string key, object? defaultValue) => BindingExtensions.GetValueCore(configuration, type, key) ?? defaultValue; #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt index fb5cf5e4b5ca31..0b7031b1da00ba 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt @@ -31,7 +31,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Attempts to bind the configuration instance to a new instance of type T. - [InterceptsLocationAttribute(@"src-0.cs", 11, 40)] + [InterceptsLocation(@"src-0.cs", 11, 40)] public static T? Get(this IConfiguration configuration) => (T?)(GetCore(configuration, typeof(T), configureOptions: null) ?? default(T)); #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt index ac8e362b4e2e07..4c950a79266d11 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt @@ -31,7 +31,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Attempts to bind the configuration instance to a new instance of type T. - [InterceptsLocationAttribute(@"src-0.cs", 11, 40)] + [InterceptsLocation(@"src-0.cs", 11, 40)] public static T? Get(this IConfiguration configuration, Action? configureOptions) => (T?)(GetCore(configuration, typeof(T), configureOptions) ?? default(T)); #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt index 5d0088b908162d..ca323c234b8485 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt @@ -31,7 +31,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Attempts to bind the configuration instance to a new instance of type T. - [InterceptsLocationAttribute(@"src-0.cs", 11, 40)] + [InterceptsLocation(@"src-0.cs", 11, 51)] public static object? Get(this IConfiguration configuration, Type type) => GetCore(configuration, type, configureOptions: null); #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt index 9da3a3a22e9b7c..e4a376a0cb3257 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt @@ -31,7 +31,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Attempts to bind the configuration instance to a new instance of type T. - [InterceptsLocationAttribute(@"src-0.cs", 11, 20)] + [InterceptsLocation(@"src-0.cs", 11, 20)] public static object? Get(this IConfiguration configuration, Type type, Action? configureOptions) => GetCore(configuration, type, configureOptions); #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt index 96e389be895602..f3829683be2bb3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt @@ -33,7 +33,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region OptionsBuilder extensions. /// Registers the dependency injection container to bind against the obtained from the DI service provider. - [InterceptsLocationAttribute(@"src-0.cs", 12, 24)] + [InterceptsLocation(@"src-0.cs", 12, 24)] public static OptionsBuilder BindConfiguration(this OptionsBuilder optionsBuilder, string configSectionPath, Action? configureBinder = null) where TOptions : class { if (optionsBuilder is null) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt index 9755ab0df00086..de6ea5a3b9e1c6 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt @@ -33,7 +33,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region OptionsBuilder extensions. /// Registers a configuration instance which will bind against. - [InterceptsLocationAttribute(@"src-0.cs", 15, 24)] + [InterceptsLocation(@"src-0.cs", 15, 24)] public static OptionsBuilder Bind(this OptionsBuilder optionsBuilder, IConfiguration config) where TOptions : class { return Bind(optionsBuilder, config, configureBinder: null); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt index 141d2d41f77f83..2c40ebf69c9b46 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt @@ -33,7 +33,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region OptionsBuilder extensions. /// Registers a configuration instance which will bind against. - [InterceptsLocationAttribute(@"src-0.cs", 15, 24)] + [InterceptsLocation(@"src-0.cs", 15, 24)] public static OptionsBuilder Bind(this OptionsBuilder optionsBuilder, IConfiguration config, Action? configureBinder) where TOptions : class { if (optionsBuilder is null) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt index 1fd82a86d72c0d..7d94145d42a511 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt @@ -31,7 +31,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IConfiguration extensions. /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. - [InterceptsLocationAttribute(@"src-0.cs", 13, 16)] + [InterceptsLocation(@"src-0.cs", 13, 16)] public static void Bind_ProgramMyClass(this IConfiguration configuration, object? instance) { if (configuration is null) @@ -50,7 +50,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #endregion IConfiguration extensions. #region Core binding extensions. - private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "Prop0", "Prop1", "Prop2", "Prop3", "Prop4", "Prop5", "Prop6", "Prop8", "Prop9", "Prop10", "Prop13", "Prop14", "Prop15", "Prop16", "Prop17", "Prop19", "Prop20", "Prop21", "Prop23", "Prop24", "Prop25", "Prop26", "Prop27", "Prop7", "Prop11", "Prop12", "Prop18", "Prop22" }); + private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "Prop0", "Prop1", "Prop2", "Prop3", "Prop4", "Prop5", "Prop6", "Prop8", "Prop9", "Prop10", "Prop13", "Prop14", "Prop15", "Prop16", "Prop17", "Prop19", "Prop20", "Prop21", "Prop23", "Prop24", "Prop25", "Prop26", "Prop27", "Prop7", "Prop11", "Prop12", "Prop18", "Prop22", "Prop28", "Prop29", "Prop30" }); public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) { @@ -142,12 +142,12 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (configuration["Prop23"] is string value18) { - instance.Prop23 = ParseInt(value18, () => configuration.GetSection("Prop23").Path); + instance.Prop23 = ParseTimeSpan(value18, () => configuration.GetSection("Prop23").Path); } if (configuration["Prop24"] is string value19) { - instance.Prop24 = ParseDateTime(value19, () => configuration.GetSection("Prop24").Path); + instance.Prop24 = ParseGuid(value19, () => configuration.GetSection("Prop24").Path); } if (configuration["Prop25"] is string value20) @@ -187,7 +187,22 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (configuration["Prop22"] is string value27) { - instance.Prop22 = ParseByteArray(value27, () => configuration.GetSection("Prop22").Path); + instance.Prop22 = ParseTimeOnly(value27, () => configuration.GetSection("Prop22").Path); + } + + if (configuration["Prop28"] is string value28) + { + instance.Prop28 = ParseByteArray(value28, () => configuration.GetSection("Prop28").Path); + } + + if (configuration["Prop29"] is string value29) + { + instance.Prop29 = ParseInt(value29, () => configuration.GetSection("Prop29").Path); + } + + if (configuration["Prop30"] is string value30) + { + instance.Prop30 = ParseDateTime(value30, () => configuration.GetSection("Prop30").Path); } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt index 0ff2de59156df9..973895e09fe55e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt @@ -21,6 +21,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Options; using System; using System.CodeDom.Compiler; using System.Collections.Generic; @@ -32,7 +33,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IServiceCollection extensions. /// Registers a configuration instance which TOptions will bind against. - [InterceptsLocationAttribute(@"src-0.cs", 14, 18)] + [InterceptsLocation(@"src-0.cs", 14, 18)] public static IServiceCollection Configure(this IServiceCollection services, IConfiguration config) where TOptions : class { return Configure(services, string.Empty, config, configureOptions: null); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt index 7058edb884007f..08f233aff5503b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt @@ -21,6 +21,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Options; using System; using System.CodeDom.Compiler; using System.Collections.Generic; @@ -32,7 +33,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IServiceCollection extensions. /// Registers a configuration instance which TOptions will bind against. - [InterceptsLocationAttribute(@"src-0.cs", 14, 18)] + [InterceptsLocation(@"src-0.cs", 14, 18)] public static IServiceCollection Configure(this IServiceCollection services, IConfiguration config, Action? configureOptions) where TOptions : class { return Configure(services, string.Empty, config, configureOptions); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt index a8f247779978ca..cb41ea860980a9 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt @@ -21,6 +21,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Options; using System; using System.CodeDom.Compiler; using System.Collections.Generic; @@ -32,7 +33,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IServiceCollection extensions. /// Registers a configuration instance which TOptions will bind against. - [InterceptsLocationAttribute(@"src-0.cs", 14, 18)] + [InterceptsLocation(@"src-0.cs", 14, 18)] public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration config) where TOptions : class { return Configure(services, name, config, configureOptions: null); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt index 0cbd2fba049558..0a5e5a7ff6d26c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt @@ -21,6 +21,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Options; using System; using System.CodeDom.Compiler; using System.Collections.Generic; @@ -32,7 +33,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { #region IServiceCollection extensions. /// Registers a configuration instance which TOptions will bind against. - [InterceptsLocationAttribute(@"src-0.cs", 14, 18)] + [InterceptsLocation(@"src-0.cs", 14, 18)] public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration config, Action? configureOptions) where TOptions : class { if (services is null) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.Options.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.Options.cs index 0126744eacbfa4..c3d1ce89c1206f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.Options.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.Options.cs @@ -20,7 +20,7 @@ public static void Main() { ConfigurationBuilder configurationBuilder = new(); IConfiguration config = configurationBuilder.Build(); - IConfigurationSection section = config.GetSection(""MySection""); + IConfigurationSection section = config.GetSection("MySection"); ServiceCollection services = new(); services.Configure({{paramList}}); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs index 65e812d30b420f..7b3251e7fc85dc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs @@ -5,46 +5,15 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; using Xunit; namespace Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests { public partial class ConfigurationBindingGeneratorTests { - private const string BindCallSampleCode = @" - using System.Collections.Generic; - using Microsoft.Extensions.Configuration; - - public class Program - { - public static void Main() - { - ConfigurationBuilder configurationBuilder = new(); - IConfigurationRoot config = configurationBuilder.Build(); - - MyClass configObj = new(); - config.Bind(configObj); - config.Bind(configObj, options => { }); - config.Bind(""key"", configObj); - } - - public class MyClass - { - public string MyString { get; set; } - public int MyInt { get; set; } - public List MyList { get; set; } - public Dictionary MyDictionary { get; set; } - public Dictionary MyComplexDictionary { get; set; } - } - - public class MyClass2 { } - }"; - - [Theory] - [InlineData(LanguageVersion.Preview)] - public async Task Bind(LanguageVersion langVersion) => - await VerifyAgainstBaselineUsingFile("Bind.generated.txt", BindCallSampleCode, langVersion, extType: ExtensionClassType.ConfigurationBinder); + [Fact] + public async Task Bind() => + await VerifyAgainstBaselineUsingFile("Bind.generated.txt", BindCallSampleCode, extType: ExtensionClassType.ConfigurationBinder); [Fact] public async Task Bind_Instance() @@ -163,9 +132,9 @@ public static void Main() IConfigurationRoot config = configurationBuilder.Build(); MyClass configObj = config.Get(); - configObj = config.Get(typeof(MyClass2)); + MyClass2 configObj2 = (MyClass2)config.Get(typeof(MyClass2)); configObj = config.Get(binderOptions => { }); - configObj = config.Get(typeof(MyClass2), binderOptions => { }); + configObj2 = (MyClass2)config.Get(typeof(MyClass2), binderOptions => { }); } public class MyClass @@ -302,7 +271,7 @@ public static void Main() ConfigurationBuilder configurationBuilder = new(); IConfigurationRoot config = configurationBuilder.Build(); - MyClass configObj = config.Get(typeof(MyClass2)); + MyClass2 configObj = (MyClass2)config.Get(typeof(MyClass2)); } public class MyClass @@ -590,9 +559,9 @@ public class MyClass public UInt128 Prop12 { get; set; } public DateOnly Prop18 { get; set; } public TimeOnly Prop22 { get; set; } - public byte[] Prop22 { get; set; } - public int Prop23 { get; set; } - public DateTime Prop24 { get; set; } + public byte[] Prop28 { get; set; } + public int Prop29 { get; set; } + public DateTime Prop30 { get; set; } } } """; @@ -613,7 +582,7 @@ public static void Main() { ConfigurationBuilder configurationBuilder = new(); IConfiguration config = configurationBuilder.Build(); - IConfigurationSection section = config.GetSection(""MySection""); + IConfigurationSection section = config.GetSection("MySection"); section.Get(); } @@ -647,7 +616,7 @@ public interface ICustomSet : ISet } """; - await VerifyAgainstBaselineUsingFile("Collections.generated.txt", source, assessDiagnostics: (d) => + await VerifyAgainstBaselineUsingFile("Collections.generated.txt", source, validateOutputCompDiags: false, assessDiagnostics: (d) => { Assert.Equal(3, d.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); Assert.Equal(6, d.Where(diag => diag.Id == Diagnostics.PropertyNotSupported.Id).Count()); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs new file mode 100644 index 00000000000000..d8818bcf3c1d4c --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs @@ -0,0 +1,171 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration.Binder.SourceGeneration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using SourceGenerators.Tests; +using Xunit; + +namespace Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests +{ + public partial class ConfigurationBindingGeneratorTests + { + private const string BindCallSampleCode = """ + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfigurationRoot config = configurationBuilder.Build(); + + MyClass configObj = new(); + config.Bind(configObj); + config.Bind(configObj, options => { }); + config.Bind("key", configObj); + } + + public class MyClass + { + public string MyString { get; set; } + public int MyInt { get; set; } + public List MyList { get; set; } + public Dictionary MyDictionary { get; set; } + public Dictionary MyComplexDictionary { get; set; } + } + + public class MyClass2 { } + } + """; + + private static class Diagnostics + { + public static (string Id, string Title) TypeNotSupported = ("SYSLIB1100", "Did not generate binding logic for a type"); + public static (string Id, string Title) PropertyNotSupported = ("SYSLIB1101", "Did not generate binding logic for a property on a type"); + public static (string Id, string Title) ValueTypesInvalidForBind = ("SYSLIB1103", "Value types are invalid inputs to configuration 'Bind' methods"); + public static (string Id, string Title) CouldNotDetermineTypeInfo = ("SYSLIB1104", "The target type for a binder call could not be determined"); + } + + private static readonly Assembly[] s_compilationAssemblyRefs = new[] { + typeof(ConfigurationBinder).Assembly, + typeof(ConfigurationBuilder).Assembly, + typeof(CultureInfo).Assembly, + typeof(Dictionary<,>).Assembly, + typeof(Enumerable).Assembly, + typeof(IConfiguration).Assembly, + typeof(IServiceCollection).Assembly, + typeof(IServiceProvider).Assembly, + typeof(IDictionary).Assembly, + typeof(OptionsBuilder<>).Assembly, + typeof(OptionsConfigurationServiceCollectionExtensions).Assembly, + typeof(Uri).Assembly, + }; + + private enum ExtensionClassType + { + None, + ConfigurationBinder, + OptionsBuilder, + ServiceCollection, + } + + private static async Task VerifyAgainstBaselineUsingFile( + string filename, + string testSourceCode, + Action>? assessDiagnostics = null, + ExtensionClassType extType = ExtensionClassType.None, + bool validateOutputCompDiags = true) + { + string path = extType is ExtensionClassType.None + ? Path.Combine("Baselines", filename) + : Path.Combine("Baselines", extType.ToString(), filename); + string baseline = LineEndingsHelper.Normalize(await File.ReadAllTextAsync(path).ConfigureAwait(false)); + string[] expectedLines = baseline.Replace("%VERSION%", typeof(ConfigurationBindingGenerator).Assembly.GetName().Version?.ToString()) + .Split(Environment.NewLine); + + var (d, r) = await RunGenerator(testSourceCode, validateOutputCompDiags); + bool success = RoslynTestUtils.CompareLines(expectedLines, r[0].SourceText, out string errorMessage); + +#if UPDATE_BASELINES + if (!success) + { + string? repoRootDir = Environment.GetEnvironmentVariable("RepoRootDir"); + Assert.True(repoRootDir is not null, "To update baselines, specifiy the root runtime repo dir"); + + IEnumerable lines = r[0].SourceText.Lines.Select(l => l.ToString()); + string source = string.Join(Environment.NewLine, lines).TrimEnd(Environment.NewLine.ToCharArray()) + Environment.NewLine; + path = Path.Combine($"{repoRootDir}\\src\\libraries\\Microsoft.Extensions.Configuration.Binder\\tests\\SourceGenerationTests\\", path); + + await File.WriteAllTextAsync(path, source).ConfigureAwait(false); + success = true; + } +#endif + + Assert.Single(r); + (assessDiagnostics ?? ((d) => Assert.Empty(d))).Invoke(d); + Assert.True(success, errorMessage); + } + + private static async Task<(ImmutableArray, ImmutableArray)> RunGenerator( + string testSourceCode, + bool validateOutputCompDiags = false, + LanguageVersion langVersion = LanguageVersion.CSharp12, + IEnumerable? references = null) + { + using var workspace = RoslynTestUtils.CreateTestWorkspace(); + CSharpParseOptions parseOptions = new CSharpParseOptions(langVersion).WithFeatures(new[] { new KeyValuePair("InterceptorsPreview", "") }); + + Project proj = RoslynTestUtils.CreateTestProject(workspace, references ?? s_compilationAssemblyRefs, langVersion: langVersion) + .WithCompilationOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithNullableContextOptions(NullableContextOptions.Annotations)) + .WithDocuments(new string[] { testSourceCode }) + .WithParseOptions(parseOptions); + + Assert.True(proj.Solution.Workspace.TryApplyChanges(proj.Solution)); + + Compilation comp = await proj.GetCompilationAsync(CancellationToken.None).ConfigureAwait(false); + CSharpGeneratorDriver cgd = CSharpGeneratorDriver.Create(new[] { new ConfigurationBindingGenerator().AsSourceGenerator() }, parseOptions: parseOptions); + GeneratorDriver gd = cgd.RunGeneratorsAndUpdateCompilation(comp, out Compilation outputCompilation, out _, CancellationToken.None); + GeneratorDriverRunResult runResult = gd.GetRunResult(); + + if (validateOutputCompDiags) + { + Assert.False(outputCompilation.GetDiagnostics().Any(d => d.Severity > DiagnosticSeverity.Info)); + } + + return (runResult.Results[0].Diagnostics, runResult.Results[0].GeneratedSources); + } + + public static List GetAssemblyRefsWithAdditional(params Type[] additional) + { + List assemblies = new(s_compilationAssemblyRefs); + assemblies.AddRange(additional.Select(t => t.Assembly)); + return assemblies; + } + + public static HashSet GetFilteredAssemblyRefs(IEnumerable exclusions) + { + HashSet assemblies = new(s_compilationAssemblyRefs); + foreach (Type exclusion in exclusions) + { + assemblies.Remove(exclusion.Assembly); + } + return assemblies; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs index 33a4d04834b57a..3fddad379397ef 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs @@ -6,19 +6,15 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Globalization; -using System.IO; using System.Linq; -using System.Reflection; using System.Text; using System.Text.Json; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Configuration.Binder.SourceGeneration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using SourceGenerators.Tests; using Xunit; namespace Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests @@ -26,39 +22,12 @@ namespace Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests [ActiveIssue("https://github.com/dotnet/runtime/issues/52062", TestPlatforms.Browser)] public partial class ConfigurationBindingGeneratorTests : ConfigurationBinderTestsBase { - private static class Diagnostics - { - public static (string Id, string Title) TypeNotSupported = ("SYSLIB1100", "Did not generate binding logic for a type"); - public static (string Id, string Title) PropertyNotSupported = ("SYSLIB1101", "Did not generate binding logic for a property on a type"); - public static (string Id, string Title) ValueTypesInvalidForBind = ("SYSLIB1103", "Value types are invalid inputs to configuration 'Bind' methods"); - public static (string Id, string Title) CouldNotDetermineTypeInfo = ("SYSLIB1104", "The target type for a binder call could not be determined"); - } - - private static readonly Assembly[] s_compilationAssemblyRefs = new[] { - typeof(ConfigurationBinder).Assembly, - typeof(CultureInfo).Assembly, - typeof(IConfiguration).Assembly, - typeof(IServiceCollection).Assembly, - typeof(IDictionary).Assembly, - typeof(OptionsBuilder<>).Assembly, - typeof(OptionsConfigurationServiceCollectionExtensions).Assembly, - typeof(Uri).Assembly, - }; - - private enum ExtensionClassType - { - None, - ConfigurationBinder, - OptionsBuilder, - ServiceCollection, - } - [Theory] [InlineData(LanguageVersion.CSharp11)] [InlineData(LanguageVersion.CSharp10)] public async Task LangVersionMustBeCharp12OrHigher(LanguageVersion langVersion) { - var (d, r) = await RunGenerator(BindCallSampleCode, langVersion); + var (d, r) = await RunGenerator(BindCallSampleCode, langVersion: langVersion); Assert.Empty(r); Diagnostic diagnostic = Assert.Single(d); @@ -371,69 +340,5 @@ public class AnotherGraphWithUnsupportedMembers Assert.Equal(12, d.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); Assert.Equal(10, d.Where(diag => diag.Id == Diagnostics.PropertyNotSupported.Id).Count()); } - - private static async Task VerifyAgainstBaselineUsingFile( - string filename, - string testSourceCode, - LanguageVersion languageVersion = LanguageVersion.Preview, - Action>? assessDiagnostics = null, - ExtensionClassType extType = ExtensionClassType.None) - { - string path = extType is ExtensionClassType.None - ? Path.Combine("Baselines", filename) - : Path.Combine("Baselines", extType.ToString(), filename); - string baseline = LineEndingsHelper.Normalize(await File.ReadAllTextAsync(path).ConfigureAwait(false)); - string[] expectedLines = baseline.Replace("%VERSION%", typeof(ConfigurationBindingGenerator).Assembly.GetName().Version?.ToString()) - .Split(Environment.NewLine); - - var (d, r) = await RunGenerator(testSourceCode, languageVersion); - bool success = RoslynTestUtils.CompareLines(expectedLines, r[0].SourceText, out string errorMessage); - -#if UPDATE_BASELINES - if (!success) - { - string? repoRootDir = Environment.GetEnvironmentVariable("RepoRootDir"); - Assert.True(repoRootDir is not null, "To update baselines, specifiy the root runtime repo dir"); - - IEnumerable lines = r[0].SourceText.Lines.Select(l => l.ToString()); - string source = string.Join(Environment.NewLine, lines).TrimEnd(Environment.NewLine.ToCharArray()) + Environment.NewLine; - path = Path.Combine($"{repoRootDir}\\src\\libraries\\Microsoft.Extensions.Configuration.Binder\\tests\\SourceGenerationTests\\", path); - - await File.WriteAllTextAsync(path, source).ConfigureAwait(false); - success = true; - } -#endif - - Assert.Single(r); - (assessDiagnostics ?? ((d) => Assert.Empty(d))).Invoke(d); - Assert.True(success, errorMessage); - } - - private static async Task<(ImmutableArray, ImmutableArray)> RunGenerator( - string testSourceCode, - LanguageVersion langVersion = LanguageVersion.Preview, - IEnumerable? references = null) => - await RoslynTestUtils.RunGenerator( - new ConfigurationBindingGenerator(), - references ?? s_compilationAssemblyRefs, - new[] { testSourceCode }, - langVersion: langVersion).ConfigureAwait(false); - - public static List GetAssemblyRefsWithAdditional(params Type[] additional) - { - List assemblies = new(s_compilationAssemblyRefs); - assemblies.AddRange(additional.Select(t => t.Assembly)); - return assemblies; - } - - public static HashSet GetFilteredAssemblyRefs(IEnumerable exclusions) - { - HashSet assemblies = new(s_compilationAssemblyRefs); - foreach (Type exclusion in exclusions) - { - assemblies.Remove(exclusion.Assembly); - } - return assemblies; - } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj index 94d95564a47352..49ee1c1f968c06 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj @@ -54,6 +54,7 @@ + From e500806c224cb58328936133ca7a7bde896b514c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 12:52:57 -0700 Subject: [PATCH 137/783] [release/8.0] Enable interceptors implicitly in binder gen nupkg when generator is enabled (#91559) * Enable interceptors implicitly in binder gen nupkg when generator is enabled * Simplify impl & remove unneeded target --------- Co-authored-by: Layomi Akinrinade --- .../Microsoft.Extensions.Configuration.Binder.targets | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/buildTransitive/Microsoft.Extensions.Configuration.Binder.targets b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/buildTransitive/Microsoft.Extensions.Configuration.Binder.targets index f091c7a57b23ae..fdfd48d12a75ad 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/buildTransitive/Microsoft.Extensions.Configuration.Binder.targets +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/buildTransitive/Microsoft.Extensions.Configuration.Binder.targets @@ -1,5 +1,10 @@ - + + $(InterceptorsPreviewNamespaces);Microsoft.Extensions.Configuration.Binder.SourceGeneration + + + @@ -8,8 +13,8 @@ - + <_Microsoft_Extensions_Configuration_Binder_Compatible_TargetFramework Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'netcoreapp2.0')) AND From b40f21207a12c813069e03eecf16af4e378b4b4c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 16:54:27 -0700 Subject: [PATCH 138/783] [release/8.0] Add late binding lookup in VB.NET for COM objects (#91433) * Add late binding lookup in VB.NET for COM objects * Review feedback * Feedback --------- Co-authored-by: Aaron R Robinson --- .../CompilerServices/NewLateBinding.vb | 33 +++++++++++++++++-- .../VisualBasic/CompilerServices/Symbols.vb | 6 ++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/NewLateBinding.vb b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/NewLateBinding.vb index de0bde5e73a2f0..5d2f624b7a6b93 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/NewLateBinding.vb +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/NewLateBinding.vb @@ -47,6 +47,10 @@ Namespace Microsoft.VisualBasic.CompilerServices baseReference = New Container(Instance) End If + If baseReference.IsCOMObject AndAlso Not baseReference.IsWindowsRuntimeObject Then + Return LateBinding.InternalLateCall(Instance, Type, MemberName, Arguments, ArgumentNames, CopyBack, IgnoreReturn) + End If + Dim idmop As IDynamicMetaObjectProvider = IDOUtils.TryCastToIDMOP(Instance) If idmop IsNot Nothing AndAlso TypeArguments Is NoTypeArguments Then Return IDOBinder.IDOCall(idmop, MemberName, Arguments, ArgumentNames, CopyBack, IgnoreReturn) @@ -139,7 +143,7 @@ Namespace Microsoft.VisualBasic.CompilerServices ' LateCallInvokeDefault is used to optionally invoke the default action on a call target. ' If the arguments are non-empty, then it isn't optional, and is treated ' as an error if there is no default action. - ' Currently we can get here only in the process of execution of NewLateBinding.LateCall. + ' Currently we can get here only in the process of execution of NewLateBinding.LateCall. @@ -155,7 +159,7 @@ Namespace Microsoft.VisualBasic.CompilerServices ' LateGetInvokeDefault is used to optionally invoke the default action. ' If the arguments are non-empty, then it isn't optional, and is treated ' as an error if there is no default action. - ' Currently we can get here only in the process of execution of NewLateBinding.LateGet. + ' Currently we can get here only in the process of execution of NewLateBinding.LateGet. @@ -167,7 +171,7 @@ Namespace Microsoft.VisualBasic.CompilerServices ' According to a comment in VBGetBinder.FallbackInvoke, this function is called when ' "The DLR was able to resolve o.member, but not o.member(args)" - ' When NewLateBinding.LateGet is evaluating similar expression itself, it never tries to invoke default action + ' When NewLateBinding.LateGet is evaluating similar expression itself, it never tries to invoke default action ' if arguments are not empty. It simply returns result of evaluating o.member. I believe, it makes sense ' to follow the same logic here. I.e., if there are no arguments, simply return the instance unless it is an IDO. @@ -278,6 +282,9 @@ Namespace Microsoft.VisualBasic.CompilerServices If argumentNames Is Nothing Then argumentNames = NoArgumentNames Dim baseReference As Container = New Container(instance) + If baseReference.IsCOMObject AndAlso Not baseReference.IsWindowsRuntimeObject Then + Return LateBinding.LateIndexGet(instance, arguments, argumentNames) + End If 'An r-value expression o(a) has two possible forms: ' 1: o(a) array lookup--where o is an array object and a is a set of indices @@ -372,6 +379,10 @@ Namespace Microsoft.VisualBasic.CompilerServices baseReference = New Container(Instance) End If + If baseReference.IsCOMObject AndAlso Not baseReference.IsWindowsRuntimeObject Then + Return LateBinding.LateGet(Instance, Type, MemberName, Arguments, ArgumentNames, CopyBack) + End If + Dim invocationFlags As BindingFlags = BindingFlagsInvokeMethod Or BindingFlagsGetProperty Dim idmop As IDynamicMetaObjectProvider = IDOUtils.TryCastToIDMOP(Instance) @@ -653,6 +664,10 @@ Namespace Microsoft.VisualBasic.CompilerServices End If Dim methodName As String = "" + If baseReference.IsCOMObject AndAlso Not baseReference.IsWindowsRuntimeObject Then + LateBinding.LateIndexSetComplex(instance, arguments, argumentNames, optimisticSet, rValueBase) + Return + End If Dim invocationFlags As BindingFlags = BindingFlagsSetProperty @@ -927,6 +942,18 @@ Namespace Microsoft.VisualBasic.CompilerServices baseReference = New Container(Instance) End If + If baseReference.IsCOMObject AndAlso Not baseReference.IsWindowsRuntimeObject Then + Try + LateBinding.InternalLateSet(Instance, Type, MemberName, Arguments, ArgumentNames, OptimisticSet, CallType) + If RValueBase And Type.IsValueType Then + Throw New Exception(Utils.GetResourceString(SR.RValueBaseForValueType, baseReference.VBFriendlyName, baseReference.VBFriendlyName)) + End If + Return + Catch ex As MissingMemberException When OptimisticSet + Return + End Try + End If + Dim invocationFlags As BindingFlags ' If we have a IDO that implements TryGetMember for a property but not TrySetMember then we could land up diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Symbols.vb b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Symbols.vb index 8301ee324af3fc..44c694595b35bb 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Symbols.vb +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Symbols.vb @@ -823,6 +823,12 @@ Namespace Microsoft.VisualBasic.CompilerServices End Get End Property + Friend ReadOnly Property IsCOMObject() As Boolean + Get + Return _type.IsCOMObject + End Get + End Property + Friend ReadOnly Property VBFriendlyName() As String Get Return Utils.VBFriendlyName(_type, _instance) From da3500bb02343b1d0424c74ccdddbc592b5b3f4f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 08:18:26 -0700 Subject: [PATCH 139/783] Add Microsoft.Extensions.Options.SourceGeneration To TransitivePackage (#91700) Co-authored-by: Tarek Mahmoud Sayed --- .../src/Microsoft.Internal.Runtime.AspNetCore.Transport.proj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libraries/Microsoft.Internal.Runtime.AspNetCore.Transport/src/Microsoft.Internal.Runtime.AspNetCore.Transport.proj b/src/libraries/Microsoft.Internal.Runtime.AspNetCore.Transport/src/Microsoft.Internal.Runtime.AspNetCore.Transport.proj index 611ac6d7d33814..732c102bab245b 100644 --- a/src/libraries/Microsoft.Internal.Runtime.AspNetCore.Transport/src/Microsoft.Internal.Runtime.AspNetCore.Transport.proj +++ b/src/libraries/Microsoft.Internal.Runtime.AspNetCore.Transport/src/Microsoft.Internal.Runtime.AspNetCore.Transport.proj @@ -34,5 +34,8 @@ + From 49b266d7eb231affbe24cddb186f9f27fe98014a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 18:56:38 -0700 Subject: [PATCH 140/783] Split the informational version on both SemVer2 separators, not just '-'. (#91760) This fixes a build break found when we stabilize the package version (and the only separator in the informational version is '+' before the commit id) Co-authored-by: Jeremy Koritzinsky --- .../AnalyzerConfigOptionsExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/AnalyzerConfigOptionsExtensions.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/AnalyzerConfigOptionsExtensions.cs index c7cfc69972d337..65f188ae1f7175 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/AnalyzerConfigOptionsExtensions.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/AnalyzerConfigOptionsExtensions.cs @@ -20,8 +20,8 @@ public static class AnalyzerConfigOptionsExtensions // Parse from the informational version as that is the only version that always matches the TFM version // even in debug builds. private static readonly Version ThisAssemblyVersion = Version.Parse( - typeof(IncrementalGeneratorInitializationContextExtensions).Assembly - .GetCustomAttribute().InformationalVersion.Split('-')[0]); + typeof(AnalyzerConfigOptionsExtensions).Assembly + .GetCustomAttribute().InformationalVersion.Split('-', '+')[0]); public static TargetFrameworkSettings GetTargetFrameworkSettings(this AnalyzerConfigOptions options) { From 467e23ffb4242c2891dab28c1e548a4bc71ef065 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 07:42:45 -0700 Subject: [PATCH 141/783] JIT: Fix invalid memory barrier removal optimization (#91870) The ARM32/ARM64 backends have an optimization where they optimize out the latter of two subsequent memory barriers if no memory store/load has been seen between them. This optimization should not be allowed to remove memory barriers when a call has been seen. Fix #91732 Co-authored-by: Jakob Botsch Nielsen --- src/coreclr/jit/emitarm.cpp | 1 + src/coreclr/jit/emitarm64.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index a0dc786782b0bc..784f797bc5efed 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -4850,6 +4850,7 @@ void emitter::emitIns_Call(EmitCallType callType, dispIns(id); appendToCurIG(id); + emitLastMemBarrier = nullptr; // Cannot optimize away future memory barriers } /***************************************************************************** diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index f01ad548d2ee04..ef1220e325e47c 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -8886,6 +8886,7 @@ void emitter::emitIns_Call(EmitCallType callType, dispIns(id); appendToCurIG(id); + emitLastMemBarrier = nullptr; // Cannot optimize away future memory barriers } /***************************************************************************** From 1ce9687c01aa45348ba72853676d1e05178f372b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 07:44:55 -0700 Subject: [PATCH 142/783] [release/8.0] JIT: Fix invalid zero-init suppression for untracked variables (#91840) * JIT: Fix invalid zero-init supression for untracked variables optRemoveRedundantZeroInits has logic to remove unnecessary zero inits if we can determine that the local will be zeroed in the prolog. In addition, it also has logic to suppress the prolog zero init if there is a dominating initialization already. The latter logic was trying to reason about liveness for untracked locals, which does not make sense. Fix #91576 * Make EH succ logic less conservative --------- Co-authored-by: Jakob Botsch Nielsen Co-authored-by: Jeff Schwartz --- src/coreclr/jit/optimizer.cpp | 16 +++--- .../JitBlue/Runtime_91576/Runtime_91576.cs | 51 +++++++++++++++++++ .../Runtime_91576/Runtime_91576.csproj | 8 +++ 3 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91576/Runtime_91576.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91576/Runtime_91576.csproj diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index 684f71b898f313..7c99a6a423dd01 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -9031,9 +9031,9 @@ void Compiler::optRemoveRedundantZeroInits() CompAllocator allocator(getAllocator(CMK_ZeroInit)); LclVarRefCounts refCounts(allocator); BitVecTraits bitVecTraits(lvaCount, this); - BitVec zeroInitLocals = BitVecOps::MakeEmpty(&bitVecTraits); - bool hasGCSafePoint = false; - bool canThrow = false; + BitVec zeroInitLocals = BitVecOps::MakeEmpty(&bitVecTraits); + bool hasGCSafePoint = false; + bool hasImplicitControlFlow = false; assert(fgNodeThreading == NodeThreading::AllTrees); @@ -9044,6 +9044,8 @@ void Compiler::optRemoveRedundantZeroInits() CompAllocator allocator(getAllocator(CMK_ZeroInit)); LclVarRefCounts defsInBlock(allocator); bool removedTrackedDefs = false; + bool hasEHSuccs = block->HasPotentialEHSuccs(this); + for (Statement* stmt = block->FirstNonPhiDef(); stmt != nullptr;) { Statement* next = stmt->GetNextStmt(); @@ -9054,10 +9056,7 @@ void Compiler::optRemoveRedundantZeroInits() hasGCSafePoint = true; } - if ((tree->gtFlags & GTF_EXCEPT) != 0) - { - canThrow = true; - } + hasImplicitControlFlow |= hasEHSuccs && ((tree->gtFlags & GTF_EXCEPT) != 0); switch (tree->gtOper) { @@ -9203,7 +9202,8 @@ void Compiler::optRemoveRedundantZeroInits() } } - if (!removedExplicitZeroInit && isEntire && (!canThrow || !lclDsc->lvLiveInOutOfHndlr)) + if (!removedExplicitZeroInit && isEntire && + (!hasImplicitControlFlow || (lclDsc->lvTracked && !lclDsc->lvLiveInOutOfHndlr))) { // If compMethodRequiresPInvokeFrame() returns true, lower may later // insert a call to CORINFO_HELP_INIT_PINVOKE_FRAME which is a gc-safe point. diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91576/Runtime_91576.cs b/src/tests/JIT/Regression/JitBlue/Runtime_91576/Runtime_91576.cs new file mode 100644 index 00000000000000..4df185d99ab241 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91576/Runtime_91576.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license.aa + +// Generated by Fuzzlyn v1.6 on 2023-09-03 15:59:01 +// Run on X64 Windows +// Seed: 11520325105937570553 +// Reduced from 294.5 KiB to 0.7 KiB in 00:04:32 +// Debug: Outputs False +// Release: Outputs True +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_91576 +{ + [Fact] + public static int TestEntryPoint() + { + Assert.Throws(() => + { + Run(new int[1]); + Run(null); + }); + + return s_result; + } + + static int s_result; + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Run(int[] l) + { + bool b = false; + try + { + int result = l[0]; + b = true; + } + finally + { + Check(ref b); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Check(ref bool b) + { + s_result = b ? 101 : 100; + } +} + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91576/Runtime_91576.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_91576/Runtime_91576.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91576/Runtime_91576.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From dbec2046adc49de5970af5a4482e68c06c4f39d2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 07:45:57 -0700 Subject: [PATCH 143/783] [release/8.0] JIT: Handle mistyped commas in morph in pre-order too (#91718) * JIT: Compensate for mistyped commas in morph pre-order too Morph has post-order logic to compensate for mistyped commas produced by impStoreStruct. However, block morphing can optimize unused stores into INDs; this interacts with the mistyped commas to produce illegal IR shapes (e.g. `COMMA(..., IND(...))`). The ideal solution is to fix impStoreStruct (#91586 tracks this), but this change has a more surgical fix for the problem that can be backported to .NET 8. Fix #91443 * Fix build --------- Co-authored-by: Jakob Botsch Nielsen Co-authored-by: Jeff Schwartz --- src/coreclr/jit/morph.cpp | 8 +++++++ .../JitBlue/Runtime_91443/Runtime_91443.cs | 23 +++++++++++++++++++ .../Runtime_91443/Runtime_91443.csproj | 8 +++++++ 3 files changed, 39 insertions(+) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91443/Runtime_91443.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91443/Runtime_91443.csproj diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 52454b0c8b7316..153f9b8bba8a82 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -8919,6 +8919,14 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA break; #endif + case GT_COMMA: + if (op2->OperIsStore() || (op2->OperGet() == GT_COMMA && op2->TypeGet() == TYP_VOID) || fgIsThrow(op2)) + { + typ = tree->gtType = TYP_VOID; + } + + break; + default: break; } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91443/Runtime_91443.cs b/src/tests/JIT/Regression/JitBlue/Runtime_91443/Runtime_91443.cs new file mode 100644 index 00000000000000..d3844b77271dd7 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91443/Runtime_91443.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Numerics; +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_91443 +{ + [Fact] + public static void TestEntryPoint() + { + new Runtime_91443().Method0(); + } + + static Vector3 s; + + [MethodImpl(MethodImplOptions.NoInlining)] + private void Method0() + { + Vector3.Cross(s, s); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91443/Runtime_91443.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_91443/Runtime_91443.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91443/Runtime_91443.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From af44ecbcf83fcae54acfd0d34032ecc7fab6e633 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 07:47:18 -0700 Subject: [PATCH 144/783] [release/8.0] Emit less metadata for not-reflection-visible types (#91703) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Emit less metadata for not-reflection-visible types In .NET 8 we massively regressed the size of an empty WinForms app. A WinForms app now brings in a big chunk of WPF with it. I traced it down to the `ICommand` interface having a WPF `TypeConverter` and `ValueSerializer` attribute on it: https://github.com/dotnet/runtime/blob/04bd438844482c907062583153a43a9e3b37dbb8/src/libraries/System.ObjectModel/src/System/Windows/Input/ICommand.cs#L13-L16. An empty app will have a call to a method on `ICommand`, but nothing actually implements `ICommand`. Previously this would mean we generate an unconstructed `MethodTable` for `ICommand`, the unconstructed `MethodTable`s get no reflection metadata, and that's the end of the story. After #85810 however, the reflection stack can no longer reason about `MethodTable`s that don't have reflection metadata, so we need to generate it. This means we end up with the custom attribute and all the reflection dataflow that comes out of it. But this metadata is not actually visible in trim safe apps (the only place where reflection could see these method tables in trim safe code is if they're used in a type comparison `x == typeof(Foo)` and we were able to optimize the method table to the unconstructed version because of that). So we can generate less of it and still get away with it. In this PR I'm adding support for skipping generation of custom attribute metadata for such types. The size of an empty WinForms app goes from 50-something MB to 20-something MB. I think we'll be able to further reduce this number to ~7 MB or less because 12 MB of this are embedded resources that look designer related. * CR feedback --------- Co-authored-by: Michal Strehovský Co-authored-by: Jeff Schwartz --- .../Compiler/DependencyAnalysis/EETypeNode.cs | 3 +- .../GenericDefinitionEETypeNode.cs | 2 +- .../DependencyAnalysis/NodeFactory.cs | 17 ++++++- .../DependencyAnalysis/TypeMetadataNode.cs | 49 ++++++++++--------- .../Compiler/MetadataManager.cs | 6 +-- .../Compiler/UsageBasedMetadataManager.cs | 10 ++-- .../TrimmingBehaviors/DeadCodeElimination.cs | 46 +++++++++++++++++ 7 files changed, 100 insertions(+), 33 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs index 61520b4bfadaff..cd1ef49a221477 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs @@ -625,7 +625,8 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact // Ask the metadata manager // if we have any dependencies due to presence of the EEType. - factory.MetadataManager.GetDependenciesDueToEETypePresence(ref dependencies, factory, _type); + bool isFullType = factory.MaximallyConstructableType(_type) == this; + factory.MetadataManager.GetDependenciesDueToEETypePresence(ref dependencies, factory, _type, isFullType); if (_type is MetadataType mdType) ModuleUseBasedDependencyAlgorithm.AddDependenciesDueToModuleUse(ref dependencies, factory, mdType.Module); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs index b42d93273e4686..2bf7672884de07 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs @@ -25,7 +25,7 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact DependencyList dependencyList = null; // Ask the metadata manager if we have any dependencies due to the presence of the EEType. - factory.MetadataManager.GetDependenciesDueToEETypePresence(ref dependencyList, factory, _type); + factory.MetadataManager.GetDependenciesDueToEETypePresence(ref dependencyList, factory, _type, isFullType: true); return dependencyList; } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs index fbb6c08e04006c..5bc64c02d2886c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs @@ -458,7 +458,12 @@ private void CreateNodeCaches() _typesWithMetadata = new NodeCache(type => { - return new TypeMetadataNode(type); + return new TypeMetadataNode(type, includeCustomAttributes: true); + }); + + _typesWithMetadataWithoutCustomAttributes = new NodeCache(type => + { + return new TypeMetadataNode(type, includeCustomAttributes: false); }); _methodsWithMetadata = new NodeCache(method => @@ -1156,6 +1161,16 @@ internal TypeMetadataNode TypeMetadata(MetadataType type) return _typesWithMetadata.GetOrAdd(type); } + private NodeCache _typesWithMetadataWithoutCustomAttributes; + + internal TypeMetadataNode TypeMetadataWithoutCustomAttributes(MetadataType type) + { + // These are only meaningful for UsageBasedMetadataManager. We should not have them + // in the dependency graph otherwise. + Debug.Assert(MetadataManager is UsageBasedMetadataManager); + return _typesWithMetadataWithoutCustomAttributes.GetOrAdd(type); + } + private NodeCache _methodsWithMetadata; internal MethodMetadataNode MethodMetadata(MethodDesc method) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs index de162987d508b3..8979feb1061ca9 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs @@ -24,11 +24,13 @@ namespace ILCompiler.DependencyAnalysis internal sealed class TypeMetadataNode : DependencyNodeCore { private readonly MetadataType _type; + private readonly bool _includeCustomAttributes; - public TypeMetadataNode(MetadataType type) + public TypeMetadataNode(MetadataType type, bool includeCustomAttributes) { Debug.Assert(type.IsTypeDefinition); _type = type; + _includeCustomAttributes = includeCustomAttributes; } public MetadataType Type => _type; @@ -37,13 +39,21 @@ public override IEnumerable GetStaticDependencies(NodeFacto { DependencyList dependencies = new DependencyList(); - CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, ((EcmaType)_type)); + if (_includeCustomAttributes) + CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, ((EcmaType)_type)); DefType containingType = _type.ContainingType; if (containingType != null) - dependencies.Add(factory.TypeMetadata((MetadataType)containingType), "Containing type of a reflectable type"); + { + TypeMetadataNode metadataNode = _includeCustomAttributes + ? factory.TypeMetadata((MetadataType)containingType) + : factory.TypeMetadataWithoutCustomAttributes((MetadataType)containingType); + dependencies.Add(metadataNode, "Containing type of a reflectable type"); + } else + { dependencies.Add(factory.ModuleMetadata(_type.Module), "Containing module of a reflectable type"); + } var mdManager = (UsageBasedMetadataManager)factory.MetadataManager; @@ -100,7 +110,7 @@ public override IEnumerable GetStaticDependencies(NodeFacto /// Decomposes a constructed type into individual units that will be needed to /// express the constructed type in metadata. /// - public static void GetMetadataDependencies(ref DependencyList dependencies, NodeFactory nodeFactory, TypeDesc type, string reason) + public static void GetMetadataDependencies(ref DependencyList dependencies, NodeFactory nodeFactory, TypeDesc type, string reason, bool isFullType = true) { MetadataManager mdManager = nodeFactory.MetadataManager; @@ -110,13 +120,13 @@ public static void GetMetadataDependencies(ref DependencyList dependencies, Node case TypeFlags.SzArray: case TypeFlags.ByRef: case TypeFlags.Pointer: - GetMetadataDependencies(ref dependencies, nodeFactory, ((ParameterizedType)type).ParameterType, reason); + GetMetadataDependencies(ref dependencies, nodeFactory, ((ParameterizedType)type).ParameterType, reason, isFullType); break; case TypeFlags.FunctionPointer: var pointerType = (FunctionPointerType)type; - GetMetadataDependencies(ref dependencies, nodeFactory, pointerType.Signature.ReturnType, reason); + GetMetadataDependencies(ref dependencies, nodeFactory, pointerType.Signature.ReturnType, reason, isFullType); foreach (TypeDesc paramType in pointerType.Signature) - GetMetadataDependencies(ref dependencies, nodeFactory, paramType, reason); + GetMetadataDependencies(ref dependencies, nodeFactory, paramType, reason, isFullType); break; case TypeFlags.SignatureMethodVariable: @@ -126,27 +136,22 @@ public static void GetMetadataDependencies(ref DependencyList dependencies, Node default: Debug.Assert(type.IsDefType); - TypeDesc typeDefinition = type.GetTypeDefinition(); + var typeDefinition = (MetadataType)type.GetTypeDefinition(); if (typeDefinition != type) { - if (mdManager.CanGenerateMetadata((MetadataType)typeDefinition)) - { - dependencies ??= new DependencyList(); - dependencies.Add(nodeFactory.TypeMetadata((MetadataType)typeDefinition), reason); - } - foreach (TypeDesc typeArg in type.Instantiation) { - GetMetadataDependencies(ref dependencies, nodeFactory, typeArg, reason); + GetMetadataDependencies(ref dependencies, nodeFactory, typeArg, reason, isFullType); } } - else + + if (mdManager.CanGenerateMetadata(typeDefinition)) { - if (mdManager.CanGenerateMetadata((MetadataType)type)) - { - dependencies ??= new DependencyList(); - dependencies.Add(nodeFactory.TypeMetadata((MetadataType)type), reason); - } + dependencies ??= new DependencyList(); + TypeMetadataNode node = isFullType + ? nodeFactory.TypeMetadata(typeDefinition) + : nodeFactory.TypeMetadataWithoutCustomAttributes(typeDefinition); + dependencies.Add(node, reason); } break; } @@ -154,7 +159,7 @@ public static void GetMetadataDependencies(ref DependencyList dependencies, Node protected override string GetName(NodeFactory factory) { - return "Reflectable type: " + _type.ToString(); + return $"Reflectable type: {_type}{(!_includeCustomAttributes ? " (No custom attributes)" : "")}"; } protected override void OnMarked(NodeFactory factory) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs index 8658068c1ebe4d..b62304f362c16c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs @@ -478,13 +478,13 @@ protected virtual void GetMetadataDependenciesDueToReflectability(ref Dependency /// /// This method is an extension point that can provide additional metadata-based dependencies to generated EETypes. /// - public virtual void GetDependenciesDueToEETypePresence(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) + public virtual void GetDependenciesDueToEETypePresence(ref DependencyList dependencies, NodeFactory factory, TypeDesc type, bool isFullType) { MetadataCategory category = GetMetadataCategory(type); if ((category & MetadataCategory.Description) != 0) { - GetMetadataDependenciesDueToReflectability(ref dependencies, factory, type); + GetMetadataDependenciesDueToReflectability(ref dependencies, factory, type, isFullType); } } @@ -493,7 +493,7 @@ internal virtual void GetDependenciesDueToModuleUse(ref DependencyList dependenc // MetadataManagers can override this to provide additional dependencies caused by using a module } - protected virtual void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) + protected virtual void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type, bool isFullType) { // MetadataManagers can override this to provide additional dependencies caused by the emission of metadata // (E.g. dependencies caused by the type having custom attributes applied to it: making sure we compile the attribute constructor diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs index e680bf80f2dfa7..fc0249f76847e5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs @@ -271,9 +271,9 @@ internal override void GetDependenciesDueToModuleUse(ref DependencyList dependen } } - protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) + protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type, bool isFullType) { - TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, type, "Reflectable type"); + TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, type, "Reflectable type", isFullType); if (type.IsDelegate) { @@ -385,9 +385,9 @@ private static bool IsTrimmableAssembly(ModuleDesc assembly) return false; } - public override void GetDependenciesDueToEETypePresence(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) + public override void GetDependenciesDueToEETypePresence(ref DependencyList dependencies, NodeFactory factory, TypeDesc type, bool isFullType) { - base.GetDependenciesDueToEETypePresence(ref dependencies, factory, type); + base.GetDependenciesDueToEETypePresence(ref dependencies, factory, type, isFullType); DataflowAnalyzedTypeDefinitionNode.GetDependencies(ref dependencies, factory, FlowAnnotations, type); } @@ -970,7 +970,7 @@ public bool GeneratesMetadata(MethodDesc methodDef) public bool GeneratesMetadata(MetadataType typeDef) { - return _factory.TypeMetadata(typeDef).Marked; + return _factory.TypeMetadata(typeDef).Marked || _factory.TypeMetadataWithoutCustomAttributes(typeDef).Marked; } public bool GeneratesMetadata(EcmaModule module, CustomAttributeHandle caHandle) diff --git a/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/DeadCodeElimination.cs b/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/DeadCodeElimination.cs index 152c8514556660..e030b3a1de99ce 100644 --- a/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/DeadCodeElimination.cs +++ b/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/DeadCodeElimination.cs @@ -21,6 +21,7 @@ public static int Run() TestStaticVirtualMethodOptimizations.Run(); TestTypeEquals.Run(); TestBranchesInGenericCodeRemoval.Run(); + TestLimitedMetadataBlobs.Run(); return 100; } @@ -378,6 +379,51 @@ public static void Run() } } + class TestLimitedMetadataBlobs + { + class MyAttribute : Attribute + { + public MyAttribute([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type t) { } + } + + class ShouldNotBeNeeded + { + } + + [My(typeof(ShouldNotBeNeeded))] + interface INeverImplemented + { + void Never(); + } + + static INeverImplemented s_instance; +#if !DEBUG + static Type s_type; +#endif + + internal static void Run() + { + Console.WriteLine("Testing generation of limited metadata blobs"); + + // Force a reference to the interface from a dispatch cell + if (s_instance != null) + s_instance.Never(); + + // Following is for release only since it relies on optimizing the typeof into an unconstructed + // MethodTable. +#if !DEBUG + // Force another reference from an LDTOKEN + if (s_type == typeof(INeverImplemented)) + s_type = typeof(object); +#endif + + ThrowIfPresent(typeof(TestLimitedMetadataBlobs), nameof(ShouldNotBeNeeded)); + ThrowIfPresent(typeof(TestLimitedMetadataBlobs), nameof(MyAttribute)); + ThrowIfNotPresent(typeof(TestLimitedMetadataBlobs), nameof(INeverImplemented)); + } + } + + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern", Justification = "That's the point")] private static Type GetTypeSecretly(Type testType, string typeName) => testType.GetNestedType(typeName, BindingFlags.NonPublic | BindingFlags.Public); From 603e3cc01aea0027077858e64dbbc7cf8bfca3c4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 12:47:11 -0700 Subject: [PATCH 145/783] Remove DebugProxy from ClaimsIdentity and ClaimsPrincipal (#91680) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: David Cantú --- .../System/Security/Claims/ClaimsIdentity.cs | 22 ------------------- .../System/Security/Claims/ClaimsPrincipal.cs | 16 -------------- 2 files changed, 38 deletions(-) diff --git a/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsIdentity.cs b/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsIdentity.cs index e0d82df3b7863f..4408b11cddf135 100644 --- a/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsIdentity.cs +++ b/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsIdentity.cs @@ -14,7 +14,6 @@ namespace System.Security.Claims /// An Identity that is represented by a set of claims. /// [DebuggerDisplay("{DebuggerToString(),nq}")] - [DebuggerTypeProxy(typeof(ClaimsIdentityDebugProxy))] public class ClaimsIdentity : IIdentity { private enum SerializationMask @@ -962,26 +961,5 @@ internal string DebuggerToString() return debugText; } - - private sealed class ClaimsIdentityDebugProxy - { - private readonly ClaimsIdentity _identity; - - public ClaimsIdentityDebugProxy(ClaimsIdentity identity) - { - _identity = identity; - } - - public ClaimsIdentity? Actor => _identity.Actor; - public string? AuthenticationType => _identity.AuthenticationType; - public object? BootstrapContext => _identity.BootstrapContext; - // List type has a friendly debugger view - public List Claims => new List(_identity.Claims); - public bool IsAuthenticated => _identity.IsAuthenticated; - public string? Label => _identity.Label; - public string? Name => _identity.Name; - public string NameClaimType => _identity.NameClaimType; - public string RoleClaimType => _identity.RoleClaimType; - } } } diff --git a/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsPrincipal.cs b/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsPrincipal.cs index 13ee10f7f6f4e6..de8f7d89725c68 100644 --- a/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsPrincipal.cs +++ b/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsPrincipal.cs @@ -15,7 +15,6 @@ namespace System.Security.Claims /// Concrete IPrincipal supporting multiple claims-based identities /// [DebuggerDisplay("{DebuggerToString(),nq}")] - [DebuggerTypeProxy(typeof(ClaimsPrincipalDebugProxy))] public class ClaimsPrincipal : IPrincipal { private enum SerializationMask @@ -594,20 +593,5 @@ private string DebuggerToString() return $"Identities = {identitiesCount}, Claims = {claimsCount}"; } - - private sealed class ClaimsPrincipalDebugProxy - { - private readonly ClaimsPrincipal _principal; - - public ClaimsPrincipalDebugProxy(ClaimsPrincipal principal) - { - _principal = principal; - } - - // List type has a friendly debugger view - public List Claims => new List(_principal.Claims); - public List Identities => new List(_principal.Identities); - public IIdentity? Identity => _principal.Identity; - } } } From 282da2cd568a4e1429990d3257efbc3724b79fee Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 16:38:49 -0600 Subject: [PATCH 146/783] [release/8.0] Update dependencies from dotnet/roslyn (#91482) * Update dependencies from https://github.com/dotnet/roslyn build 20230901.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23451.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230901.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23451.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230901.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23451.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230904.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23454.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230905.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23455.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230905.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23455.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230905.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23455.5 * Update dependencies from https://github.com/dotnet/roslyn build 20230905.11 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23455.11 * Update dependencies from https://github.com/dotnet/roslyn build 20230905.12 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23455.12 * Update dependencies from https://github.com/dotnet/roslyn build 20230906.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23456.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230906.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23456.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230906.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23456.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230906.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23456.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230906.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23456.5 * Update dependencies from https://github.com/dotnet/roslyn build 20230906.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23456.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230906.8 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23456.8 * Update dependencies from https://github.com/dotnet/roslyn build 20230906.11 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23456.11 * Update dependencies from https://github.com/dotnet/roslyn build 20230906.12 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23456.12 * Update dependencies from https://github.com/dotnet/roslyn build 20230906.13 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23456.13 * Update dependencies from https://github.com/dotnet/roslyn build 20230907.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23457.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230907.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23457.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230907.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23457.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230907.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23457.5 * Update dependencies from https://github.com/dotnet/roslyn build 20230907.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23457.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230907.7 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23457.7 * Update dependencies from https://github.com/dotnet/roslyn build 20230907.8 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23457.8 * Update dependencies from https://github.com/dotnet/roslyn build 20230908.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23458.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230908.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23458.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230908.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23458.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230908.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23458.5 * Update dependencies from https://github.com/dotnet/roslyn build 20230908.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23458.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230908.7 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23458.7 * Update dependencies from https://github.com/dotnet/roslyn build 20230908.8 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23458.8 * Update dependencies from https://github.com/dotnet/roslyn build 20230909.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23459.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230909.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23451.1 -> To Version 4.8.0-3.23459.2 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 52a007513c2b51..5fea3f92af6736 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - 3686f3061a9202260a0de4d06e91855b0fa21e8c + d080175cabfe297ebf079af099279b61913bcc28 - + https://github.com/dotnet/roslyn - 3686f3061a9202260a0de4d06e91855b0fa21e8c + d080175cabfe297ebf079af099279b61913bcc28 - + https://github.com/dotnet/roslyn - 3686f3061a9202260a0de4d06e91855b0fa21e8c + d080175cabfe297ebf079af099279b61913bcc28 https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index 7097377fb2510a..560db925f60625 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -42,9 +42,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23451.1 - 4.8.0-3.23451.1 - 4.8.0-3.23451.1 + 4.8.0-3.23459.2 + 4.8.0-3.23459.2 + 4.8.0-3.23459.2 - 3.11.0-beta1.23425.3 - 8.0.0-preview.23425.3 + 3.11.0-beta1.23458.2 + 8.0.0-preview.23458.2 - 8.0.0-rc.2.23455.4 + 8.0.0-rc.2.23460.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda From 217be6c5b81c38bcfdd8d014a3a0b4412b6c2c1c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:09:04 -0600 Subject: [PATCH 148/783] Fix implementation of NegotiateAuthentication.Wrap for Kerberos on Windows (#91311) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Filip Navara Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- .../Net/NegotiateAuthenticationPal.Windows.cs | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Windows.cs index 3dcb03bfd08f74..07e8dea22baa9c 100644 --- a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Windows.cs @@ -421,28 +421,32 @@ public override unsafe NegotiateAuthenticationStatusCode Wrap(ReadOnlySpan Debug.Assert(success); // alloc new output buffer if not supplied or too small - int resultSize = input.Length + sizes.cbMaxSignature; + int resultSize = input.Length + sizes.cbSecurityTrailer + sizes.cbBlockSize; Span outputBuffer = outputWriter.GetSpan(resultSize); // make a copy of user data for in-place encryption - input.CopyTo(outputBuffer.Slice(sizes.cbMaxSignature, input.Length)); + input.CopyTo(outputBuffer.Slice(sizes.cbSecurityTrailer, input.Length)); isEncrypted = requestEncryption; fixed (byte* outputPtr = outputBuffer) { // Prepare buffers TOKEN(signature), DATA and Padding. - Interop.SspiCli.SecBuffer* unmanagedBuffer = stackalloc Interop.SspiCli.SecBuffer[2]; + Interop.SspiCli.SecBuffer* unmanagedBuffer = stackalloc Interop.SspiCli.SecBuffer[3]; Interop.SspiCli.SecBuffer* tokenBuffer = &unmanagedBuffer[0]; Interop.SspiCli.SecBuffer* dataBuffer = &unmanagedBuffer[1]; + Interop.SspiCli.SecBuffer* paddingBuffer = &unmanagedBuffer[2]; tokenBuffer->BufferType = SecurityBufferType.SECBUFFER_TOKEN; tokenBuffer->pvBuffer = (IntPtr)(outputPtr); - tokenBuffer->cbBuffer = sizes.cbMaxSignature; + tokenBuffer->cbBuffer = sizes.cbSecurityTrailer; dataBuffer->BufferType = SecurityBufferType.SECBUFFER_DATA; - dataBuffer->pvBuffer = (IntPtr)(outputPtr + sizes.cbMaxSignature); + dataBuffer->pvBuffer = (IntPtr)(outputPtr + sizes.cbSecurityTrailer); dataBuffer->cbBuffer = input.Length; + paddingBuffer->BufferType = SecurityBufferType.SECBUFFER_PADDING; + paddingBuffer->pvBuffer = (IntPtr)(outputPtr + sizes.cbSecurityTrailer + input.Length); + paddingBuffer->cbBuffer = sizes.cbBlockSize; - Interop.SspiCli.SecBufferDesc sdcInOut = new Interop.SspiCli.SecBufferDesc(2) + Interop.SspiCli.SecBufferDesc sdcInOut = new Interop.SspiCli.SecBufferDesc(3) { pBuffers = unmanagedBuffer }; @@ -460,7 +464,20 @@ public override unsafe NegotiateAuthenticationStatusCode Wrap(ReadOnlySpan }; } - outputWriter.Advance(tokenBuffer->cbBuffer + dataBuffer->cbBuffer); + // Compact the result + if (tokenBuffer->cbBuffer != sizes.cbSecurityTrailer) + { + outputBuffer.Slice(sizes.cbSecurityTrailer, dataBuffer->cbBuffer).CopyTo( + outputBuffer.Slice(tokenBuffer->cbBuffer, dataBuffer->cbBuffer)); + } + if (tokenBuffer->cbBuffer != sizes.cbSecurityTrailer || + paddingBuffer->cbBuffer != sizes.cbBlockSize) + { + outputBuffer.Slice(sizes.cbSecurityTrailer + input.Length, paddingBuffer->cbBuffer).CopyTo( + outputBuffer.Slice(tokenBuffer->cbBuffer + dataBuffer->cbBuffer, paddingBuffer->cbBuffer)); + } + + outputWriter.Advance(tokenBuffer->cbBuffer + dataBuffer->cbBuffer + paddingBuffer->cbBuffer); return NegotiateAuthenticationStatusCode.Completed; } } From ef67ba828e906e12f0a158765e4c20c564f45270 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:09:49 -0600 Subject: [PATCH 149/783] [release/8.0] Add Native AOT Pri0 test leg (#91373) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Pri0 test leg * wip * hm * Update Comparer_get_Default.csproj * Revert "wip" This reverts commit af025c048145685352b70eb76894c6d6d1eca0c5. * Add failing JIT test to issues.targets --------- Co-authored-by: Michal Strehovský Co-authored-by: Andy Gocke --- .../runtime-extra-platforms-other.yml | 38 +++++++++++++++++++ .../Comparer_get_Default.csproj | 3 ++ src/tests/build.proj | 1 + src/tests/issues.targets | 3 ++ 4 files changed, 45 insertions(+) diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml index 13d3352393fa7f..c279c318e34d59 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml +++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml @@ -193,6 +193,44 @@ jobs: eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), eq(variables['isRollingBuild'], true)) +# +# CoreCLR NativeAOT checked build and Pri0 tests +# Only when CoreCLR is changed +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml + buildConfig: Checked + platforms: + - windows_x64 + - linux_x64 + variables: + - name: timeoutPerTestInMinutes + value: 60 + - name: timeoutPerTestCollectionInMinutes + value: 180 + jobParameters: + timeoutInMinutes: 240 + nameSuffix: NativeAOT_Pri0 + buildArgs: -s clr.aot+host.native+libs -rc $(_BuildConfig) -lc Release -hc Release + extraStepsTemplate: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml + extraStepsParameters: + creator: dotnet-bot + testBuildArgs: 'nativeaot /p:IlcUseServerGc=false' + liveLibrariesBuildConfig: Release + testRunNamePrefixSuffix: NativeAOT_Pri0_$(_BuildConfig) + extraVariablesTemplates: + - template: /eng/pipelines/common/templates/runtimes/test-variables.yml + parameters: + testGroup: innerloop + liveLibrariesBuildConfig: Release + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), + eq(variables['isRollingBuild'], true)) + # Run net48 tests on win-x64 - template: /eng/pipelines/common/platform-matrix.yml parameters: diff --git a/src/tests/JIT/opt/Devirtualization/Comparer_get_Default.csproj b/src/tests/JIT/opt/Devirtualization/Comparer_get_Default.csproj index c6636e39772f44..ef9e4a7a6abc7c 100644 --- a/src/tests/JIT/opt/Devirtualization/Comparer_get_Default.csproj +++ b/src/tests/JIT/opt/Devirtualization/Comparer_get_Default.csproj @@ -1,6 +1,9 @@ True + + + true diff --git a/src/tests/build.proj b/src/tests/build.proj index 090f11df3acd5a..e49ddc0b51b2f8 100644 --- a/src/tests/build.proj +++ b/src/tests/build.proj @@ -595,6 +595,7 @@ $(GroupBuildCmd) "/p:CrossBuild=true" $(GroupBuildCmd) "/p:DefaultBuildAllTarget=BuildNativeAot" $(GroupBuildCmd) "/p:IlcMultiModule=true" + $(GroupBuildCmd) "/p:IlcUseServerGc=false" $(GroupBuildCmd) "/p:BuildNativeAotFrameworkObjects=true" diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 7ec7dc726f34ef..d950862b7fdbf2 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -694,6 +694,9 @@ + + https://github.com/dotnet/runtime/issues/90848 + https://github.com/dotnet/runtime/issues/89157 From acab656484c23d9c6e24ca3f77eb8234cb8100e1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:13:46 -0600 Subject: [PATCH 150/783] [release/8.0] Update dependencies from dnceng/internal/dotnet-optimization (#91501) * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230901.6 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23431.4 -> To Version 1.0.0-prerelease.23451.6 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230902.2 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23431.4 -> To Version 1.0.0-prerelease.23452.2 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230902.2 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23431.4 -> To Version 1.0.0-prerelease.23452.2 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230902.2 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23431.4 -> To Version 1.0.0-prerelease.23452.2 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230907.4 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23431.4 -> To Version 1.0.0-prerelease.23457.4 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230908.2 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23431.4 -> To Version 1.0.0-prerelease.23458.2 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230908.2 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23431.4 -> To Version 1.0.0-prerelease.23458.2 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230908.2 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23431.4 -> To Version 1.0.0-prerelease.23458.2 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 90223f37e1382b..942050ec170f13 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -334,21 +334,21 @@ https://github.com/dotnet/arcade 4665b3d04e1da3796b965c3c3e3b97f55c449a6e - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 07f1da26c7bd97db0defad5e38bed5e514eb960e + 25dddd65cef2d69facd6cd646600e540d46fd6ec - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 07f1da26c7bd97db0defad5e38bed5e514eb960e + 25dddd65cef2d69facd6cd646600e540d46fd6ec - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 07f1da26c7bd97db0defad5e38bed5e514eb960e + 25dddd65cef2d69facd6cd646600e540d46fd6ec - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 07f1da26c7bd97db0defad5e38bed5e514eb960e + 25dddd65cef2d69facd6cd646600e540d46fd6ec https://github.com/dotnet/hotreload-utils @@ -384,13 +384,13 @@ d10b02ae5cc670609d920a672985ed4456bdd6b6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 07f1da26c7bd97db0defad5e38bed5e514eb960e + 25dddd65cef2d69facd6cd646600e540d46fd6ec - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 07f1da26c7bd97db0defad5e38bed5e514eb960e + 25dddd65cef2d69facd6cd646600e540d46fd6ec diff --git a/eng/Versions.props b/eng/Versions.props index 10212c081a0dc9..f2a663cea35218 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -156,12 +156,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23431.4 - 1.0.0-prerelease.23431.4 - 1.0.0-prerelease.23431.4 - 1.0.0-prerelease.23431.4 - 1.0.0-prerelease.23431.4 - 1.0.0-prerelease.23431.4 + 1.0.0-prerelease.23458.2 + 1.0.0-prerelease.23458.2 + 1.0.0-prerelease.23458.2 + 1.0.0-prerelease.23458.2 + 1.0.0-prerelease.23458.2 + 1.0.0-prerelease.23458.2 16.11.27-beta1.23180.1 2.0.0-beta4.23307.1 From 64c5aaede2e82c4f353d3cac7111b10ebced2dec Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:17:44 -0600 Subject: [PATCH 151/783] [release/8.0] Fix Dispose and SendData Race on Http3 Test (#91690) * Fix Dispose and Send Data Race * Review feedback --------- Co-authored-by: Ahmet Ibrahim Aksoy (from Dev Box) --- .../tests/FunctionalTests/HttpClientHandlerTest.Http3.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs index 92c4ab0d6097f6..844d2866bde61e 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs @@ -1626,6 +1626,7 @@ public async Task DuplexStreaming_AbortByServer_StreamingCancelled(bool graceful public async Task ServerSendsTrailingHeaders_Success() { using Http3LoopbackServer server = CreateHttp3LoopbackServer(); + SemaphoreSlim clientFinishedSemaphore = new SemaphoreSlim(0); Task serverTask = Task.Run(async () => { @@ -1636,6 +1637,7 @@ public async Task ServerSendsTrailingHeaders_Success() await requestStream.ReadRequestDataAsync(); await requestStream.SendResponseAsync(isFinal: false); await requestStream.SendResponseHeadersAsync(null, new[] { new HttpHeaderData("MyHeader", "MyValue") }); + await clientFinishedSemaphore.WaitAsync(TimeSpan.FromSeconds(20)); }); Task clientTask = Task.Run(async () => @@ -1655,6 +1657,7 @@ public async Task ServerSendsTrailingHeaders_Success() (string key, IEnumerable value) = Assert.Single(response.TrailingHeaders); Assert.Equal("MyHeader", key); Assert.Equal("MyValue", Assert.Single(value)); + clientFinishedSemaphore.Release(); }); await new[] { clientTask, serverTask }.WhenAllOrAnyFailed(200_000); From bfdfb82ad34baa6381dc6cc22c4ec695aafa8525 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:18:32 -0600 Subject: [PATCH 152/783] [maccatalyst] Make sure MacProxy is included in System.Net.Http (#91599) https://github.com/dotnet/runtime/issues/90258 identified that `HttpClient.DefaultProxy` returned `System.Net.Http.HttpNoProxy` when using MacCatalyst. This is due to a condition in System.Net.Http.csproj not including maccatalyst as a condition and as a result, skipped adding the MacProxy sources. Way back when, https://github.com/dotnet/runtime/pull/47823 had the condition, but this appears to have changed in https://github.com/dotnet/runtime/pull/48652 when we thought MacCatalyst would inherit settings from iOS. That turned out to not be the case and this check was never added back. Co-authored-by: Steve Pfister --- src/libraries/System.Net.Http/src/System.Net.Http.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index f9c229575e1214..f263f9480cd67e 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -316,11 +316,11 @@ - + - + Date: Tue, 12 Sep 2023 01:19:43 +0200 Subject: [PATCH 153/783] Check DotNetFinalVersionKind when setting WorkloadVersionSuffix (#91791) --- eng/Versions.props | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index f2a663cea35218..646f22880d530d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -11,16 +11,16 @@ 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) rc 2 - -$(PreReleaseVersionLabel).$(PreReleaseVersionIteration) + + false + release + -$(PreReleaseVersionLabel).$(PreReleaseVersionIteration) $(SdkBandVersion)$(WorkloadVersionSuffix) false $(MajorVersion).$(MinorVersion).0.0 - - false - release true false From 4147efb8b031eecd5776b6172f974e02b4972f56 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Tue, 12 Sep 2023 01:23:50 +0200 Subject: [PATCH 154/783] [release/8.0] JIT: DNER multiregs with SIMD12 (#91878) * JIT: DNER multiregs with SIMD12s Locals with SIMD12 fields will never match the ABI when they end up as multireg returns, so these should always be DNER'd. Fix #91214 * Fix test build --- src/coreclr/jit/lower.cpp | 22 ++++++++++ .../JitBlue/Runtime_91062/Runtime_91062.cs | 2 +- .../JitBlue/Runtime_91170/Runtime_91170.cs | 2 +- .../JitBlue/Runtime_91214/Runtime_91214.cs | 40 +++++++++++++++++++ .../Runtime_91214/Runtime_91214.csproj | 8 ++++ 5 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91214/Runtime_91214.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91214/Runtime_91214.csproj diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 81df694f05e1ff..2e454e64c14eb1 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -7484,6 +7484,28 @@ bool Lowering::CheckMultiRegLclVar(GenTreeLclVar* lclNode, int registerCount) if (registerCount == varDsc->lvFieldCnt) { canEnregisterAsMultiReg = true; + +#ifdef FEATURE_SIMD + // TYP_SIMD12 breaks the above invariant that "we won't have + // matching reg and field counts"; for example, consider + // + // * STORE_LCL_VAR(CALL) + // * RETURN(LCL_VAR) + // + // These return in two GPR registers, while the fields of the + // local are stored in SIMD and GPR register, so registerCount + // == varDsc->lvFieldCnt == 2. But the backend cannot handle + // this. + + for (int i = 0; i < varDsc->lvFieldCnt; i++) + { + if (comp->lvaGetDesc(varDsc->lvFieldLclStart + i)->TypeGet() == TYP_SIMD12) + { + canEnregisterAsMultiReg = false; + break; + } + } +#endif } } } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91062/Runtime_91062.cs b/src/tests/JIT/Regression/JitBlue/Runtime_91062/Runtime_91062.cs index 8886bd2044ab04..562d2029ff85c5 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_91062/Runtime_91062.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91062/Runtime_91062.cs @@ -1,5 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license.aa +// The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91170/Runtime_91170.cs b/src/tests/JIT/Regression/JitBlue/Runtime_91170/Runtime_91170.cs index afb26b6def0bc0..7f3e9293eba974 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_91170/Runtime_91170.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91170/Runtime_91170.cs @@ -1,5 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license.aa +// The .NET Foundation licenses this file to you under the MIT license. // Found by Antigen diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91214/Runtime_91214.cs b/src/tests/JIT/Regression/JitBlue/Runtime_91214/Runtime_91214.cs new file mode 100644 index 00000000000000..d30adf6e60cf11 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91214/Runtime_91214.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Found by Antigen + +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Numerics; +using Xunit; + +public class Runtime_91214 +{ + [Fact] + public static void TestEntryPoint() + { + Method0(); + } + + struct S + { + public Vector3 v3; + public bool b; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static S Method2() + { + return default; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Method0() + { + S s = Method2(); + Log(null, s.v3); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Log(object a, object b) { } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91214/Runtime_91214.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_91214/Runtime_91214.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91214/Runtime_91214.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From 9819f182fdab5238be9971c76bdd0c3845c97a6b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:24:18 -0600 Subject: [PATCH 155/783] [release/8.0] Improve perf of ActivatorUtilities.CreateInstance() (#91881) * Improve perf of ActivatorUtilities.CreateInstance() * Support MetadataUpdateHandler for hot reload * Support unloadable assembly contexts * Add tests * Rename new test classes * Remove Mono from test; remove cache for NetFramework; remove use of ConstructorInvoker for possible risk of callstack usage * Misc naming etc; non-functional * Update some comments * Simplify use of ConditionalWeakTable.Add --------- Co-authored-by: Steve Harter --- .../src/ActivatorUtilities.cs | 227 ++++++++++++++---- .../CollectibleAssembly/CollectableClasses.cs | 25 ++ .../CollectibleAssembly.csproj | 11 + .../tests/DI.Tests/ActivatorUtilitiesTests.cs | 159 +++++++++++- ...xtensions.DependencyInjection.Tests.csproj | 3 +- 5 files changed, 372 insertions(+), 53 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/CollectibleAssembly/CollectableClasses.cs create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/tests/CollectibleAssembly/CollectibleAssembly.csproj diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs index eb7931489b557e..6a42373ccc77d4 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Concurrent; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq.Expressions; @@ -10,6 +11,10 @@ using System.Runtime.ExceptionServices; using Microsoft.Extensions.Internal; +#if NETCOREAPP +[assembly: System.Reflection.Metadata.MetadataUpdateHandler(typeof(Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ActivatorUtilitiesUpdateHandler))] +#endif + namespace Microsoft.Extensions.DependencyInjection { /// @@ -17,6 +22,14 @@ namespace Microsoft.Extensions.DependencyInjection /// public static class ActivatorUtilities { +#if NETCOREAPP + // Support caching of constructor metadata for the common case of types in non-collectible assemblies. + private static readonly ConcurrentDictionary s_constructorInfos = new(); + + // Support caching of constructor metadata for types in collectible assemblies. + private static readonly Lazy> s_collectibleConstructorInfos = new(); +#endif + #if NET8_0_OR_GREATER // Maximum number of fixed arguments for ConstructorInvoker.Invoke(arg1, etc). private const int FixedArgumentThreshold = 4; @@ -47,6 +60,17 @@ public static object CreateInstance( throw new InvalidOperationException(SR.CannotCreateAbstractClasses); } + ConstructorInfoEx[]? constructors; +#if NETCOREAPP + if (!s_constructorInfos.TryGetValue(instanceType, out constructors)) + { + constructors = GetOrAddConstructors(instanceType); + } +#else + constructors = CreateConstructorInfoExs(instanceType); +#endif + + ConstructorInfoEx? constructor; IServiceProviderIsService? serviceProviderIsService = provider.GetService(); // if container supports using IServiceProviderIsService, we try to find the longest ctor that // (a) matches all parameters given to CreateInstance @@ -61,10 +85,11 @@ public static object CreateInstance( ConstructorMatcher bestMatcher = default; bool multipleBestLengthFound = false; - foreach (ConstructorInfo? constructor in instanceType.GetConstructors()) + for (int i = 0; i < constructors.Length; i++) { - var matcher = new ConstructorMatcher(constructor); - bool isPreferred = constructor.IsDefined(typeof(ActivatorUtilitiesConstructorAttribute), false); + constructor = constructors[i]; + ConstructorMatcher matcher = new(constructor); + bool isPreferred = constructor.IsPreferred; int length = matcher.Match(parameters, serviceProviderIsService); if (isPreferred) @@ -105,18 +130,79 @@ public static object CreateInstance( } } - Type?[] argumentTypes = new Type[parameters.Length]; - for (int i = 0; i < argumentTypes.Length; i++) + Type?[] argumentTypes; + if (parameters.Length == 0) { - argumentTypes[i] = parameters[i]?.GetType(); + argumentTypes = Type.EmptyTypes; + } + else + { + argumentTypes = new Type[parameters.Length]; + for (int i = 0; i < argumentTypes.Length; i++) + { + argumentTypes[i] = parameters[i]?.GetType(); + } } FindApplicableConstructor(instanceType, argumentTypes, out ConstructorInfo constructorInfo, out int?[] parameterMap); - var constructorMatcher = new ConstructorMatcher(constructorInfo); + + // Find the ConstructorInfoEx from the given constructorInfo. + constructor = null; + foreach (ConstructorInfoEx ctor in constructors) + { + if (ReferenceEquals(ctor.Info, constructorInfo)) + { + constructor = ctor; + break; + } + } + + Debug.Assert(constructor != null); + + var constructorMatcher = new ConstructorMatcher(constructor); constructorMatcher.MapParameters(parameterMap, parameters); return constructorMatcher.CreateInstance(provider); } +#if NETCOREAPP + private static ConstructorInfoEx[] GetOrAddConstructors( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) + { + // Not found. Do the slower work of checking for the value in the correct cache. + // Null and non-collectible load contexts use the default cache. + if (!type.Assembly.IsCollectible) + { + return s_constructorInfos.GetOrAdd(type, CreateConstructorInfoExs(type)); + } + + // Collectible load contexts should use the ConditionalWeakTable so they can be unloaded. + if (s_collectibleConstructorInfos.Value.TryGetValue(type, out ConstructorInfoEx[]? value)) + { + return value; + } + + value = CreateConstructorInfoExs(type); + + // ConditionalWeakTable doesn't support GetOrAdd() so use AddOrUpdate(). This means threads + // can have different instances for the same type, but that is OK since they are equivalent. + s_collectibleConstructorInfos.Value.AddOrUpdate(type, value); + return value; + } +#endif // NETCOREAPP + + private static ConstructorInfoEx[] CreateConstructorInfoExs( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) + { + ConstructorInfo[] constructors = type.GetConstructors(); + ConstructorInfoEx[]? value = new ConstructorInfoEx[constructors.Length]; + for (int i = 0; i < constructors.Length; i++) + { + value[i] = new ConstructorInfoEx(constructors[i]); + } + + return value; + } + /// /// Create a delegate that will instantiate a type with constructor arguments provided directly /// and/or from an . @@ -551,58 +637,82 @@ private static bool TryCreateParameterMap(ParameterInfo[] constructorParameters, return true; } - private static object? GetService(IServiceProvider serviceProvider, ParameterInfo parameterInfo) + private sealed class ConstructorInfoEx { - // Handle keyed service - if (TryGetServiceKey(parameterInfo, out object? key)) + public readonly ConstructorInfo Info; + public readonly ParameterInfo[] Parameters; + public readonly bool IsPreferred; + private readonly object?[]? _parameterKeys; + + public ConstructorInfoEx(ConstructorInfo constructor) { - if (serviceProvider is IKeyedServiceProvider keyedServiceProvider) + Info = constructor; + Parameters = constructor.GetParameters(); + IsPreferred = constructor.IsDefined(typeof(ActivatorUtilitiesConstructorAttribute), inherit: false); + + for (int i = 0; i < Parameters.Length; i++) { - return keyedServiceProvider.GetKeyedService(parameterInfo.ParameterType, key); + FromKeyedServicesAttribute? attr = (FromKeyedServicesAttribute?) + Attribute.GetCustomAttribute(Parameters[i], typeof(FromKeyedServicesAttribute), inherit: false); + + if (attr is not null) + { + _parameterKeys ??= new object?[Parameters.Length]; + _parameterKeys[i] = attr.Key; + } } - throw new InvalidOperationException(SR.KeyedServicesNotSupported); } - // Try non keyed service - return serviceProvider.GetService(parameterInfo.ParameterType); - } - private static bool IsService(IServiceProviderIsService serviceProviderIsService, ParameterInfo parameterInfo) - { - // Handle keyed service - if (TryGetServiceKey(parameterInfo, out object? key)) + public bool IsService(IServiceProviderIsService serviceProviderIsService, int parameterIndex) { - if (serviceProviderIsService is IServiceProviderIsKeyedService serviceProviderIsKeyedService) + ParameterInfo parameterInfo = Parameters[parameterIndex]; + + // Handle keyed service + object? key = _parameterKeys?[parameterIndex]; + if (key is not null) { - return serviceProviderIsKeyedService.IsKeyedService(parameterInfo.ParameterType, key); + if (serviceProviderIsService is IServiceProviderIsKeyedService serviceProviderIsKeyedService) + { + return serviceProviderIsKeyedService.IsKeyedService(parameterInfo.ParameterType, key); + } + + throw new InvalidOperationException(SR.KeyedServicesNotSupported); } - throw new InvalidOperationException(SR.KeyedServicesNotSupported); + + // Use non-keyed service + return serviceProviderIsService.IsService(parameterInfo.ParameterType); } - // Try non keyed service - return serviceProviderIsService.IsService(parameterInfo.ParameterType); - } - private static bool TryGetServiceKey(ParameterInfo parameterInfo, out object? key) - { - foreach (var attribute in parameterInfo.GetCustomAttributes(false)) + public object? GetService(IServiceProvider serviceProvider, int parameterIndex) { - key = attribute.Key; - return true; + ParameterInfo parameterInfo = Parameters[parameterIndex]; + + // Handle keyed service + object? key = _parameterKeys?[parameterIndex]; + if (key is not null) + { + if (serviceProvider is IKeyedServiceProvider keyedServiceProvider) + { + return keyedServiceProvider.GetKeyedService(parameterInfo.ParameterType, key); + } + + throw new InvalidOperationException(SR.KeyedServicesNotSupported); + } + + // Use non-keyed service + return serviceProvider.GetService(parameterInfo.ParameterType); } - key = null; - return false; } private readonly struct ConstructorMatcher { - private readonly ConstructorInfo _constructor; - private readonly ParameterInfo[] _parameters; + private readonly ConstructorInfoEx _constructor; private readonly object?[] _parameterValues; - public ConstructorMatcher(ConstructorInfo constructor) + public ConstructorMatcher(ConstructorInfoEx constructor) { _constructor = constructor; - _parameters = _constructor.GetParameters(); - _parameterValues = new object?[_parameters.Length]; + _parameterValues = new object[constructor.Parameters.Length]; } public int Match(object[] givenParameters, IServiceProviderIsService serviceProviderIsService) @@ -612,10 +722,10 @@ public int Match(object[] givenParameters, IServiceProviderIsService serviceProv Type? givenType = givenParameters[givenIndex]?.GetType(); bool givenMatched = false; - for (int applyIndex = 0; applyIndex < _parameters.Length; applyIndex++) + for (int applyIndex = 0; applyIndex < _constructor.Parameters.Length; applyIndex++) { if (_parameterValues[applyIndex] == null && - _parameters[applyIndex].ParameterType.IsAssignableFrom(givenType)) + _constructor.Parameters[applyIndex].ParameterType.IsAssignableFrom(givenType)) { givenMatched = true; _parameterValues[applyIndex] = givenParameters[givenIndex]; @@ -630,12 +740,12 @@ public int Match(object[] givenParameters, IServiceProviderIsService serviceProv } // confirms the rest of ctor arguments match either as a parameter with a default value or as a service registered - for (int i = 0; i < _parameters.Length; i++) + for (int i = 0; i < _constructor.Parameters.Length; i++) { if (_parameterValues[i] == null && - !IsService(serviceProviderIsService, _parameters[i])) + !_constructor.IsService(serviceProviderIsService, i)) { - if (ParameterDefaultValue.TryGetDefaultValue(_parameters[i], out object? defaultValue)) + if (ParameterDefaultValue.TryGetDefaultValue(_constructor.Parameters[i], out object? defaultValue)) { _parameterValues[i] = defaultValue; } @@ -646,21 +756,21 @@ public int Match(object[] givenParameters, IServiceProviderIsService serviceProv } } - return _parameters.Length; + return _constructor.Parameters.Length; } public object CreateInstance(IServiceProvider provider) { - for (int index = 0; index < _parameters.Length; index++) + for (int index = 0; index < _constructor.Parameters.Length; index++) { if (_parameterValues[index] == null) { - object? value = GetService(provider, _parameters[index]); + object? value = _constructor.GetService(provider, index); if (value == null) { - if (!ParameterDefaultValue.TryGetDefaultValue(_parameters[index], out object? defaultValue)) + if (!ParameterDefaultValue.TryGetDefaultValue(_constructor.Parameters[index], out object? defaultValue)) { - throw new InvalidOperationException(SR.Format(SR.UnableToResolveService, _parameters[index].ParameterType, _constructor.DeclaringType)); + throw new InvalidOperationException(SR.Format(SR.UnableToResolveService, _constructor.Parameters[index].ParameterType, _constructor.Info.DeclaringType)); } else { @@ -677,7 +787,7 @@ public object CreateInstance(IServiceProvider provider) #if NETFRAMEWORK || NETSTANDARD2_0 try { - return _constructor.Invoke(_parameterValues); + return _constructor.Info.Invoke(_parameterValues); } catch (TargetInvocationException ex) when (ex.InnerException != null) { @@ -686,13 +796,13 @@ public object CreateInstance(IServiceProvider provider) throw; } #else - return _constructor.Invoke(BindingFlags.DoNotWrapExceptions, binder: null, parameters: _parameterValues, culture: null); + return _constructor.Info.Invoke(BindingFlags.DoNotWrapExceptions, binder: null, parameters: _parameterValues, culture: null); #endif } public void MapParameters(int?[] parameterMap, object[] givenParameters) { - for (int i = 0; i < _parameters.Length; i++) + for (int i = 0; i < _constructor.Parameters.Length; i++) { if (parameterMap[i] != null) { @@ -974,5 +1084,20 @@ private static object ReflectionFactoryCanonical( return constructor.Invoke(BindingFlags.DoNotWrapExceptions, binder: null, constructorArguments, culture: null); } #endif // NET8_0_OR_GREATER + +#if NETCOREAPP + internal static class ActivatorUtilitiesUpdateHandler + { + public static void ClearCache(Type[]? _) + { + // Ignore the Type[] argument; just clear the caches. + s_constructorInfos.Clear(); + if (s_collectibleConstructorInfos.IsValueCreated) + { + s_collectibleConstructorInfos.Value.Clear(); + } + } + } +#endif } } diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/CollectibleAssembly/CollectableClasses.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/CollectibleAssembly/CollectableClasses.cs new file mode 100644 index 00000000000000..cc9e925ae0ad8e --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/CollectibleAssembly/CollectableClasses.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Extensions.DependencyInjection; + +namespace CollectibleAssembly +{ + public class ClassToCreate + { + public object ClassAsCtorArgument { get; set; } + + public ClassToCreate(ClassAsCtorArgument obj) { ClassAsCtorArgument = obj; } + + public static object Create(ServiceProvider provider) + { + // Both the type to create (ClassToCreate) and the ctor's arg type (ClassAsCtorArgument) are + // located in this assembly, so both types need to be GC'd for this assembly to be collected. + return ActivatorUtilities.CreateInstance(provider, new ClassAsCtorArgument()); + } + } + + public class ClassAsCtorArgument + { + } +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/CollectibleAssembly/CollectibleAssembly.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/CollectibleAssembly/CollectibleAssembly.csproj new file mode 100644 index 00000000000000..82159cece28227 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/CollectibleAssembly/CollectibleAssembly.csproj @@ -0,0 +1,11 @@ + + + $(NetCoreAppCurrent);$(NetFrameworkMinimum) + true + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs index 7572e6977a4c49..dda3cafa442eb0 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs @@ -2,8 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.IO; +using System.Reflection; using Microsoft.DotNet.RemoteExecutor; using Xunit; +using System.Runtime.CompilerServices; + +#if NETCOREAPP +using System.Runtime.Loader; +#endif namespace Microsoft.Extensions.DependencyInjection.Tests { @@ -386,6 +393,125 @@ public void CreateFactory_RemoteExecutor_NoParameters_Success(bool useDynamicCod }, options); } +#if NETCOREAPP + [ActiveIssue("https://github.com/dotnet/runtime/issues/34072", TestRuntimes.Mono)] + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [InlineData(true)] + [InlineData(false)] + public void CreateInstance_CollectibleAssembly(bool useDynamicCode) + { + if (PlatformDetection.IsNonBundledAssemblyLoadingSupported) + { + RemoteInvokeOptions options = new(); + if (!useDynamicCode) + { + DisableDynamicCode(options); + } + + using var remoteHandle = RemoteExecutor.Invoke(static () => + { + Assert.False(Collectible_IsAssemblyLoaded()); + Collectible_LoadAndCreate(useCollectibleAssembly : true, out WeakReference asmWeakRef, out WeakReference typeWeakRef); + + for (int i = 0; (typeWeakRef.IsAlive || asmWeakRef.IsAlive) && (i < 10); i++) + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + + // These should be GC'd. + Assert.False(asmWeakRef.IsAlive, "asmWeakRef.IsAlive"); + Assert.False(typeWeakRef.IsAlive, "typeWeakRef.IsAlive"); + Assert.False(Collectible_IsAssemblyLoaded()); + }, options); + } + } + + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [InlineData(true)] + [InlineData(false)] + public void CreateInstance_NormalAssembly(bool useDynamicCode) + { + RemoteInvokeOptions options = new(); + if (!useDynamicCode) + { + DisableDynamicCode(options); + } + + using var remoteHandle = RemoteExecutor.Invoke(static () => + { + Assert.False(Collectible_IsAssemblyLoaded()); + Collectible_LoadAndCreate(useCollectibleAssembly: false, out WeakReference asmWeakRef, out WeakReference typeWeakRef); + + for (int i = 0; (typeWeakRef.IsAlive || asmWeakRef.IsAlive) && (i < 10); i++) + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + + // These will not be GC'd. + Assert.True(asmWeakRef.IsAlive, "alcWeakRef.IsAlive"); + Assert.True(typeWeakRef.IsAlive, "typeWeakRef.IsAlive"); + Assert.True(Collectible_IsAssemblyLoaded()); + }, options); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Collectible_LoadAndCreate(bool useCollectibleAssembly, out WeakReference asmWeakRef, out WeakReference typeWeakRef) + { + Assembly asm; + object obj; + + if (useCollectibleAssembly) + { + asm = MyLoadContext.LoadAsCollectable(); + obj = CreateWithActivator(asm); + Assert.True(obj.GetType().Assembly.IsCollectible); + } + else + { + asm = MyLoadContext.LoadNormal(); + obj = CreateWithActivator(asm); + Assert.False(obj.GetType().Assembly.IsCollectible); + } + + Assert.True(Collectible_IsAssemblyLoaded()); + asmWeakRef = new WeakReference(asm); + typeWeakRef = new WeakReference(obj.GetType()); + + static object CreateWithActivator(Assembly asm) + { + Type t = asm.GetType("CollectibleAssembly.ClassToCreate"); + MethodInfo mi = t.GetMethod("Create", BindingFlags.Static | BindingFlags.Public, new Type[] { typeof(ServiceProvider) }); + + object instance; + ServiceCollection services = new(); + using (ServiceProvider provider = services.BuildServiceProvider()) + { + instance = mi.Invoke(null, new object[] { provider }); + } + + return instance; + } + } + + static bool Collectible_IsAssemblyLoaded() + { + Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); + for (int i = 0; i < assemblies.Length; i++) + { + Assembly asm = assemblies[i]; + string asmName = Path.GetFileName(asm.Location); + if (asmName == "CollectibleAssembly.dll") + { + return true; + } + } + + return false; + } +#endif + private static void DisableDynamicCode(RemoteInvokeOptions options) { // We probably only need to set 'IsDynamicCodeCompiled' since only that is checked, @@ -581,5 +707,36 @@ public ClassWithStringDefaultValue(string text = "DEFAULT") Text = text; } } -} +#if NETCOREAPP + internal class MyLoadContext : AssemblyLoadContext + { + private MyLoadContext() : base(isCollectible: true) + { + } + + public Assembly LoadAssembly() + { + Assembly asm = LoadFromAssemblyPath(GetPath()); + Assert.Equal(GetLoadContext(asm), this); + return asm; + } + + public static Assembly LoadAsCollectable() + { + MyLoadContext alc = new MyLoadContext(); + return alc.LoadAssembly(); + } + + public static Assembly LoadNormal() + { + return Assembly.LoadFrom(GetPath()); + } + + private static string GetPath() + { + return Path.Combine(Directory.GetCurrentDirectory(), "CollectibleAssembly.dll"); + } + } +#endif +} diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj index 4ac3c02d7157a3..067508506a82fe 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);$(NetFrameworkMinimum) @@ -24,6 +24,7 @@ + From 267b39201599f6493b1d8f23874fbcca9e8f6c96 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:27:35 -0600 Subject: [PATCH 156/783] JIT: ensure AVX512 ternary operands aren't used twice (#91883) Don't spill unused zeros early; we might decide to use them later. Fixes #91796. Co-authored-by: Andy Ayers --- src/coreclr/jit/hwintrinsicxarch.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 488f65b5ac008d..065999982a87a9 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -3602,17 +3602,19 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - if (unusedVal1) + // Consume operands we won't use, in case they have side effects. + // + if (unusedVal1 && !(*val1)->IsVectorZero()) { impAppendTree(gtUnusedValNode(*val1), CHECK_SPILL_ALL, impCurStmtDI); } - if (unusedVal2) + if (unusedVal2 && !(*val2)->IsVectorZero()) { impAppendTree(gtUnusedValNode(*val2), CHECK_SPILL_ALL, impCurStmtDI); } - if (unusedVal3) + if (unusedVal3 && !(*val3)->IsVectorZero()) { impAppendTree(gtUnusedValNode(*val3), CHECK_SPILL_ALL, impCurStmtDI); } From 4adb83e748513d5c69fb7be791b3940f1fe2dc07 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 08:26:55 -0700 Subject: [PATCH 157/783] [release/8.0] Fix `Item4` is missing in some `ValueTuple`s' `IStructuralEquatable.Equals` (#91470) * Add missing comparisons * Add unit tests --------- Co-authored-by: Hamish Arblaster --- .../src/System/ValueTuple.cs | 4 + .../tests/ValueTupleTests.cs | 104 ++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/ValueTuple.cs b/src/libraries/System.Private.CoreLib/src/System/ValueTuple.cs index 240ad862ffcf24..aa919ea294f78d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ValueTuple.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ValueTuple.cs @@ -1125,6 +1125,7 @@ other is ValueTuple vt && comparer.Equals(Item1, vt.Item1) && comparer.Equals(Item2, vt.Item2) && comparer.Equals(Item3, vt.Item3) && + comparer.Equals(Item4, vt.Item4) && comparer.Equals(Item5, vt.Item5); int IComparable.CompareTo(object? other) @@ -1366,6 +1367,7 @@ other is ValueTuple vt && comparer.Equals(Item1, vt.Item1) && comparer.Equals(Item2, vt.Item2) && comparer.Equals(Item3, vt.Item3) && + comparer.Equals(Item4, vt.Item4) && comparer.Equals(Item5, vt.Item5) && comparer.Equals(Item6, vt.Item6); @@ -1625,6 +1627,7 @@ other is ValueTuple vt && comparer.Equals(Item1, vt.Item1) && comparer.Equals(Item2, vt.Item2) && comparer.Equals(Item3, vt.Item3) && + comparer.Equals(Item4, vt.Item4) && comparer.Equals(Item5, vt.Item5) && comparer.Equals(Item6, vt.Item6) && comparer.Equals(Item7, vt.Item7); @@ -1908,6 +1911,7 @@ other is ValueTuple vt && comparer.Equals(Item1, vt.Item1) && comparer.Equals(Item2, vt.Item2) && comparer.Equals(Item3, vt.Item3) && + comparer.Equals(Item4, vt.Item4) && comparer.Equals(Item5, vt.Item5) && comparer.Equals(Item6, vt.Item6) && comparer.Equals(Item7, vt.Item7) && diff --git a/src/libraries/System.ValueTuple/tests/ValueTupleTests.cs b/src/libraries/System.ValueTuple/tests/ValueTupleTests.cs index 9507b31388b1f8..147b4ea9647cbf 100644 --- a/src/libraries/System.ValueTuple/tests/ValueTupleTests.cs +++ b/src/libraries/System.ValueTuple/tests/ValueTupleTests.cs @@ -799,6 +799,12 @@ public static void OneTuples() Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + Assert.True(ValueTuple.Create(1).Equals(ValueTuple.Create(1))); + Assert.False(ValueTuple.Create(1).Equals(ValueTuple.Create(0))); + + Assert.True(((IStructuralEquatable)ValueTuple.Create(1)).Equals(ValueTuple.Create(1), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1)).Equals(ValueTuple.Create(0), TestEqualityComparer.Instance)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1)).ToString()); var vtWithNull = new ValueTuple(null); @@ -831,6 +837,14 @@ public static void TwoTuples() Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + Assert.True(ValueTuple.Create(1, 2).Equals(ValueTuple.Create(1, 2))); + Assert.False(ValueTuple.Create(1, 2).Equals(ValueTuple.Create(0, 2))); + Assert.False(ValueTuple.Create(1, 2).Equals(ValueTuple.Create(1, 0))); + + Assert.True(((IStructuralEquatable)ValueTuple.Create(1, 2)).Equals(ValueTuple.Create(1, 2), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2)).Equals(ValueTuple.Create(0, 2), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2)).Equals(ValueTuple.Create(1, 0), TestEqualityComparer.Instance)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1, 2)).ToString()); var vtWithNull = new ValueTuple(null, null); @@ -866,6 +880,16 @@ public static void ThreeTuples() Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + Assert.True(ValueTuple.Create(1, 2, 3).Equals(ValueTuple.Create(1, 2, 3))); + Assert.False(ValueTuple.Create(1, 2, 3).Equals(ValueTuple.Create(0, 2, 3))); + Assert.False(ValueTuple.Create(1, 2, 3).Equals(ValueTuple.Create(1, 0, 3))); + Assert.False(ValueTuple.Create(1, 2, 3).Equals(ValueTuple.Create(1, 2, 0))); + + Assert.True(((IStructuralEquatable)ValueTuple.Create(1, 2, 3)).Equals(ValueTuple.Create(1, 2, 3), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3)).Equals(ValueTuple.Create(0, 2, 3), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3)).Equals(ValueTuple.Create(1, 0, 3), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3)).Equals(ValueTuple.Create(1, 2, 0), TestEqualityComparer.Instance)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2, 3)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1, 2, 3)).ToString()); var vtWithNull = new ValueTuple(null, null, null); @@ -905,6 +929,18 @@ public static void FourTuples() Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + Assert.True(ValueTuple.Create(1, 2, 3, 4).Equals(ValueTuple.Create(1, 2, 3, 4))); + Assert.False(ValueTuple.Create(1, 2, 3, 4).Equals(ValueTuple.Create(0, 2, 3, 4))); + Assert.False(ValueTuple.Create(1, 2, 3, 4).Equals(ValueTuple.Create(1, 0, 3, 4))); + Assert.False(ValueTuple.Create(1, 2, 3, 4).Equals(ValueTuple.Create(1, 2, 0, 4))); + Assert.False(ValueTuple.Create(1, 2, 3, 4).Equals(ValueTuple.Create(1, 2, 3, 0))); + + Assert.True(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4)).Equals(ValueTuple.Create(1, 2, 3, 4), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4)).Equals(ValueTuple.Create(0, 2, 3, 4), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4)).Equals(ValueTuple.Create(1, 0, 3, 4), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4)).Equals(ValueTuple.Create(1, 2, 0, 4), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4)).Equals(ValueTuple.Create(1, 2, 3, 0), TestEqualityComparer.Instance)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1, 2, 3, 4)).ToString()); var vtWithNull = new ValueTuple(null, null, null, null); @@ -947,6 +983,20 @@ public static void FiveTuples() Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + Assert.True(ValueTuple.Create(1, 2, 3, 4, 5).Equals(ValueTuple.Create(1, 2, 3, 4, 5))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5).Equals(ValueTuple.Create(0, 2, 3, 4, 5))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5).Equals(ValueTuple.Create(1, 0, 3, 4, 5))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5).Equals(ValueTuple.Create(1, 2, 0, 4, 5))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5).Equals(ValueTuple.Create(1, 2, 3, 0, 5))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5).Equals(ValueTuple.Create(1, 2, 3, 4, 0))); + + Assert.True(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5)).Equals(ValueTuple.Create(1, 2, 3, 4, 5), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5)).Equals(ValueTuple.Create(0, 2, 3, 4, 5), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5)).Equals(ValueTuple.Create(1, 0, 3, 4, 5), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5)).Equals(ValueTuple.Create(1, 2, 0, 4, 5), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5)).Equals(ValueTuple.Create(1, 2, 3, 0, 5), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5)).Equals(ValueTuple.Create(1, 2, 3, 4, 0), TestEqualityComparer.Instance)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1, 2, 3, 4, 5)).ToString()); var vtWithNull = new ValueTuple(null, null, null, null, null); @@ -992,6 +1042,22 @@ public static void SixTuples() Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + Assert.True(ValueTuple.Create(1, 2, 3, 4, 5, 6).Equals(ValueTuple.Create(1, 2, 3, 4, 5, 6))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5, 6).Equals(ValueTuple.Create(0, 2, 3, 4, 5, 6))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5, 6).Equals(ValueTuple.Create(1, 0, 3, 4, 5, 6))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5, 6).Equals(ValueTuple.Create(1, 2, 0, 4, 5, 6))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5, 6).Equals(ValueTuple.Create(1, 2, 3, 0, 5, 6))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5, 6).Equals(ValueTuple.Create(1, 2, 3, 4, 0, 6))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5, 6).Equals(ValueTuple.Create(1, 2, 3, 4, 5, 0))); + + Assert.True(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6)).Equals(ValueTuple.Create(1, 2, 3, 4, 5, 6), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6)).Equals(ValueTuple.Create(0, 2, 3, 4, 5, 6), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6)).Equals(ValueTuple.Create(1, 0, 3, 4, 5, 6), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6)).Equals(ValueTuple.Create(1, 2, 0, 4, 5, 6), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6)).Equals(ValueTuple.Create(1, 2, 3, 0, 5, 6), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6)).Equals(ValueTuple.Create(1, 2, 3, 4, 0, 6), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6)).Equals(ValueTuple.Create(1, 2, 3, 4, 5, 0), TestEqualityComparer.Instance)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1, 2, 3, 4, 5, 6)).ToString()); var vtWithNull = new ValueTuple(null, null, null, null, null, null); @@ -1040,6 +1106,24 @@ public static void SevenTuples() Assert.False(((IStructuralEquatable)sc).Equals(sc, DummyTestEqualityComparer.Instance)); + Assert.True(ValueTuple.Create(1, 2, 3, 4, 5, 6, 7).Equals(ValueTuple.Create(1, 2, 3, 4, 5, 6, 7))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5, 6, 7).Equals(ValueTuple.Create(0, 2, 3, 4, 5, 6, 7))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5, 6, 7).Equals(ValueTuple.Create(1, 0, 3, 4, 5, 6, 7))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5, 6, 7).Equals(ValueTuple.Create(1, 2, 0, 4, 5, 6, 7))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5, 6, 7).Equals(ValueTuple.Create(1, 2, 3, 0, 5, 6, 7))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5, 6, 7).Equals(ValueTuple.Create(1, 2, 3, 4, 0, 6, 7))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5, 6, 7).Equals(ValueTuple.Create(1, 2, 3, 4, 5, 0, 7))); + Assert.False(ValueTuple.Create(1, 2, 3, 4, 5, 6, 7).Equals(ValueTuple.Create(1, 2, 3, 4, 5, 6, 0))); + + Assert.True(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6, 7)).Equals(ValueTuple.Create(1, 2, 3, 4, 5, 6, 7), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6, 7)).Equals(ValueTuple.Create(0, 2, 3, 4, 5, 6, 7), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6, 7)).Equals(ValueTuple.Create(1, 0, 3, 4, 5, 6, 7), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6, 7)).Equals(ValueTuple.Create(1, 2, 0, 4, 5, 6, 7), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6, 7)).Equals(ValueTuple.Create(1, 2, 3, 0, 5, 6, 7), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6, 7)).Equals(ValueTuple.Create(1, 2, 3, 4, 0, 6, 7), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6, 7)).Equals(ValueTuple.Create(1, 2, 3, 4, 5, 0, 7), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)ValueTuple.Create(1, 2, 3, 4, 5, 6, 7)).Equals(ValueTuple.Create(1, 2, 3, 4, 5, 6, 0), TestEqualityComparer.Instance)); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7)", CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(1, 2, 3, 4, 5, 6, 7)).ToString()); var vtWithNull = new ValueTuple(null, null, null, null, null, null, null); @@ -1109,6 +1193,26 @@ public static void EightTuples() Assert.False(se.Equals(t, DummyTestEqualityComparer.Instance)); + Assert.True(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)).Equals(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)))); + Assert.False(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)).Equals(CreateLong(0, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)))); + Assert.False(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)).Equals(CreateLong(1, 0, 3, 4, 5, 6, 7, ValueTuple.Create(8)))); + Assert.False(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)).Equals(CreateLong(1, 2, 0, 4, 5, 6, 7, ValueTuple.Create(8)))); + Assert.False(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)).Equals(CreateLong(1, 2, 3, 0, 5, 6, 7, ValueTuple.Create(8)))); + Assert.False(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)).Equals(CreateLong(1, 2, 3, 4, 0, 6, 7, ValueTuple.Create(8)))); + Assert.False(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)).Equals(CreateLong(1, 2, 3, 4, 5, 0, 7, ValueTuple.Create(8)))); + Assert.False(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)).Equals(CreateLong(1, 2, 3, 4, 5, 6, 0, ValueTuple.Create(8)))); + Assert.False(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)).Equals(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(0)))); + + Assert.True(((IStructuralEquatable)CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8))).Equals(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8))).Equals(CreateLong(0, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8))).Equals(CreateLong(1, 0, 3, 4, 5, 6, 7, ValueTuple.Create(8)), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8))).Equals(CreateLong(1, 2, 0, 4, 5, 6, 7, ValueTuple.Create(8)), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8))).Equals(CreateLong(1, 2, 3, 0, 5, 6, 7, ValueTuple.Create(8)), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8))).Equals(CreateLong(1, 2, 3, 4, 0, 6, 7, ValueTuple.Create(8)), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8))).Equals(CreateLong(1, 2, 3, 4, 5, 0, 7, ValueTuple.Create(8)), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8))).Equals(CreateLong(1, 2, 3, 4, 5, 6, 0, ValueTuple.Create(8)), TestEqualityComparer.Instance)); + Assert.False(((IStructuralEquatable)CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8))).Equals(CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(0)), TestEqualityComparer.Instance)); + // Notice that 0-tuple prints as empty position Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7, )", CreateLong(1, 2, 3, 4, 5, 6, 7, CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create())).ToString()); From 52ff583dbf5af1f70433c6805f5e0c697426bc52 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 08:56:53 -0700 Subject: [PATCH 158/783] Don't log warnings for certain RemoveAttributeInstances (#91866) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #88994. ILLinker attribute XML format has a way to express "only remove these attributes when parameter X has value of Y". We currently generate a warning and don't trim the attribute at all. The savings from trimming these attributes are going to be miniscule. Even in IL, this is scraping the bottom of the barrel. In Native AOT these attributes are pretty effectively deduplicated across assemblies. We'll likely never need this. This keeps the existing behavior (don't trim the attribute), but removes the warning. Co-authored-by: Michal Strehovský --- .../ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs index fc0249f76847e5..45be574e031eac 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs @@ -1093,7 +1093,7 @@ private void ProcessAttribute(TypeDesc type, XPathNavigator nav) string internalValue = GetAttribute(nav, "internal"); if (!string.IsNullOrEmpty(internalValue)) { - if (!IsRemoveAttributeInstances(internalValue) || !nav.IsEmptyElement) + if (!IsRemoveAttributeInstances(internalValue)) { LogWarning(nav, DiagnosticId.UnrecognizedInternalAttribute, internalValue); } From ac388a199b8c0fda2b13022cfc4b052c5291fba9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 09:07:15 -0700 Subject: [PATCH 159/783] [release/8.0] JIT: Fix illegal IR created by GetElement/ToScalar lowering (#91874) * JIT: Fix illegal IR created by GetElement/ToScalar lowering These could create TYP_ULONG/TYP_UINT indirs/LCL_FLD nodes, which are illegal. Fix #91174 * Add test * Fix license header in new test --------- Co-authored-by: Jakob Botsch Nielsen --- src/coreclr/jit/lowerxarch.cpp | 24 +++++++-------- .../JitBlue/Runtime_91174/Runtime_91174.cs | 30 +++++++++++++++++++ .../Runtime_91174/Runtime_91174.csproj | 8 +++++ 3 files changed, 50 insertions(+), 12 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91174/Runtime_91174.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91174/Runtime_91174.csproj diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 00143839a440d7..d1c3e317d83b87 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -3754,17 +3754,14 @@ GenTree* Lowering::LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node) // We want to optimize GetElement down to an Indir where possible as // this unlocks additional containment opportunities for various nodes - var_types newType; - GenTree* newBase; - GenTree* newIndex; - uint32_t newScale; - int32_t newOffset; + GenTree* newBase; + GenTree* newIndex; + uint32_t newScale; + int32_t newOffset; GenTreeIndir* indir = op1->AsIndir(); GenTree* addr = indir->Addr(); - newType = simdBaseType; - if (addr->OperIsAddrMode()) { // We have an existing addressing mode, so we want to try and @@ -3860,7 +3857,8 @@ GenTree* Lowering::LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node) new (comp, GT_LEA) GenTreeAddrMode(addr->TypeGet(), newBase, newIndex, newScale, newOffset); BlockRange().InsertBefore(node, newAddr); - GenTreeIndir* newIndir = comp->gtNewIndir(newType, newAddr, (indir->gtFlags & GTF_IND_FLAGS)); + GenTreeIndir* newIndir = + comp->gtNewIndir(JITtype2varType(simdBaseJitType), newAddr, (indir->gtFlags & GTF_IND_FLAGS)); BlockRange().InsertBefore(node, newIndir); LIR::Use use; @@ -3911,8 +3909,8 @@ GenTree* Lowering::LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node) if (lclDsc->lvDoNotEnregister && (lclOffs <= 0xFFFF) && ((lclOffs + elemSize) <= lclDsc->lvExactSize())) { - GenTree* lclFld = - comp->gtNewLclFldNode(lclVar->GetLclNum(), simdBaseType, static_cast(lclOffs)); + GenTree* lclFld = comp->gtNewLclFldNode(lclVar->GetLclNum(), JITtype2varType(simdBaseJitType), + static_cast(lclOffs)); BlockRange().InsertBefore(node, lclFld); LIR::Use use; @@ -5327,7 +5325,8 @@ GenTree* Lowering::LowerHWIntrinsicToScalar(GenTreeHWIntrinsic* node) GenTreeIndir* indir = op1->AsIndir(); - GenTreeIndir* newIndir = comp->gtNewIndir(simdBaseType, indir->Addr(), (indir->gtFlags & GTF_IND_FLAGS)); + GenTreeIndir* newIndir = + comp->gtNewIndir(JITtype2varType(simdBaseJitType), indir->Addr(), (indir->gtFlags & GTF_IND_FLAGS)); BlockRange().InsertBefore(node, newIndir); LIR::Use use; @@ -5359,7 +5358,8 @@ GenTree* Lowering::LowerHWIntrinsicToScalar(GenTreeHWIntrinsic* node) if (lclDsc->lvDoNotEnregister && (lclOffs <= 0xFFFF) && ((lclOffs + elemSize) <= lclDsc->lvExactSize())) { - GenTree* lclFld = comp->gtNewLclFldNode(lclVar->GetLclNum(), simdBaseType, lclVar->GetLclOffs()); + GenTree* lclFld = + comp->gtNewLclFldNode(lclVar->GetLclNum(), JITtype2varType(simdBaseJitType), lclVar->GetLclOffs()); BlockRange().InsertBefore(node, lclFld); LIR::Use use; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91174/Runtime_91174.cs b/src/tests/JIT/Regression/JitBlue/Runtime_91174/Runtime_91174.cs new file mode 100644 index 00000000000000..3ae45f998542b4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91174/Runtime_91174.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using Xunit; + +public class Runtime_91174 +{ + [MethodImpl(MethodImplOptions.NoInlining)] + public static int Foo(ref Vector256 v1, ref Vector256 v2) + { + if (Vector256.ToScalar(v1) < Vector256.ToScalar(v2)) + { + Console.WriteLine("FAIL"); + return 101; + } + + return 100; + } + + [Fact] + public static int TestEntryPoint() + { + Vector256 v1 = Vector256.Create(20); + Vector256 v2 = Vector256.Create(10); + return Foo(ref v1, ref v2); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91174/Runtime_91174.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_91174/Runtime_91174.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91174/Runtime_91174.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From 0f3d1ed15f64cb9a9d4f47d1a1ed433e0047e16c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 10:22:35 -0700 Subject: [PATCH 160/783] [release/8.0] [iOS] Fix trimming warnings in HttpClientHandler.AnyMobile (#91877) * Unconditionally supress trimming warnings when calling InvokeNativeHandlerMethod * Update HttpClientHandler --------- Co-authored-by: Simon Rozsival --- ...LLink.Suppressions.Mobile.LibraryBuild.xml | 269 ------------------ .../src/System.Net.Http.csproj | 3 +- ...ntHandler.AnyMobile.InvokeNativeHandler.cs | 192 +++++++------ .../Net/Http/HttpClientHandler.AnyMobile.cs | 23 +- 4 files changed, 112 insertions(+), 375 deletions(-) delete mode 100644 src/libraries/System.Net.Http/src/ILLink/ILLink.Suppressions.Mobile.LibraryBuild.xml diff --git a/src/libraries/System.Net.Http/src/ILLink/ILLink.Suppressions.Mobile.LibraryBuild.xml b/src/libraries/System.Net.Http/src/ILLink/ILLink.Suppressions.Mobile.LibraryBuild.xml deleted file mode 100644 index 7fd4d6a15a34fb..00000000000000 --- a/src/libraries/System.Net.Http/src/ILLink/ILLink.Suppressions.Mobile.LibraryBuild.xml +++ /dev/null @@ -1,269 +0,0 @@ - - - - - ILLink - IL2075 - member - M:System.Net.Http.HttpClientHandler.InvokeNativeHandlerMethod(System.String,System.Object[]) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetUseCookies() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetUseCookies(System.Boolean) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetCookieContainer() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetCookieContainer(System.Net.CookieContainer) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetAllowAutoRedirect() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetAllowAutoRedirect(System.Boolean) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetCredentials() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetCredentials(System.Net.ICredentials) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetAutomaticDecompression() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetAutomaticDecompression(System.Net.DecompressionMethods) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetUseProxy() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetUseProxy(System.Boolean) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetProxy() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetProxy(System.Net.IWebProxy) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetPreAuthenticate() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetPreAuthenticate(System.Boolean) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetMaxAutomaticRedirections() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetMaxAutomaticRedirections(System.Int32) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetServerCertificateCustomValidationCallback - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetServerCertificateCustomValidationCallback(System.Func{System.Net.Http.HttpRequestMessage,System.Security.Cryptography.X509Certificates.X509Certificate2,System.Security.Cryptography.X509Certificates.X509Chain,System.Net.Security.SslPolicyErrors,System.Boolean}) - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetCheckCertificateRevocationList() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetCheckCertificateRevocationList(System.Boolean) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetClientCertificateOptions() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetClientCertificateOptions(System.Net.Http.ClientCertificateOption) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetClientCertificates() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetDefaultProxyCredentials() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetDefaultProxyCredentials(System.Net.ICredentials) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetMaxConnectionsPerServer() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetMaxConnectionsPerServer(System.Int32) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetMaxResponseHeadersLength() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetMaxResponseHeadersLength(System.Int32) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetProperties() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetSupportsAutomaticDecompression() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetSupportsProxy() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetSupportsRedirectConfiguration() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.GetSslProtocols() - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - ILLink - IL2035 - member - M:System.Net.Http.HttpClientHandler.SetSslProtocols(System.Security.Authentication.SslProtocols) - The Xamarin.iOS and Mono.Android libraries are not present when running the trimmer analysis during our build. A consuming application will get a warning if these libraries aren't present when trimming the full app. - - - diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index f263f9480cd67e..67909e99ba391b 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -25,7 +25,6 @@ - @@ -477,4 +476,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.InvokeNativeHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.InvokeNativeHandler.cs index c11aa3a0c323f5..8f8c101b9e4a52 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.InvokeNativeHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.InvokeNativeHandler.cs @@ -6,6 +6,8 @@ using System.Diagnostics.CodeAnalysis; using System.Net.Security; using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; @@ -16,135 +18,130 @@ public partial class HttpClientHandler : HttpMessageHandler private static MethodInfo? _nativeHandlerMethod; #if TARGET_ANDROID - private const string NativeHandlerType = "Xamarin.Android.Net.AndroidMessageHandler"; - private const string AssemblyName = "Mono.Android"; + private const string NativeHandlerType = "Xamarin.Android.Net.AndroidMessageHandler, Mono.Android"; private const string GetHttpMessageHandlerType = "Android.Runtime.AndroidEnvironment, Mono.Android"; #elif TARGET_IOS - private const string NativeHandlerType = "System.Net.Http.NSUrlSessionHandler"; - private const string AssemblyName = "Microsoft.iOS"; + private const string NativeHandlerType = "System.Net.Http.NSUrlSessionHandler, Microsoft.iOS"; private const string GetHttpMessageHandlerType = "ObjCRuntime.RuntimeOptions, Microsoft.iOS"; #elif TARGET_MACCATALYST - private const string NativeHandlerType = "System.Net.Http.NSUrlSessionHandler"; - private const string AssemblyName = "Microsoft.MacCatalyst"; + private const string NativeHandlerType = "System.Net.Http.NSUrlSessionHandler, Microsoft.MacCatalyst"; private const string GetHttpMessageHandlerType = "ObjCRuntime.RuntimeOptions, Microsoft.MacCatalyst"; #elif TARGET_TVOS - private const string NativeHandlerType = "System.Net.Http.NSUrlSessionHandler"; - private const string AssemblyName = "Microsoft.tvOS"; + private const string NativeHandlerType = "System.Net.Http.NSUrlSessionHandler, Microsoft.tvOS"; private const string GetHttpMessageHandlerType = "ObjCRuntime.RuntimeOptions, Microsoft.tvOS"; #else #error Unknown target #endif - [DynamicDependency("get_DefaultProxyCredentials", NativeHandlerType, AssemblyName)] - private ICredentials? GetDefaultProxyCredentials() => (ICredentials?)InvokeNativeHandlerMethod("get_DefaultProxyCredentials"); + private ICredentials? GetDefaultProxyCredentials() + => (ICredentials?)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_DefaultProxyCredentials")!); - [DynamicDependency("set_DefaultProxyCredentials", NativeHandlerType, AssemblyName)] - private void SetDefaultProxyCredentials(ICredentials? value) => InvokeNativeHandlerMethod("set_DefaultProxyCredentials", value); + private void SetDefaultProxyCredentials(ICredentials? value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_DefaultProxyCredentials")!, value); - [DynamicDependency("get_MaxConnectionsPerServer", NativeHandlerType, AssemblyName)] - private int GetMaxConnectionsPerServer() => (int)InvokeNativeHandlerMethod("get_MaxConnectionsPerServer"); + private int GetMaxConnectionsPerServer() + => (int)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_MaxConnectionsPerServer")!); - [DynamicDependency("set_MaxConnectionsPerServer", NativeHandlerType, AssemblyName)] - private void SetMaxConnectionsPerServer(int value) => InvokeNativeHandlerMethod("set_MaxConnectionsPerServer", value); + private void SetMaxConnectionsPerServer(int value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_MaxConnectionsPerServer")!, value); - [DynamicDependency("get_MaxResponseHeadersLength", NativeHandlerType, AssemblyName)] - private int GetMaxResponseHeadersLength() => (int)InvokeNativeHandlerMethod("get_MaxResponseHeadersLength"); + private int GetMaxResponseHeadersLength() + => (int)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_MaxResponseHeadersLength")!); - [DynamicDependency("set_MaxResponseHeadersLength", NativeHandlerType, AssemblyName)] - private void SetMaxResponseHeadersLength(int value) => InvokeNativeHandlerMethod("set_MaxResponseHeadersLength", value); + private void SetMaxResponseHeadersLength(int value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_MaxResponseHeadersLength")!, value); - [DynamicDependency("get_ClientCertificateOptions", NativeHandlerType, AssemblyName)] - private ClientCertificateOption GetClientCertificateOptions() => (ClientCertificateOption)InvokeNativeHandlerMethod("get_ClientCertificateOptions"); + private ClientCertificateOption GetClientCertificateOptions() + => (ClientCertificateOption)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_ClientCertificateOptions")!); - [DynamicDependency("set_ClientCertificateOptions", NativeHandlerType, AssemblyName)] - private void SetClientCertificateOptions(ClientCertificateOption value) => InvokeNativeHandlerMethod("set_ClientCertificateOptions", value); + private void SetClientCertificateOptions(ClientCertificateOption value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_ClientCertificateOptions")!, value); - [DynamicDependency("get_ClientCertificates", NativeHandlerType, AssemblyName)] - private X509CertificateCollection GetClientCertificates() => (X509CertificateCollection)InvokeNativeHandlerMethod("get_ClientCertificates"); + private X509CertificateCollection GetClientCertificates() + => (X509CertificateCollection)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_ClientCertificates")!); - [DynamicDependency("get_ServerCertificateCustomValidationCallback", NativeHandlerType, AssemblyName)] - private Func GetServerCertificateCustomValidationCallback() => (Func)InvokeNativeHandlerMethod("get_ServerCertificateCustomValidationCallback"); + private Func GetServerCertificateCustomValidationCallback() + => (Func)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_ServerCertificateCustomValidationCallback")!); - [DynamicDependency("set_ServerCertificateCustomValidationCallback", NativeHandlerType, AssemblyName)] - private void SetServerCertificateCustomValidationCallback(Func? value) => InvokeNativeHandlerMethod("set_ServerCertificateCustomValidationCallback", value); + private void SetServerCertificateCustomValidationCallback(Func? value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_ServerCertificateCustomValidationCallback")!, value); - [DynamicDependency("get_CheckCertificateRevocationList", NativeHandlerType, AssemblyName)] - private bool GetCheckCertificateRevocationList() => (bool)InvokeNativeHandlerMethod("get_CheckCertificateRevocationList"); + private bool GetCheckCertificateRevocationList() + => (bool)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_CheckCertificateRevocationList")!); - [DynamicDependency("set_CheckCertificateRevocationList", NativeHandlerType, AssemblyName)] - private void SetCheckCertificateRevocationList(bool value) => InvokeNativeHandlerMethod("set_CheckCertificateRevocationList", value); + private void SetCheckCertificateRevocationList(bool value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_CheckCertificateRevocationList")!, value); - [DynamicDependency("get_SslProtocols", NativeHandlerType, AssemblyName)] - private SslProtocols GetSslProtocols() => (SslProtocols)InvokeNativeHandlerMethod("get_SslProtocols"); + private SslProtocols GetSslProtocols() + => (SslProtocols)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_SslProtocols")!); - [DynamicDependency("set_SslProtocols", NativeHandlerType, AssemblyName)] - private void SetSslProtocols(SslProtocols value) => InvokeNativeHandlerMethod("set_SslProtocols", value); + private void SetSslProtocols(SslProtocols value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_SslProtocols")!, value); - [DynamicDependency("get_Properties", NativeHandlerType, AssemblyName)] - private IDictionary GetProperties() => (IDictionary)InvokeNativeHandlerMethod("get_Properties"); + private IDictionary GetProperties() + => (IDictionary)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_Properties")!); - [DynamicDependency("get_SupportsAutomaticDecompression", NativeHandlerType, AssemblyName)] - private bool GetSupportsAutomaticDecompression() => (bool)InvokeNativeHandlerMethod("get_SupportsAutomaticDecompression"); + private bool GetSupportsAutomaticDecompression() + => (bool)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_SupportsAutomaticDecompression")!); - [DynamicDependency("get_SupportsProxy", NativeHandlerType, AssemblyName)] - private bool GetSupportsProxy() => (bool)InvokeNativeHandlerMethod("get_SupportsProxy"); + private bool GetSupportsProxy() + => (bool)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_SupportsProxy")!); - [DynamicDependency("get_SupportsRedirectConfiguration", NativeHandlerType, AssemblyName)] - private bool GetSupportsRedirectConfiguration() => (bool)InvokeNativeHandlerMethod("get_SupportsRedirectConfiguration"); + private bool GetSupportsRedirectConfiguration() + => (bool)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_SupportsRedirectConfiguration")!); - [DynamicDependency("get_AutomaticDecompression", NativeHandlerType, AssemblyName)] - private DecompressionMethods GetAutomaticDecompression() => (DecompressionMethods)InvokeNativeHandlerMethod("get_AutomaticDecompression"); + private DecompressionMethods GetAutomaticDecompression() + => (DecompressionMethods)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_AutomaticDecompression")!); - [DynamicDependency("set_AutomaticDecompression", NativeHandlerType, AssemblyName)] - private void SetAutomaticDecompression(DecompressionMethods value) => InvokeNativeHandlerMethod("set_AutomaticDecompression", value); + private void SetAutomaticDecompression(DecompressionMethods value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_AutomaticDecompression")!, value); - [DynamicDependency("get_UseProxy", NativeHandlerType, AssemblyName)] - private bool GetUseProxy() => (bool)InvokeNativeHandlerMethod("get_UseProxy"); + private bool GetUseProxy() + => (bool)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_UseProxy")!); - [DynamicDependency("set_UseProxy", NativeHandlerType, AssemblyName)] - private void SetUseProxy(bool value) => InvokeNativeHandlerMethod("set_UseProxy", value); + private void SetUseProxy(bool value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_UseProxy")!, value); - [DynamicDependency("get_Proxy", NativeHandlerType, AssemblyName)] - private IWebProxy GetProxy() => (IWebProxy)InvokeNativeHandlerMethod("get_Proxy"); + private IWebProxy GetProxy() + => (IWebProxy)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_Proxy")!); - [DynamicDependency("set_Proxy", NativeHandlerType, AssemblyName)] - private void SetProxy(IWebProxy value) => InvokeNativeHandlerMethod("set_Proxy", value); + private void SetProxy(IWebProxy value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_Proxy")!, value); - [DynamicDependency("get_PreAuthenticate", NativeHandlerType, AssemblyName)] - private bool GetPreAuthenticate() => (bool)InvokeNativeHandlerMethod("get_PreAuthenticate"); + private bool GetPreAuthenticate() + => (bool)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_PreAuthenticate")!); - [DynamicDependency("set_PreAuthenticate", NativeHandlerType, AssemblyName)] - private void SetPreAuthenticate(bool value) => InvokeNativeHandlerMethod("set_PreAuthenticate", value); + private void SetPreAuthenticate(bool value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_PreAuthenticate")!, value); - [DynamicDependency("get_MaxAutomaticRedirections", NativeHandlerType, AssemblyName)] - private int GetMaxAutomaticRedirections() => (int)InvokeNativeHandlerMethod("get_MaxAutomaticRedirections"); + private int GetMaxAutomaticRedirections() + => (int)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_MaxAutomaticRedirections")!); - [DynamicDependency("set_MaxAutomaticRedirections", NativeHandlerType, AssemblyName)] - private void SetMaxAutomaticRedirections(int value) => InvokeNativeHandlerMethod("set_MaxAutomaticRedirections", value); + private void SetMaxAutomaticRedirections(int value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_MaxAutomaticRedirections")!, value); - [DynamicDependency("get_UseCookies", NativeHandlerType, AssemblyName)] - private bool GetUseCookies() => (bool)InvokeNativeHandlerMethod("get_UseCookies"); + private bool GetUseCookies() => (bool)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_UseCookies")!); - [DynamicDependency("set_UseCookies", NativeHandlerType, AssemblyName)] - private void SetUseCookies(bool value) => InvokeNativeHandlerMethod("set_UseCookies", value); + private void SetUseCookies(bool value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_UseCookies")!, value); - [DynamicDependency("get_CookieContainer", NativeHandlerType, AssemblyName)] - private CookieContainer GetCookieContainer() => (CookieContainer)InvokeNativeHandlerMethod("get_CookieContainer"); + private CookieContainer GetCookieContainer() + => (CookieContainer)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_CookieContainer")!); - [DynamicDependency("set_CookieContainer", NativeHandlerType, AssemblyName)] - private void SetCookieContainer(CookieContainer value) => InvokeNativeHandlerMethod("set_CookieContainer", value); + private void SetCookieContainer(CookieContainer value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_CookieContainer")!, value); - [DynamicDependency("get_AllowAutoRedirect", NativeHandlerType, AssemblyName)] - private bool GetAllowAutoRedirect() => (bool)InvokeNativeHandlerMethod("get_AllowAutoRedirect"); + private bool GetAllowAutoRedirect() + => (bool)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_AllowAutoRedirect")!); - [DynamicDependency("set_AllowAutoRedirect", NativeHandlerType, AssemblyName)] - private void SetAllowAutoRedirect(bool value) => InvokeNativeHandlerMethod("set_AllowAutoRedirect", value); + private void SetAllowAutoRedirect(bool value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_AllowAutoRedirect")!, value); - [DynamicDependency("get_Credentials", NativeHandlerType, AssemblyName)] - private ICredentials GetCredentials() => (ICredentials)InvokeNativeHandlerMethod("get_Credentials"); + private ICredentials GetCredentials() + => (ICredentials)InvokeNativeHandlerGetter(() => Type.GetType(NativeHandlerType)!.GetMethod("get_Credentials")!); - [DynamicDependency("set_Credentials", NativeHandlerType, AssemblyName)] - private void SetCredentials(ICredentials? value) => InvokeNativeHandlerMethod("set_Credentials", value); + private void SetCredentials(ICredentials? value) + => InvokeNativeHandlerSetter(() => Type.GetType(NativeHandlerType)!.GetMethod("set_Credentials")!, value); private static HttpMessageHandler CreateNativeHandler() { @@ -156,5 +153,36 @@ private static HttpMessageHandler CreateNativeHandler() return (HttpMessageHandler)_nativeHandlerMethod!.Invoke(null, null)!; } + + private object InvokeNativeHandlerGetter(Func getMethod, [CallerMemberName] string? cachingKey = null) + { + return InvokeNativeHandlerMethod(getMethod, parameters: null, cachingKey!); + } + + private void InvokeNativeHandlerSetter(Func getMethod, object? value, [CallerMemberName] string? cachingKey = null) + { + InvokeNativeHandlerMethod(getMethod, parameters: new object?[] { value }, cachingKey!); + } + + private object InvokeNativeHandlerMethod(Func getMethod, object?[]? parameters, string cachingKey) + { + MethodInfo? method; + + if (!s_cachedMethods.TryGetValue(cachingKey, out method)) + { + method = getMethod(); + s_cachedMethods[cachingKey] = method; + } + + try + { + return method!.Invoke(_nativeHandler, parameters)!; + } + catch (TargetInvocationException e) + { + ExceptionDispatchInfo.Capture(e.InnerException!).Throw(); + throw; + } + } } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs index d1b3db12b8ed1c..dd7d005dbc3c27 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs @@ -4,12 +4,12 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Metrics; using System.Globalization; using System.Net.Http.Metrics; using System.Net.Security; using System.Reflection; -using System.Runtime.ExceptionServices; using System.Runtime.Versioning; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; @@ -796,27 +796,6 @@ private void ThrowForModifiedManagedSslOptionsIfStarted() _socketHandler!.SslOptions = _socketHandler!.SslOptions; } - private object InvokeNativeHandlerMethod(string name, params object?[] parameters) - { - MethodInfo? method; - - if (!s_cachedMethods.TryGetValue(name, out method)) - { - method = _nativeHandler!.GetType()!.GetMethod(name); - s_cachedMethods[name] = method; - } - - try - { - return method!.Invoke(_nativeHandler, parameters)!; - } - catch (TargetInvocationException e) - { - ExceptionDispatchInfo.Capture(e.InnerException!).Throw(); - throw; - } - } - private static bool IsNativeHandlerEnabled => RuntimeSettingParser.QueryRuntimeSettingSwitch( "System.Net.Http.UseNativeHttpHandler", false); From e32d6d4ee0fc2e26ae6bee015d54bc5eca229fb0 Mon Sep 17 00:00:00 2001 From: Natalia Kondratyeva Date: Tue, 12 Sep 2023 22:26:34 +0000 Subject: [PATCH 161/783] Merged PR 33648: [release/8.0] Update MsQuic --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 646f22880d530d..15b861e0b7ecca 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -219,7 +219,7 @@ 8.0.0-rc.2.23454.2 - 2.2.2 + 2.2.3-ci.391104 8.0.0-alpha.1.23412.1 16.0.5-alpha.1.23423.1 From d34a059b42a333956dfab085c8011b8d05ba5066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Wed, 13 Sep 2023 11:46:12 -0700 Subject: [PATCH 162/783] Revert "[release/8.0] Update dependencies from dotnet/roslyn (#91482)" (#92011) This reverts commit 282da2cd568a4e1429990d3257efbc3724b79fee. --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 942050ec170f13..68a0bcba3d449d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - d080175cabfe297ebf079af099279b61913bcc28 + 3686f3061a9202260a0de4d06e91855b0fa21e8c - + https://github.com/dotnet/roslyn - d080175cabfe297ebf079af099279b61913bcc28 + 3686f3061a9202260a0de4d06e91855b0fa21e8c - + https://github.com/dotnet/roslyn - d080175cabfe297ebf079af099279b61913bcc28 + 3686f3061a9202260a0de4d06e91855b0fa21e8c https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index 646f22880d530d..25577272a24e6e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -42,9 +42,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23459.2 - 4.8.0-3.23459.2 - 4.8.0-3.23459.2 + 4.8.0-3.23451.1 + 4.8.0-3.23451.1 + 4.8.0-3.23451.1 diff --git a/eng/Versions.props b/eng/Versions.props index 25577272a24e6e..ab7d5680216416 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -156,12 +156,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23458.2 - 1.0.0-prerelease.23458.2 - 1.0.0-prerelease.23458.2 - 1.0.0-prerelease.23458.2 - 1.0.0-prerelease.23458.2 - 1.0.0-prerelease.23458.2 + 1.0.0-prerelease.23462.6 + 1.0.0-prerelease.23462.6 + 1.0.0-prerelease.23462.6 + 1.0.0-prerelease.23462.6 + 1.0.0-prerelease.23462.6 + 1.0.0-prerelease.23462.6 16.11.27-beta1.23180.1 2.0.0-beta4.23307.1 From 6afd6964b0dfa2e1f2fb6491ff6ac8e615b7442f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 09:50:09 -0700 Subject: [PATCH 172/783] [release/8.0] Don't shut down event pipe in DLLs on Windows (#92044) Trying to enable EventSourceSupport in a shared library project on Native AOT currently results in a build failure since this is actively blocked in the targets. But EventSourceSupport/event pipe mostly work, with some issues (#91762). The blocking makes it impossible for anyone to run diagnostics on their shared library. This is a regression from .NET 7, where it was at least possible to get GC ETW events in PerfView on Windows. This changes the blocking to a suppressible warning, and fixes and issue that was causing a shutdown hang. --- src/coreclr/nativeaot/Bootstrap/main.cpp | 10 +++++++-- .../Microsoft.NETCore.Native.Publish.targets | 3 +-- src/coreclr/nativeaot/Runtime/startup.cpp | 22 ++++++++++++++++--- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/coreclr/nativeaot/Bootstrap/main.cpp b/src/coreclr/nativeaot/Bootstrap/main.cpp index cc78cf8d6710a9..c2ff85b50e81fd 100644 --- a/src/coreclr/nativeaot/Bootstrap/main.cpp +++ b/src/coreclr/nativeaot/Bootstrap/main.cpp @@ -93,7 +93,7 @@ static char& __unbox_z = __stop___unbox; #endif // _MSC_VER -extern "C" bool RhInitialize(); +extern "C" bool RhInitialize(bool isDll); extern "C" void RhSetRuntimeInitializationCallback(int (*fPtr)()); extern "C" bool RhRegisterOSModule(void * pModule, @@ -164,7 +164,13 @@ extern "C" void __managed__Startup(); static int InitializeRuntime() { - if (!RhInitialize()) + if (!RhInitialize( +#ifdef NATIVEAOT_DLL + /* isDll */ true +#else + /* isDll */ false +#endif + )) return -1; void * osModule = PalGetModuleHandleFromPointer((void*)&NATIVEAOT_ENTRYPOINT); diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets index 32eefb307eb0fd..caee0777b30ddd 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets @@ -50,8 +50,7 @@ Text="RuntimeIdentifier is required for native compilation. Try running dotnet publish with the -r option value specified." /> - - + diff --git a/src/coreclr/nativeaot/Runtime/startup.cpp b/src/coreclr/nativeaot/Runtime/startup.cpp index 32cbab53cb8304..5db04aa27766dd 100644 --- a/src/coreclr/nativeaot/Runtime/startup.cpp +++ b/src/coreclr/nativeaot/Runtime/startup.cpp @@ -297,6 +297,10 @@ static void UninitDLL() Thread* g_threadPerformingShutdown = NULL; #endif +#if defined(_WIN32) && defined(FEATURE_PERFTRACING) +bool g_safeToShutdownTracing; +#endif + static void __cdecl OnProcessExit() { #ifdef _WIN32 @@ -309,8 +313,16 @@ static void __cdecl OnProcessExit() #endif #ifdef FEATURE_PERFTRACING - EventPipe_Shutdown(); - DiagnosticServer_Shutdown(); +#ifdef _WIN32 + // We forgo shutting down event pipe if it wouldn't be safe and could lead to a hang. + // If there was an active trace session, the trace will likely be corrupted without + // orderly shutdown. See https://github.com/dotnet/runtime/issues/89346. + if (g_safeToShutdownTracing) +#endif + { + EventPipe_Shutdown(); + DiagnosticServer_Shutdown(); + } #endif } @@ -348,7 +360,7 @@ void RuntimeThreadShutdown(void* thread) #endif } -extern "C" bool RhInitialize() +extern "C" bool RhInitialize(bool isDll) { if (!PalInit()) return false; @@ -357,6 +369,10 @@ extern "C" bool RhInitialize() atexit(&OnProcessExit); #endif +#if defined(_WIN32) && defined(FEATURE_PERFTRACING) + g_safeToShutdownTracing = !isDll; +#endif + if (!InitDLL(PalGetModuleHandleFromPointer((void*)&RhInitialize))) return false; From 18ac00889e96961119db0b72fe1532d2299d292a Mon Sep 17 00:00:00 2001 From: Nikola Milosavljevic Date: Thu, 14 Sep 2023 10:39:41 -0700 Subject: [PATCH 173/783] Update THIRD-PARTY-NOTICES for 8.0 release (#91933) * Update THIRD-PARTY-NOTICES for 8.0 release * Addressed review comments * Remove test-only notice --- THIRD-PARTY-NOTICES.TXT | 8 +- src/installer/pkg/THIRD-PARTY-NOTICES.TXT | 343 +++++++++++++++++++++- 2 files changed, 345 insertions(+), 6 deletions(-) diff --git a/THIRD-PARTY-NOTICES.TXT b/THIRD-PARTY-NOTICES.TXT index 53855810b5af9f..4b40333f72ce4f 100644 --- a/THIRD-PARTY-NOTICES.TXT +++ b/THIRD-PARTY-NOTICES.TXT @@ -480,8 +480,8 @@ Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital Equipment Corporation makes any representations about the suitability of this software for any purpose." -License notice for The LLVM Compiler Infrastructure ---------------------------------------------------- +License notice for The LLVM Compiler Infrastructure (Legacy License) +-------------------------------------------------------------------- Developed by: @@ -986,8 +986,8 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -License for remote stack unwind (https://github.com/llvm/llvm-project/blob/main/lldb/source/Symbol/CompactUnwindInfo.cpp) --------------------------------------- +License notice for The LLVM Project +----------------------------------- Copyright 2019 LLVM Project diff --git a/src/installer/pkg/THIRD-PARTY-NOTICES.TXT b/src/installer/pkg/THIRD-PARTY-NOTICES.TXT index fcb519506d511e..237af34f098f15 100644 --- a/src/installer/pkg/THIRD-PARTY-NOTICES.TXT +++ b/src/installer/pkg/THIRD-PARTY-NOTICES.TXT @@ -449,8 +449,8 @@ Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital Equipment Corporation makes any representations about the suitability of this software for any purpose." -License notice for The LLVM Compiler Infrastructure ---------------------------------------------------- +License notice for The LLVM Compiler Infrastructure (Legacy License) +-------------------------------------------------------------------- Developed by: @@ -1481,3 +1481,342 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +Copyright (c) 2015, Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +License for C# Implementation of Fast CRC Computation +----------------------------------------------------- + +https://github.com/SixLabors/ImageSharp/blob/f4f689ce67ecbcc35cebddba5aacb603e6d1068a/src/ImageSharp/Formats/Png/Zlib/Crc32.cs + +Copyright (c) Six Labors. +Licensed under the Apache License, Version 2.0. + +Available at +https://github.com/SixLabors/ImageSharp/blob/f4f689ce67ecbcc35cebddba5aacb603e6d1068a/LICENSE + +License for Fast CRC Computation +-------------------------------------- + +https://github.com/intel/isa-l/blob/33a2d9484595c2d6516c920ce39a694c144ddf69/crc/crc32_ieee_by4.asm +https://github.com/intel/isa-l/blob/33a2d9484595c2d6516c920ce39a694c144ddf69/crc/crc64_ecma_norm_by8.asm + +Copyright(c) 2011-2015 Intel Corporation All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License for fastmod (https://github.com/lemire/fastmod), ibm-fpgen (https://github.com/nigeltao/parse-number-fxx-test-data) and fastrange (https://github.com/lemire/fastrange) +-------------------------------------- + + Copyright 2018 Daniel Lemire + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +License for Jb Evain +--------------------- + +Copyright (c) 2006 Jb Evain (jbevain@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +--- Optional exception to the license --- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into a machine-executable object form of such +source code, you may redistribute such embedded portions in such object form +without including the above copyright and permission notices. + +License for MurmurHash3 +-------------------------------------- + +https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp + +MurmurHash3 was written by Austin Appleby, and is placed in the public +domain. The author hereby disclaims copyright to this source + +License notice for The LLVM Project +----------------------------------- + +Copyright 2019 LLVM Project + +Licensed under the Apache License, Version 2.0 (the "License") with LLVM Exceptions; +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +https://llvm.org/LICENSE.txt + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +License for sse4-strstr (https://github.com/WojciechMula/sse4-strstr) +-------------------------------------- + + Copyright (c) 2008-2016, Wojciech Mula + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License for the Teddy multi-substring searching implementation +-------------------------------------- + +https://github.com/BurntSushi/aho-corasick + +The MIT License (MIT) + +Copyright (c) 2015 Andrew Gallant + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +License notice for amd/aocl-libm-ose +------------------------------- + +Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +License notice for code from The Practice of Programming +------------------------------- + +Copyright (C) 1999 Lucent Technologies + +Excerpted from 'The Practice of Programming +by Brian W. Kernighan and Rob Pike + +You may use this code for any purpose, as long as you leave the copyright notice and book citation attached. + +License notice for fmtlib/fmt +------------------------------- + +Formatting library for C++ + +Copyright (c) 2012 - present, Victor Zverovich + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +License notice for gRPC +=================================== + +Copyright 2019 The gRPC Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +License notice for m-ou-se/floatconv +------------------------------- + +Copyright (c) 2020 Mara Bos +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License notice for MsQuic +-------------------------------------- + +Copyright (c) Microsoft Corporation. +Licensed under the MIT License. + +Available at +https://github.com/microsoft/msquic/blob/main/LICENSE + +License notice for vectorized hex parsing +-------------------------------------------------------- + +Copyright (c) 2022, Geoff Langdale +Copyright (c) 2022, Wojciech Mula +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +- Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Notice for Euclidean Affine Functions and Applications to Calendar +Algorithms +------------------------------- + +Aspects of Date/Time processing based on algorithm described in "Euclidean Affine Functions and Applications to Calendar +Algorithms", Cassio Neri and Lorenz Schneider. https://arxiv.org/pdf/2102.06959.pdf From 3aec9611c87bd4ec3432123a1e598d8eccee0c4d Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Thu, 14 Sep 2023 10:44:58 -0700 Subject: [PATCH 174/783] [release/8.0] Metrics Feature Switch (#92019) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Metrics Feature Switch * Add missed empty lines --------- Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- docs/workflow/trimming/feature-switches.md | 1 + .../ILLink/ILLink.Substitutions.Shared.xml | 10 ++++ ...System.Diagnostics.DiagnosticSource.csproj | 4 ++ .../System/Diagnostics/Metrics/Instrument.cs | 6 ++ .../src/System/Diagnostics/Metrics/Meter.cs | 10 ++++ .../Diagnostics/Metrics/MeterListener.cs | 32 ++++++++++- ....Diagnostics.DiagnosticSource.Tests.csproj | 1 + .../tests/TestNotSupported.cs | 56 +++++++++++++++++++ 8 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 src/libraries/System.Diagnostics.DiagnosticSource/src/ILLink/ILLink.Substitutions.Shared.xml create mode 100644 src/libraries/System.Diagnostics.DiagnosticSource/tests/TestNotSupported.cs diff --git a/docs/workflow/trimming/feature-switches.md b/docs/workflow/trimming/feature-switches.md index 7fa3045547e0f0..635187684116b5 100644 --- a/docs/workflow/trimming/feature-switches.md +++ b/docs/workflow/trimming/feature-switches.md @@ -13,6 +13,7 @@ configurations but their defaults might vary as any SDK can set the defaults dif | EnableUnsafeBinaryFormatterSerialization | System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization | BinaryFormatter serialization support is trimmed when set to false | | EventSourceSupport | System.Diagnostics.Tracing.EventSource.IsSupported | Any EventSource related code or logic is trimmed when set to false | | InvariantGlobalization | System.Globalization.Invariant | All globalization specific code and data is trimmed when set to true | +| MetricsSupport | System.Diagnostics.Metrics.Meter.IsSupported | Any Metrics related code or logic is trimmed when set to false | | PredefinedCulturesOnly | System.Globalization.PredefinedCulturesOnly | Don't allow creating a culture for which the platform does not have data | | HybridGlobalization | System.Globalization.Hybrid | Properties connected with the mixed: platform-specific + icu-based globalization will be trimmed | | UseSystemResourceKeys | System.Resources.UseSystemResourceKeys | Any localizable resources for system assemblies is trimmed when set to true | diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/ILLink/ILLink.Substitutions.Shared.xml b/src/libraries/System.Diagnostics.DiagnosticSource/src/ILLink/ILLink.Substitutions.Shared.xml new file mode 100644 index 00000000000000..b67ac8623c402a --- /dev/null +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/ILLink/ILLink.Substitutions.Shared.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj index 24a23478b7c0c2..49b7834a9de36c 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -20,6 +20,10 @@ System.Diagnostics.DiagnosticSource true + + + + diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Instrument.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Instrument.cs index 0cb50f523f0282..c1e2fcb199b3a5 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Instrument.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Instrument.cs @@ -64,6 +64,12 @@ protected Instrument(Meter meter, string name, string? unit, string? description /// protected void Publish() { + // All instruments call Publish when they are created. We don't want to publish the instrument if the Meter is not supported. + if (!Meter.IsSupported) + { + return; + } + List? allListeners = null; lock (Instrument.SyncObject) { diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Meter.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Meter.cs index a5722aa7b6c4dc..60314b1d5b4c00 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Meter.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Meter.cs @@ -17,6 +17,11 @@ public class Meter : IDisposable private Dictionary> _nonObservableInstrumentsCache = new(); internal bool Disposed { get; private set; } + internal static bool IsSupported { get; } = InitializeIsSupported(); + + private static bool InitializeIsSupported() => + AppContext.TryGetSwitch("System.Diagnostics.Metrics.Meter.IsSupported", out bool isSupported) ? isSupported : true; + /// /// Initialize a new instance of the Meter using the . /// @@ -77,6 +82,11 @@ private void Initialize(string name, string? version, IEnumerable - /// A delegate to represent the Meterlistener callbacks used in measurements recording operation. + /// A delegate to represent the MeterListener callbacks used in measurements recording operation. /// public delegate void MeasurementCallback(Instrument instrument, T measurement, ReadOnlySpan> tags, object? state) where T : struct; @@ -56,6 +56,11 @@ public MeterListener() { } /// A state object which will be passed back to the callback getting measurements events. public void EnableMeasurementEvents(Instrument instrument, object? state = null) { + if (!Meter.IsSupported) + { + return; + } + bool oldStateStored = false; bool enabled = false; object? oldState = null; @@ -92,6 +97,11 @@ public void EnableMeasurementEvents(Instrument instrument, object? state = null) /// The state object originally passed to method. public object? DisableMeasurementEvents(Instrument instrument) { + if (!Meter.IsSupported) + { + return default; + } + object? state = null; lock (Instrument.SyncObject) { @@ -114,6 +124,11 @@ public void EnableMeasurementEvents(Instrument instrument, object? state = null) /// The callback which can be used to get measurement recording of numeric type T. public void SetMeasurementEventCallback(MeasurementCallback? measurementCallback) where T : struct { + if (!Meter.IsSupported) + { + return; + } + measurementCallback ??= (instrument, measurement, tags, state) => { /* no-op */}; if (typeof(T) == typeof(byte)) @@ -155,6 +170,11 @@ public void SetMeasurementEventCallback(MeasurementCallback? measurementCa /// public void Start() { + if (!Meter.IsSupported) + { + return; + } + List? publishedInstruments = null; lock (Instrument.SyncObject) { @@ -184,6 +204,11 @@ public void Start() /// public void RecordObservableInstruments() { + if (!Meter.IsSupported) + { + return; + } + List? exceptionsList = null; DiagNode? current = _enabledMeasurementInstruments.First; while (current is not null) @@ -215,6 +240,11 @@ public void RecordObservableInstruments() /// public void Dispose() { + if (!Meter.IsSupported) + { + return; + } + Dictionary? callbacksArguments = null; Action? measurementsCompleted = MeasurementsCompleted; diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/System.Diagnostics.DiagnosticSource.Tests.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/tests/System.Diagnostics.DiagnosticSource.Tests.csproj index 7e8136e0a1a6b9..29a8e55dc2fc02 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/System.Diagnostics.DiagnosticSource.Tests.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/System.Diagnostics.DiagnosticSource.Tests.csproj @@ -11,6 +11,7 @@ + diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/TestNotSupported.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/TestNotSupported.cs new file mode 100644 index 00000000000000..43fae749957204 --- /dev/null +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/TestNotSupported.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.DotNet.RemoteExecutor; +using System.Diagnostics.Metrics; +using Xunit; + +namespace System.Diagnostics.Metrics.Tests +{ + public class MetricsNotSupportedTest + { + /// + /// Tests using Metrics when the System.Diagnostics.Metrics.Meter.IsSupported + /// feature switch is set to disable all metrics operations. + /// + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [InlineData(false)] + [InlineData(true)] + public void IsSupportedSwitch(bool value) + { + RemoteInvokeOptions options = new RemoteInvokeOptions(); + options.RuntimeConfigurationOptions.Add("System.Diagnostics.Metrics.Meter.IsSupported", value); + + RemoteExecutor.Invoke((val) => + { + bool isSupported = bool.Parse(val); + + Meter meter = new Meter("IsSupportedTest"); + Counter counter = meter.CreateCounter("counter"); + bool instrumentsPublished = false; + bool instrumentCompleted = false; + long counterValue = 100; + + using (MeterListener listener = new MeterListener + { + InstrumentPublished = (instruments, theListener) => instrumentsPublished = true, + MeasurementsCompleted = (instruments, state) => instrumentCompleted = true + }) + { + listener.EnableMeasurementEvents(counter, null); + listener.SetMeasurementEventCallback((inst, measurement, tags, state) => counterValue = measurement); + listener.Start(); + + Assert.Equal(isSupported, counter.Enabled); + + counter.Add(20); + } + meter.Dispose(); + + Assert.Equal(isSupported, instrumentsPublished); + Assert.Equal(isSupported, instrumentCompleted); + Assert.Equal(isSupported ? 20 : 100, counterValue); + }, value.ToString(), options).Dispose(); + } + } +} From 1978fc2974bdeb0b08c114b61b3d423cef42269f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 10:45:18 -0700 Subject: [PATCH 175/783] [release/8.0] Arm64: Pass the small size accurately to emitIns_valid_imm_for_ldst_offset (#92041) * Pass the right size to check if immediate will fit or not * Revert "Pass the right size to check if immediate will fit or not" This reverts commit d7c511abce6634d65434a149e719c6f4516d6966. * review feedback * fix the size to be passed to the instruction * fix the assert --------- Co-authored-by: Kunal Pathak --- src/coreclr/jit/codegenarm64.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index f99602d21d953b..d937cd67747e25 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -327,19 +327,38 @@ bool CodeGen::genInstrWithConstant(instruction ins, break; case INS_strb: + assert(size == EA_1BYTE); + immFitsInIns = emitter::emitIns_valid_imm_for_ldst_offset(imm, EA_1BYTE); + break; + case INS_strh: + assert(size == EA_2BYTE); + immFitsInIns = emitter::emitIns_valid_imm_for_ldst_offset(imm, EA_2BYTE); + break; + case INS_str: // reg1 is a source register for store instructions assert(tmpReg != reg1); // regTmp can not match any source register immFitsInIns = emitter::emitIns_valid_imm_for_ldst_offset(imm, size); break; + case INS_ldrb: case INS_ldrsb: + immFitsInIns = emitter::emitIns_valid_imm_for_ldst_offset(imm, EA_1BYTE); + break; + + case INS_ldrh: case INS_ldrsh: + immFitsInIns = emitter::emitIns_valid_imm_for_ldst_offset(imm, EA_2BYTE); + break; + case INS_ldrsw: - case INS_ldrb: - case INS_ldrh: + assert(size == EA_4BYTE); + immFitsInIns = emitter::emitIns_valid_imm_for_ldst_offset(imm, EA_4BYTE); + break; + case INS_ldr: + assert((size == EA_4BYTE) || (size == EA_8BYTE) || (size == EA_16BYTE)); immFitsInIns = emitter::emitIns_valid_imm_for_ldst_offset(imm, size); break; From 5c02390cfbbb0befd4b2e3a18f099ef3bfad7da6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 10:47:04 -0700 Subject: [PATCH 176/783] [release/8.0] Fix si.ibAllocated in FrozenObjectHeapManager (#92052) * Fix si.ibAllocated in FrozenObjectHeapManager * Add an assert --------- Co-authored-by: EgorBo --- src/coreclr/vm/frozenobjectheap.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/frozenobjectheap.cpp b/src/coreclr/vm/frozenobjectheap.cpp index 41af231816a645..8f11f3c8c74d64 100644 --- a/src/coreclr/vm/frozenobjectheap.cpp +++ b/src/coreclr/vm/frozenobjectheap.cpp @@ -180,10 +180,12 @@ void FrozenObjectSegment::RegisterOrUpdate(uint8_t* current, size_t sizeCommited segment_info si; si.pvMem = m_pStart; si.ibFirstObject = sizeof(ObjHeader); - si.ibAllocated = (size_t)current; + si.ibAllocated = (size_t)current - (size_t)si.pvMem; si.ibCommit = sizeCommited; si.ibReserved = m_Size; + assert((size_t)current >= (size_t)si.pvMem); + // NOTE: RegisterFrozenSegment may take a GC lock inside. m_SegmentHandle = GCHeapUtilities::GetGCHeap()->RegisterFrozenSegment(&si); if (m_SegmentHandle == nullptr) From b77984825befe46b8ce240ed7fde5bc13e8d574b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 10:49:06 -0700 Subject: [PATCH 177/783] Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230913.3 (#92059) optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23462.6 -> To Version 1.0.0-prerelease.23463.3 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f49cc41ea7ab7e..a58805b364fe5f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -334,21 +334,21 @@ https://github.com/dotnet/arcade 4665b3d04e1da3796b965c3c3e3b97f55c449a6e - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - fdf994eebae397c96184fa78dcf488c220ae0082 + 61240e7f115581d0c6f04db60242e8eae1de1496 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - fdf994eebae397c96184fa78dcf488c220ae0082 + 61240e7f115581d0c6f04db60242e8eae1de1496 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - fdf994eebae397c96184fa78dcf488c220ae0082 + 61240e7f115581d0c6f04db60242e8eae1de1496 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - fdf994eebae397c96184fa78dcf488c220ae0082 + 61240e7f115581d0c6f04db60242e8eae1de1496 https://github.com/dotnet/hotreload-utils @@ -384,13 +384,13 @@ d10b02ae5cc670609d920a672985ed4456bdd6b6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - fdf994eebae397c96184fa78dcf488c220ae0082 + 61240e7f115581d0c6f04db60242e8eae1de1496 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - fdf994eebae397c96184fa78dcf488c220ae0082 + 61240e7f115581d0c6f04db60242e8eae1de1496 diff --git a/eng/Versions.props b/eng/Versions.props index b055d7591ccd01..e7972b2a592d27 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -156,12 +156,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23462.6 - 1.0.0-prerelease.23462.6 - 1.0.0-prerelease.23462.6 - 1.0.0-prerelease.23462.6 - 1.0.0-prerelease.23462.6 - 1.0.0-prerelease.23462.6 + 1.0.0-prerelease.23463.3 + 1.0.0-prerelease.23463.3 + 1.0.0-prerelease.23463.3 + 1.0.0-prerelease.23463.3 + 1.0.0-prerelease.23463.3 + 1.0.0-prerelease.23463.3 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From 0189dc443da58b45e4df96f90e17c23ace9e1b79 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 10:49:25 -0700 Subject: [PATCH 178/783] [wasi] Work arounbd WASI's mmap implementation not returning aligned memory. (#92061) Some code in sgen like sgen_los_free_object () expects the return address to be aligned. Hopefully fixes https://github.com/dotnet/runtime/issues/88501 and others. Co-authored-by: Zoltan Varga --- src/mono/mono/utils/mono-mmap-wasm.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/utils/mono-mmap-wasm.c b/src/mono/mono/utils/mono-mmap-wasm.c index 5c38aac9f36641..b2f417b0860385 100644 --- a/src/mono/mono/utils/mono-mmap-wasm.c +++ b/src/mono/mono/utils/mono-mmap-wasm.c @@ -90,8 +90,8 @@ mono_setmmapjit (int flag) /* Ignored on HOST_WASM */ } -void* -mono_valloc (void *addr, size_t size, int flags, MonoMemAccountType type) +static void* +valloc_impl (void *addr, size_t size, int flags, MonoMemAccountType type) { void *ptr; int mflags = 0; @@ -119,6 +119,19 @@ mono_valloc (void *addr, size_t size, int flags, MonoMemAccountType type) return ptr; } +void* +mono_valloc (void *addr, size_t size, int flags, MonoMemAccountType type) +{ +#if HOST_WASI + // WASI implements mmap using malloc, so the returned address is not page aligned + // and our code depends on it + g_assert (!addr); + return mono_valloc_aligned (size, mono_pagesize (), flags, type); +#else + return valloc_impl (addr, size, flags, type); +#endif +} + static GHashTable *valloc_hash; typedef struct { @@ -130,7 +143,7 @@ void* mono_valloc_aligned (size_t size, size_t alignment, int flags, MonoMemAccountType type) { /* Allocate twice the memory to be able to put the block on an aligned address */ - char *mem = (char *) mono_valloc (NULL, size + alignment, flags, type); + char *mem = (char *) valloc_impl (NULL, size + alignment, flags, type); char *aligned; if (!mem) From 851a9362c53b565e87bb3ddb49a07d7709be4d66 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Thu, 14 Sep 2023 23:13:43 +0400 Subject: [PATCH 179/783] Do not throw PNSE exception from NegotiateAuthentication constructor, report Unsupported status instead (#91753) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- .../FunctionalTests/NtAuthTests.FakeServer.cs | 27 +++++++++++++++++++ .../Net/NegotiateAuthenticationPal.Managed.cs | 21 ++++++++++----- .../Net/NegotiateAuthenticationPal.Unix.cs | 18 ++++++------- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/NtAuthTests.FakeServer.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/NtAuthTests.FakeServer.cs index 780db637ba335e..c29beca16f4015 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/NtAuthTests.FakeServer.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/NtAuthTests.FakeServer.cs @@ -139,5 +139,32 @@ await server.AcceptConnectionAsync(async connection => }).ConfigureAwait(false); }); } + + [Fact] + [SkipOnPlatform(TestPlatforms.Browser | TestPlatforms.Windows, "DefaultCredentials are unsupported for NTLM on Unix / Managed implementation")] + public async Task DefaultHandler_FakeServer_DefaultCredentials() + { + await LoopbackServer.CreateClientAndServerAsync( + async uri => + { + HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, uri); + requestMessage.Version = new Version(1, 1); + HttpMessageHandler handler = new HttpClientHandler() { Credentials = CredentialCache.DefaultCredentials }; + using (var client = new HttpClient(handler)) + { + HttpResponseMessage response = await client.SendAsync(requestMessage); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + } + }, + async server => + { + await server.AcceptConnectionAsync(async connection => + { + var authHeader = "WWW-Authenticate: NTLM\r\n"; + await connection.SendResponseAsync(HttpStatusCode.Unauthorized, authHeader).ConfigureAwait(false); + connection.CompleteRequestProcessing(); + }).ConfigureAwait(false); + }); + } } } diff --git a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Managed.cs b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Managed.cs index 4e5e8906b795cc..fff331646b73c6 100644 --- a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Managed.cs +++ b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Managed.cs @@ -9,16 +9,23 @@ internal abstract partial class NegotiateAuthenticationPal { public static NegotiateAuthenticationPal Create(NegotiateAuthenticationClientOptions clientOptions) { - switch (clientOptions.Package) + try { - case NegotiationInfoClass.NTLM: - return new ManagedNtlmNegotiateAuthenticationPal(clientOptions); + switch (clientOptions.Package) + { + case NegotiationInfoClass.NTLM: + return new ManagedNtlmNegotiateAuthenticationPal(clientOptions); - case NegotiationInfoClass.Negotiate: - return new ManagedSpnegoNegotiateAuthenticationPal(clientOptions); + case NegotiationInfoClass.Negotiate: + return new ManagedSpnegoNegotiateAuthenticationPal(clientOptions); - default: - return new UnsupportedNegotiateAuthenticationPal(clientOptions); + default: + return new UnsupportedNegotiateAuthenticationPal(clientOptions); + } + } + catch (PlatformNotSupportedException) + { + return new UnsupportedNegotiateAuthenticationPal(clientOptions); } } diff --git a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Unix.cs b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Unix.cs index 900d66c05bfc7a..ed1fe4e2e91937 100644 --- a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Unix.cs +++ b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Unix.cs @@ -23,20 +23,20 @@ internal partial class NegotiateAuthenticationPal public static NegotiateAuthenticationPal Create(NegotiateAuthenticationClientOptions clientOptions) { - if (UseManagedNtlm) + try { - switch (clientOptions.Package) + if (UseManagedNtlm) { - case NegotiationInfoClass.NTLM: - return new ManagedNtlmNegotiateAuthenticationPal(clientOptions); + switch (clientOptions.Package) + { + case NegotiationInfoClass.NTLM: + return new ManagedNtlmNegotiateAuthenticationPal(clientOptions); - case NegotiationInfoClass.Negotiate: - return new ManagedSpnegoNegotiateAuthenticationPal(clientOptions, supportKerberos: true); + case NegotiationInfoClass.Negotiate: + return new ManagedSpnegoNegotiateAuthenticationPal(clientOptions, supportKerberos: true); + } } - } - try - { return new UnixNegotiateAuthenticationPal(clientOptions); } catch (Win32Exception) From dbcde1d274e0cda97b3470368becb05e42195f4e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 12:21:43 -0700 Subject: [PATCH 180/783] [release/8.0] Update dependencies from dotnet/roslyn (#91913) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/dotnet/roslyn build 20230911.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23459.2 -> To Version 4.8.0-3.23461.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230911.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23459.2 -> To Version 4.8.0-3.23461.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230912.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23459.2 -> To Version 4.8.0-3.23462.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230912.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23459.2 -> To Version 4.8.0-3.23462.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230912.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23459.2 -> To Version 4.8.0-3.23462.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230912.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23459.2 -> To Version 4.8.0-3.23462.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230912.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23459.2 -> To Version 4.8.0-3.23462.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230912.7 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23459.2 -> To Version 4.8.0-3.23462.7 * Update dependencies from https://github.com/dotnet/roslyn build 20230912.8 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23459.2 -> To Version 4.8.0-3.23462.8 * Update dependencies from https://github.com/dotnet/roslyn build 20230912.9 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23459.2 -> To Version 4.8.0-3.23462.9 * Update dependencies from https://github.com/dotnet/roslyn build 20230912.10 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23459.2 -> To Version 4.8.0-3.23462.10 * Permit TypeAttributes.BeforeFieldInit for InterfaceTypeTestBase --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> Co-authored-by: Eric StJohn --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- .../tests/System/Type/TypePropertyTests.cs | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a58805b364fe5f..8521a5487a5fec 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - 3686f3061a9202260a0de4d06e91855b0fa21e8c + 1b7a6f807cb8ce709048debae6b771f4705a697a - + https://github.com/dotnet/roslyn - 3686f3061a9202260a0de4d06e91855b0fa21e8c + 1b7a6f807cb8ce709048debae6b771f4705a697a - + https://github.com/dotnet/roslyn - 3686f3061a9202260a0de4d06e91855b0fa21e8c + 1b7a6f807cb8ce709048debae6b771f4705a697a https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index e7972b2a592d27..f437ad1a604c22 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -42,9 +42,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23451.1 - 4.8.0-3.23451.1 - 4.8.0-3.23451.1 + 4.8.0-3.23462.10 + 4.8.0-3.23462.10 + 4.8.0-3.23462.10 8.0.100-preview.7.23329.3 - 8.0.0-beta.23451.1 - 8.0.0-beta.23451.1 - 8.0.0-beta.23451.1 - 8.0.0-beta.23451.1 - 8.0.0-beta.23451.1 - 2.5.1-beta.23451.1 - 8.0.0-beta.23451.1 - 8.0.0-beta.23451.1 - 8.0.0-beta.23451.1 - 8.0.0-beta.23451.1 - 8.0.0-beta.23451.1 - 8.0.0-beta.23451.1 - 8.0.0-beta.23451.1 - 8.0.0-beta.23451.1 - 8.0.0-beta.23451.1 + 8.0.0-beta.23463.1 + 8.0.0-beta.23463.1 + 8.0.0-beta.23463.1 + 8.0.0-beta.23463.1 + 8.0.0-beta.23463.1 + 2.5.1-beta.23463.1 + 8.0.0-beta.23463.1 + 8.0.0-beta.23463.1 + 8.0.0-beta.23463.1 + 8.0.0-beta.23463.1 + 8.0.0-beta.23463.1 + 8.0.0-beta.23463.1 + 8.0.0-beta.23463.1 + 8.0.0-beta.23463.1 + 8.0.0-beta.23463.1 6.0.0-preview.1.102 @@ -184,7 +184,7 @@ 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 - 8.0.0-alpha.0.23455.2 + 8.0.0-alpha.0.23461.1 2.4.2 1.0.0 2.4.5 @@ -213,7 +213,7 @@ 8.0.0-rc.1.23406.6 - 0.11.4-alpha.23454.2 + 0.11.4-alpha.23461.1 8.0.0-rc.1.23406.6 @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.0-rc.2.23460.1 + 8.0.0-rc.2.23463.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda diff --git a/global.json b/global.json index 6d208cff376c28..2b41b42c3256e6 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.100-preview.7.23376.3" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23451.1", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23451.1", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23451.1", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23463.1", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23463.1", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23463.1", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From dbd788512921d7d05d33d71c5a03375357c5efb8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 13:19:27 -0700 Subject: [PATCH 182/783] [release/8.0] Remove implicit narrowing conversions from zlib (#91962) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Make zlib compile clean against MSVC C4244 and clang implicit-int-conversion Descriptions of each changes are in the respective .patch files. * Unbreak mono build --------- Co-authored-by: Levi Broderick Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- src/mono/CMakeLists.txt | 3 + ...ib-intel-compile-clean-against-C4244.patch | 75 +++++++++++++++++++ ...ake-zlib-compile-clean-against-C4244.patch | 57 ++++++++++++++ src/native/external/zlib-intel-version.txt | 2 + src/native/external/zlib-intel.cmake | 6 -- src/native/external/zlib-intel/deflate.c | 8 +- src/native/external/zlib-intel/slide_sse.c | 2 +- src/native/external/zlib-intel/trees.c | 2 +- src/native/external/zlib-version.txt | 2 + src/native/external/zlib.cmake | 6 -- src/native/external/zlib/deflate.c | 8 +- src/native/external/zlib/trees.c | 2 +- 12 files changed, 150 insertions(+), 23 deletions(-) create mode 100644 src/native/external/patches/zlib-intel/0001-Make-zlib-intel-compile-clean-against-C4244.patch create mode 100644 src/native/external/patches/zlib/0001-Make-zlib-compile-clean-against-C4244.patch diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index a57cc52b0b110b..05766210ea6be5 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -15,6 +15,9 @@ if (MSVC) if(EXISTS ${CLR_SOURCELINK_FILE_PATH}) add_link_options("/sourcelink:${CLR_SOURCELINK_FILE_PATH}") endif() + + # FIXME: Remove the line below when https://github.com/dotnet/runtime/issues/91249 is fixed. + add_compile_options($<$:/wd4244>) # conversion from 'type1' to 'type2', possible loss of data endif(MSVC) set(CROSS_ROOTFS $ENV{ROOTFS_DIR}) diff --git a/src/native/external/patches/zlib-intel/0001-Make-zlib-intel-compile-clean-against-C4244.patch b/src/native/external/patches/zlib-intel/0001-Make-zlib-intel-compile-clean-against-C4244.patch new file mode 100644 index 00000000000000..1ecb02be92ec05 --- /dev/null +++ b/src/native/external/patches/zlib-intel/0001-Make-zlib-intel-compile-clean-against-C4244.patch @@ -0,0 +1,75 @@ +From edabaf799fd071a328e0adb743a98628df6649f0 Mon Sep 17 00:00:00 2001 +From: Levi Broderick +Date: Mon, 28 Aug 2023 15:26:38 -0700 +Subject: [PATCH] Make zlib-intel compile clean against C4244 clang equivalent + is "implicit-int-conversion" warning + +The change to deflate.c is legal because 'len' has an upper bound of +MAX_STORED, which means it fits cleanly into a 16-bit integer. So +writing out 2x 8-bit values will not result in data loss. + +The change to trees.c is legal because within this loop, 'count' is +intended to have an upper bound of 138, with the target assignment +only executing if 'count' is bounded by 4. Neither the 'count' local +in isolation nor the addition that's part of the target line is +expected to result in integer overflow. But even if it did, that's a +matter for a different warning code and doesn't impact the correctness +of the narrowing cast being considered here. + +The change to slide_sse.c is legal because 'w_size' is limited to +1 << 15 (see deflateInit2_ in deflate.c), so this fits cleanly into +a 16-bit value. +--- + src/native/external/zlib-intel/deflate.c | 8 ++++---- + src/native/external/zlib-intel/slide_sse.c | 2 +- + src/native/external/zlib-intel/trees.c | 2 +- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/native/external/zlib-intel/deflate.c b/src/native/external/zlib-intel/deflate.c +index bd5e95774a6..108b1a187af 100644 +--- a/src/native/external/zlib-intel/deflate.c ++++ b/src/native/external/zlib-intel/deflate.c +@@ -1553,10 +1553,10 @@ local block_state deflate_stored(s, flush) + _tr_stored_block(s, (char *)0, 0L, last); + + /* Replace the lengths in the dummy stored block with len. */ +- s->pending_buf[s->pending - 4] = len; +- s->pending_buf[s->pending - 3] = len >> 8; +- s->pending_buf[s->pending - 2] = ~len; +- s->pending_buf[s->pending - 1] = ~len >> 8; ++ s->pending_buf[s->pending - 4] = (Bytef)len; ++ s->pending_buf[s->pending - 3] = (Bytef)(len >> 8); ++ s->pending_buf[s->pending - 2] = (Bytef)~len; ++ s->pending_buf[s->pending - 1] = (Bytef)(~len >> 8); + + /* Write the stored block header bytes. */ + flush_pending(s->strm); +diff --git a/src/native/external/zlib-intel/slide_sse.c b/src/native/external/zlib-intel/slide_sse.c +index 342fd562dd1..eb74202c5a0 100644 +--- a/src/native/external/zlib-intel/slide_sse.c ++++ b/src/native/external/zlib-intel/slide_sse.c +@@ -18,7 +18,7 @@ void slide_hash_sse(deflate_state *s) + unsigned n; + Posf *p; + uInt wsize = s->w_size; +- z_const __m128i xmm_wsize = _mm_set1_epi16(s->w_size); ++ z_const __m128i xmm_wsize = _mm_set1_epi16((short)s->w_size); + + n = s->hash_size; + p = &s->head[n] - 8; +diff --git a/src/native/external/zlib-intel/trees.c b/src/native/external/zlib-intel/trees.c +index 35462a1313a..f78b7d8c63e 100644 +--- a/src/native/external/zlib-intel/trees.c ++++ b/src/native/external/zlib-intel/trees.c +@@ -717,7 +717,7 @@ local void scan_tree(s, tree, max_code) + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { +- s->bl_tree[curlen].Freq += count; ++ s->bl_tree[curlen].Freq += (ush)count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; +-- +2.42.0.windows.1 + diff --git a/src/native/external/patches/zlib/0001-Make-zlib-compile-clean-against-C4244.patch b/src/native/external/patches/zlib/0001-Make-zlib-compile-clean-against-C4244.patch new file mode 100644 index 00000000000000..c2a26b3202b196 --- /dev/null +++ b/src/native/external/patches/zlib/0001-Make-zlib-compile-clean-against-C4244.patch @@ -0,0 +1,57 @@ +From 86d96652ddd60f61dc7b0c94b601f6d156d34632 Mon Sep 17 00:00:00 2001 +From: Levi Broderick +Date: Mon, 28 Aug 2023 15:26:38 -0700 +Subject: [PATCH] Make zlib compile clean against C4244 clang equivalent is + "implicit-int-conversion" warning + +The change to deflate.c is legal because 'len' has an upper bound of +MAX_STORED, which means it fits cleanly into a 16-bit integer. So +writing out 2x 8-bit values will not result in data loss. + +The change to trees.c is legal because within this loop, 'count' is +intended to have an upper bound of 138, with the target assignment +only executing if 'count' is bounded by 4. Neither the 'count' local +in isolation nor the addition that's part of the target line is +expected to result in integer overflow. But even if it did, that's a +matter for a different warning code and doesn't impact the correctness +of the narrowing cast being considered here. +--- + src/native/external/zlib/deflate.c | 8 ++++---- + src/native/external/zlib/trees.c | 2 +- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/native/external/zlib/deflate.c b/src/native/external/zlib/deflate.c +index d2e1106ef5d..b7636639754 100644 +--- a/src/native/external/zlib/deflate.c ++++ b/src/native/external/zlib/deflate.c +@@ -1738,10 +1738,10 @@ local block_state deflate_stored(s, flush) + _tr_stored_block(s, (char *)0, 0L, last); + + /* Replace the lengths in the dummy stored block with len. */ +- s->pending_buf[s->pending - 4] = len; +- s->pending_buf[s->pending - 3] = len >> 8; +- s->pending_buf[s->pending - 2] = ~len; +- s->pending_buf[s->pending - 1] = ~len >> 8; ++ s->pending_buf[s->pending - 4] = (Bytef)len; ++ s->pending_buf[s->pending - 3] = (Bytef)(len >> 8); ++ s->pending_buf[s->pending - 2] = (Bytef)~len; ++ s->pending_buf[s->pending - 1] = (Bytef)(~len >> 8); + + /* Write the stored block header bytes. */ + flush_pending(s->strm); +diff --git a/src/native/external/zlib/trees.c b/src/native/external/zlib/trees.c +index 5f305c47221..8a3eec559e5 100644 +--- a/src/native/external/zlib/trees.c ++++ b/src/native/external/zlib/trees.c +@@ -721,7 +721,7 @@ local void scan_tree(s, tree, max_code) + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { +- s->bl_tree[curlen].Freq += count; ++ s->bl_tree[curlen].Freq += (ush)count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; +-- +2.42.0.windows.1 + diff --git a/src/native/external/zlib-intel-version.txt b/src/native/external/zlib-intel-version.txt index d406ffbcc459b3..287c9e92512bf1 100644 --- a/src/native/external/zlib-intel-version.txt +++ b/src/native/external/zlib-intel-version.txt @@ -12,3 +12,5 @@ copied into our repo in order to build. Since then, we've just updated only those files in-place, ignoring other files in the intel/zlib repo. If new files are introduced which are necessary for building the product, feel free to bring those down as well. + +We have also applied the custom patches under the patches/zlib-intel folder. diff --git a/src/native/external/zlib-intel.cmake b/src/native/external/zlib-intel.cmake index 1b6fa0cb4765bf..e8f198271d865b 100644 --- a/src/native/external/zlib-intel.cmake +++ b/src/native/external/zlib-intel.cmake @@ -1,9 +1,3 @@ -if(MSVC) - add_compile_options($<$:/wd4244>) # conversion from 'type1' to 'type2', possible loss of data -else(CMAKE_C_COMPILER_ID MATCHES "Clang") - add_compile_options($<$:-Wno-implicit-int-conversion>) -endif() - set(ZLIB_SOURCES_BASE adler32.c compress.c diff --git a/src/native/external/zlib-intel/deflate.c b/src/native/external/zlib-intel/deflate.c index bd5e95774a689a..108b1a187af4d3 100644 --- a/src/native/external/zlib-intel/deflate.c +++ b/src/native/external/zlib-intel/deflate.c @@ -1553,10 +1553,10 @@ local block_state deflate_stored(s, flush) _tr_stored_block(s, (char *)0, 0L, last); /* Replace the lengths in the dummy stored block with len. */ - s->pending_buf[s->pending - 4] = len; - s->pending_buf[s->pending - 3] = len >> 8; - s->pending_buf[s->pending - 2] = ~len; - s->pending_buf[s->pending - 1] = ~len >> 8; + s->pending_buf[s->pending - 4] = (Bytef)len; + s->pending_buf[s->pending - 3] = (Bytef)(len >> 8); + s->pending_buf[s->pending - 2] = (Bytef)~len; + s->pending_buf[s->pending - 1] = (Bytef)(~len >> 8); /* Write the stored block header bytes. */ flush_pending(s->strm); diff --git a/src/native/external/zlib-intel/slide_sse.c b/src/native/external/zlib-intel/slide_sse.c index 342fd562dd1152..eb74202c5a04a8 100644 --- a/src/native/external/zlib-intel/slide_sse.c +++ b/src/native/external/zlib-intel/slide_sse.c @@ -18,7 +18,7 @@ void slide_hash_sse(deflate_state *s) unsigned n; Posf *p; uInt wsize = s->w_size; - z_const __m128i xmm_wsize = _mm_set1_epi16(s->w_size); + z_const __m128i xmm_wsize = _mm_set1_epi16((short)s->w_size); n = s->hash_size; p = &s->head[n] - 8; diff --git a/src/native/external/zlib-intel/trees.c b/src/native/external/zlib-intel/trees.c index 35462a1313aa83..f78b7d8c63eaed 100644 --- a/src/native/external/zlib-intel/trees.c +++ b/src/native/external/zlib-intel/trees.c @@ -717,7 +717,7 @@ local void scan_tree(s, tree, max_code) if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; + s->bl_tree[curlen].Freq += (ush)count; } else if (curlen != 0) { if (curlen != prevlen) s->bl_tree[curlen].Freq++; s->bl_tree[REP_3_6].Freq++; diff --git a/src/native/external/zlib-version.txt b/src/native/external/zlib-version.txt index 00ce7fdbb2cd32..fcac66cc4645f4 100644 --- a/src/native/external/zlib-version.txt +++ b/src/native/external/zlib-version.txt @@ -13,3 +13,5 @@ We have also cherry-picked into our local copy: This patch only affects memLevel 9 compression. .NET doesn't currently use this memLevel, but we'll take this patch out of an abundance of caution just in case we enable this functionality in a future release. + +We have also applied the custom patches under the patches/zlib folder. diff --git a/src/native/external/zlib.cmake b/src/native/external/zlib.cmake index 862e10118cd72c..730bfc4bd14020 100644 --- a/src/native/external/zlib.cmake +++ b/src/native/external/zlib.cmake @@ -1,9 +1,3 @@ -if(MSVC) - add_compile_options($<$:/wd4244>) # conversion from 'type1' to 'type2', possible loss of data -else(CMAKE_C_COMPILER_ID MATCHES "Clang") - add_compile_options($<$:-Wno-implicit-int-conversion>) -endif() - set(ZLIB_SOURCES_BASE adler32.c compress.c diff --git a/src/native/external/zlib/deflate.c b/src/native/external/zlib/deflate.c index d2e1106ef5d07d..b763663975458c 100644 --- a/src/native/external/zlib/deflate.c +++ b/src/native/external/zlib/deflate.c @@ -1738,10 +1738,10 @@ local block_state deflate_stored(s, flush) _tr_stored_block(s, (char *)0, 0L, last); /* Replace the lengths in the dummy stored block with len. */ - s->pending_buf[s->pending - 4] = len; - s->pending_buf[s->pending - 3] = len >> 8; - s->pending_buf[s->pending - 2] = ~len; - s->pending_buf[s->pending - 1] = ~len >> 8; + s->pending_buf[s->pending - 4] = (Bytef)len; + s->pending_buf[s->pending - 3] = (Bytef)(len >> 8); + s->pending_buf[s->pending - 2] = (Bytef)~len; + s->pending_buf[s->pending - 1] = (Bytef)(~len >> 8); /* Write the stored block header bytes. */ flush_pending(s->strm); diff --git a/src/native/external/zlib/trees.c b/src/native/external/zlib/trees.c index 5f305c47221e90..8a3eec559e55bc 100644 --- a/src/native/external/zlib/trees.c +++ b/src/native/external/zlib/trees.c @@ -721,7 +721,7 @@ local void scan_tree(s, tree, max_code) if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; + s->bl_tree[curlen].Freq += (ush)count; } else if (curlen != 0) { if (curlen != prevlen) s->bl_tree[curlen].Freq++; s->bl_tree[REP_3_6].Freq++; From 5de5c460b8cc2ab05c1d93c6514d57a30ffda889 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 13:20:31 -0700 Subject: [PATCH 183/783] [release/8.0] Replace http.error.reason with OTel standard error.type (#91996) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * implement standard semantics for the request.duration error tag * delete unused using * reduce s_statusCodeStrings size --------- Co-authored-by: antonfirsov Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> Co-authored-by: Anton Firszov --- .../System/Net/Http/Metrics/MetricsHandler.cs | 77 ++++++++++++------- .../tests/FunctionalTests/MetricsTest.cs | 47 ++++++++--- 2 files changed, 85 insertions(+), 39 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs index 3c34e43011938e..1f353f167150e5 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs @@ -112,11 +112,12 @@ private void RequestStop(HttpRequestMessage request, HttpResponseMessage? respon tags.Add("http.response.status_code", GetBoxedStatusCode((int)response.StatusCode)); tags.Add("network.protocol.version", GetProtocolVersionString(response.Version)); } - else + + if (TryGetErrorType(response, exception, out string? errorType)) { - Debug.Assert(exception is not null); - tags.Add("http.error.reason", GetErrorReason(exception)); + tags.Add("error.type", errorType); } + TimeSpan durationTime = Stopwatch.GetElapsedTime(startTimestamp, Stopwatch.GetTimestamp()); HttpMetricsEnrichmentContext? enrichmentContext = HttpMetricsEnrichmentContext.GetEnrichmentContextForRequest(request); @@ -130,37 +131,47 @@ private void RequestStop(HttpRequestMessage request, HttpResponseMessage? respon } } - private static string GetErrorReason(Exception exception) + private static bool TryGetErrorType(HttpResponseMessage? response, Exception? exception, out string? errorType) { - if (exception is HttpRequestException e) + if (response is not null) { - Debug.Assert(Enum.GetValues().Length == 12, "We need to extend the mapping in case new values are added to HttpRequestError."); + int statusCode = (int)response.StatusCode; - string? errorReason = e.HttpRequestError switch + // In case the status code indicates a client or a server error, return the string representation of the status code. + // See the paragraph Status and the definition of 'error.type' in + // https://github.com/open-telemetry/semantic-conventions/blob/2bad9afad58fbd6b33cc683d1ad1f006e35e4a5d/docs/http/http-spans.md + if (statusCode >= 400 && statusCode <= 599) { - HttpRequestError.NameResolutionError => "name_resolution_error", - HttpRequestError.ConnectionError => "connection_error", - HttpRequestError.SecureConnectionError => "secure_connection_error", - HttpRequestError.HttpProtocolError => "http_protocol_error", - HttpRequestError.ExtendedConnectNotSupported => "extended_connect_not_supported", - HttpRequestError.VersionNegotiationError => "version_negotiation_error", - HttpRequestError.UserAuthenticationError => "user_authentication_error", - HttpRequestError.ProxyTunnelError => "proxy_tunnel_error", - HttpRequestError.InvalidResponse => "invalid_response", - HttpRequestError.ResponseEnded => "response_ended", - HttpRequestError.ConfigurationLimitExceeded => "configuration_limit_exceeded", - - // Fall back to the exception type name (including for HttpRequestError.Unknown). - _ => null - }; - - if (errorReason is not null) - { - return errorReason; + errorType = GetErrorStatusCodeString(statusCode); + return true; } } - return exception.GetType().Name; + if (exception is null) + { + errorType = null; + return false; + } + + Debug.Assert(Enum.GetValues().Length == 12, "We need to extend the mapping in case new values are added to HttpRequestError."); + errorType = (exception as HttpRequestException)?.HttpRequestError switch + { + HttpRequestError.NameResolutionError => "name_resolution_error", + HttpRequestError.ConnectionError => "connection_error", + HttpRequestError.SecureConnectionError => "secure_connection_error", + HttpRequestError.HttpProtocolError => "http_protocol_error", + HttpRequestError.ExtendedConnectNotSupported => "extended_connect_not_supported", + HttpRequestError.VersionNegotiationError => "version_negotiation_error", + HttpRequestError.UserAuthenticationError => "user_authentication_error", + HttpRequestError.ProxyTunnelError => "proxy_tunnel_error", + HttpRequestError.InvalidResponse => "invalid_response", + HttpRequestError.ResponseEnded => "response_ended", + HttpRequestError.ConfigurationLimitExceeded => "configuration_limit_exceeded", + + // Fall back to the exception type name in case of HttpRequestError.Unknown or when exception is not an HttpRequestException. + _ => exception.GetType().Name + }; + return true; } private static string GetProtocolVersionString(Version httpVersion) => (httpVersion.Major, httpVersion.Minor) switch @@ -199,6 +210,7 @@ private static TagList InitializeCommonTags(HttpRequestMessage request) } private static object[]? s_boxedStatusCodes; + private static string[]? s_statusCodeStrings; private static object GetBoxedStatusCode(int statusCode) { @@ -209,6 +221,17 @@ private static object GetBoxedStatusCode(int statusCode) : statusCode; } + private static string GetErrorStatusCodeString(int statusCode) + { + Debug.Assert(statusCode >= 400 && statusCode <= 599); + + string[] strings = LazyInitializer.EnsureInitialized(ref s_statusCodeStrings, static () => new string[200]); + int index = statusCode - 400; + return (uint)index < (uint)strings.Length + ? strings[index] ??= statusCode.ToString() + : statusCode.ToString(); + } + private sealed class SharedMeter : Meter { public static Meter Instance { get; } = new SharedMeter(); diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs index da36366246f415..15bb4bcbe2bb97 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs @@ -75,8 +75,8 @@ protected static void VerifyRequestDuration(Measurement measurement, Version? protocolVersion = null, int? statusCode = null, string method = "GET", - string[] acceptedErrorReasons = null) => - VerifyRequestDuration(InstrumentNames.RequestDuration, measurement.Value, measurement.Tags.ToArray(), uri, protocolVersion, statusCode, method, acceptedErrorReasons); + string[] acceptedErrorTypes = null) => + VerifyRequestDuration(InstrumentNames.RequestDuration, measurement.Value, measurement.Tags.ToArray(), uri, protocolVersion, statusCode, method, acceptedErrorTypes); protected static void VerifyRequestDuration(string instrumentName, double measurement, @@ -85,7 +85,7 @@ protected static void VerifyRequestDuration(string instrumentName, Version? protocolVersion, int? statusCode, string method = "GET", - string[] acceptedErrorReasons = null) + string[] acceptedErrorTypes = null) { Assert.Equal(InstrumentNames.RequestDuration, instrumentName); Assert.InRange(measurement, double.Epsilon, 60); @@ -93,14 +93,14 @@ protected static void VerifyRequestDuration(string instrumentName, VerifyTag(tags, "http.request.method", method); VerifyTag(tags, "network.protocol.version", GetVersionString(protocolVersion)); VerifyTag(tags, "http.response.status_code", statusCode); - if (acceptedErrorReasons == null) + if (acceptedErrorTypes == null) { - Assert.DoesNotContain(tags, t => t.Key == "http.error.reason"); + Assert.DoesNotContain(tags, t => t.Key == "error.type"); } else { - string errorReason = (string)tags.Single(t => t.Key == "http.error.reason").Value; - Assert.Contains(errorReason, acceptedErrorReasons); + string errorReason = (string)tags.Single(t => t.Key == "error.type").Value; + Assert.Contains(errorReason, acceptedErrorTypes); } } @@ -659,7 +659,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => : [nameof(TaskCanceledException), nameof(OperationCanceledException)]; Measurement m = Assert.Single(recorder.GetMeasurements()); - VerifyRequestDuration(m, uri, acceptedErrorReasons: expectedExceptionTypes); + VerifyRequestDuration(m, uri, acceptedErrorTypes: expectedExceptionTypes); clientCompleted.SetResult(); }, @@ -703,7 +703,7 @@ public async Task RequestDuration_ConnectionError_LogsExpectedErrorReason() _output.WriteLine($"Client exception: {ex}"); Measurement m = Assert.Single(recorder.GetMeasurements()); - VerifyRequestDuration(m, uri, acceptedErrorReasons: ["connection_error"]); + VerifyRequestDuration(m, uri, acceptedErrorTypes: ["connection_error"]); } protected override void Dispose(bool disposing) @@ -793,6 +793,29 @@ await Assert.ThrowsAsync(async () => }, content: "x")); } + [Theory] + [InlineData(400)] + [InlineData(404)] + [InlineData(599)] + public Task RequestDuration_ErrorStatus_ErrorTypeRecorded(int statusCode) + { + return LoopbackServerFactory.CreateClientAndServerAsync(async uri => + { + using HttpMessageInvoker client = CreateHttpMessageInvoker(); + using InstrumentRecorder recorder = SetupInstrumentRecorder(InstrumentNames.RequestDuration); + using HttpRequestMessage request = new(HttpMethod.Get, uri) { Version = UseVersion }; + + using HttpResponseMessage response = await SendAsync(client, request); + + Measurement m = Assert.Single(recorder.GetMeasurements()); + VerifyRequestDuration(m, uri, UseVersion, statusCode, "GET", acceptedErrorTypes: new[] { $"{statusCode}" }); + + }, async server => + { + await server.AcceptConnectionSendResponseAndCloseAsync(statusCode: (HttpStatusCode)statusCode); + }); + } + [Fact] [SkipOnPlatform(TestPlatforms.Browser, "Browser is relaxed about validating HTTP headers")] public async Task RequestDuration_ConnectionClosedWhileReceivingHeaders_Recorded() @@ -814,7 +837,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.True(ex is HttpRequestException or TaskCanceledException); Measurement m = Assert.Single(recorder.GetMeasurements()); - VerifyRequestDuration(m, uri, acceptedErrorReasons: [nameof(TaskCanceledException), "response_ended"]); + VerifyRequestDuration(m, uri, acceptedErrorTypes: [nameof(TaskCanceledException), "response_ended"]); }, async server => { try @@ -869,7 +892,7 @@ await server.AcceptConnectionAsync(async connection => { await Assert.ThrowsAsync(() => clientTask); Measurement m = Assert.Single(recorder.GetMeasurements()); - VerifyRequestDuration(m, server.Address, acceptedErrorReasons: ["response_ended"]); + VerifyRequestDuration(m, server.Address, acceptedErrorTypes: ["response_ended"]); } else { @@ -967,7 +990,7 @@ await Assert.ThrowsAsync(async () => }); Measurement m = Assert.Single(recorder.GetMeasurements()); - VerifyRequestDuration(m, server.Address, acceptedErrorReasons: ["http_protocol_error"]); + VerifyRequestDuration(m, server.Address, acceptedErrorTypes: ["http_protocol_error"]); } } From 1d60c690e4ae64a4467357d4676fd5b9b3675ac8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 14:58:50 -0700 Subject: [PATCH 184/783] [release/8.0] Fix binder gen compile issues due to inaccessible members and identifier name clashes (#91967) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix binder gen compile issues due to inaccessible members and identifier name clashes * Minimize net diff of binder-gen visibility/identifier-clash fix * Improve identifier formatting * Use built-in API for accessiblity check --------- Co-authored-by: Layomi Akinrinade Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- .../src/SourceGenerators/TypeModelHelper.cs | 36 ++++ .../ConfigurationBindingGenerator.Parser.cs | 19 +- .../Helpers/Emitter/ConfigurationBinder.cs | 3 +- .../gen/Helpers/Emitter/CoreBindingHelpers.cs | 2 +- .../gen/Helpers/Emitter/Helpers.cs | 13 +- .../gen/Helpers/Parser/Extensions.cs | 62 +++++++ ...nfiguration.Binder.SourceGeneration.csproj | 2 + .../gen/Model/KnownTypeSymbols.cs | 4 + .../gen/Model/TypeSpec.cs | 10 +- .../gen/Resources/Strings.resx | 2 +- .../gen/Resources/xlf/Strings.cs.xlf | 4 +- .../gen/Resources/xlf/Strings.de.xlf | 4 +- .../gen/Resources/xlf/Strings.es.xlf | 4 +- .../gen/Resources/xlf/Strings.fr.xlf | 4 +- .../gen/Resources/xlf/Strings.it.xlf | 4 +- .../gen/Resources/xlf/Strings.ja.xlf | 4 +- .../gen/Resources/xlf/Strings.ko.xlf | 4 +- .../gen/Resources/xlf/Strings.pl.xlf | 4 +- .../gen/Resources/xlf/Strings.pt-BR.xlf | 4 +- .../gen/Resources/xlf/Strings.ru.xlf | 4 +- .../gen/Resources/xlf/Strings.tr.xlf | 4 +- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 4 +- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 4 +- .../tests/Common/ConfigurationBinderTests.cs | 2 +- .../Baselines/EmptyConfigType.generated.txt | 104 +++++++++++ .../ConfigurationBinderTests.Generator.cs | 166 ++++++++++++++++++ .../gen/Helpers/RoslynExtensions.cs | 22 --- .../gen/JsonSourceGenerator.Parser.cs | 8 +- .../System.Text.Json.SourceGeneration.targets | 1 + 29 files changed, 421 insertions(+), 87 deletions(-) create mode 100644 src/libraries/Common/src/SourceGenerators/TypeModelHelper.cs create mode 100644 src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/Extensions.cs create mode 100644 src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/EmptyConfigType.generated.txt diff --git a/src/libraries/Common/src/SourceGenerators/TypeModelHelper.cs b/src/libraries/Common/src/SourceGenerators/TypeModelHelper.cs new file mode 100644 index 00000000000000..73c19d61ca1225 --- /dev/null +++ b/src/libraries/Common/src/SourceGenerators/TypeModelHelper.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.CodeAnalysis; +using System.Collections.Generic; + +namespace SourceGenerators +{ + internal static class TypeModelHelper + { + public static List? GetAllTypeArgumentsInScope(this INamedTypeSymbol type) + { + if (!type.IsGenericType) + { + return null; + } + + List? args = null; + TraverseContainingTypes(type); + return args; + + void TraverseContainingTypes(INamedTypeSymbol current) + { + if (current.ContainingType is INamedTypeSymbol parent) + { + TraverseContainingTypes(parent); + } + + if (!current.TypeArguments.IsEmpty) + { + (args ??= new()).AddRange(current.TypeArguments); + } + } + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs index 64db4eb58b1f77..deb0f4c0aabc0d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs @@ -9,6 +9,7 @@ using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Operations; +using SourceGenerators; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { @@ -66,10 +67,11 @@ public Parser(SourceProductionContext context, KnownTypeSymbols typeSymbols, Imm return _sourceGenSpec; } - private static bool IsValidRootConfigType(ITypeSymbol? type) + private bool IsValidRootConfigType(ITypeSymbol? type) { if (type is null || type.SpecialType is SpecialType.System_Object or SpecialType.System_Void || + !_typeSymbols.Compilation.IsSymbolAccessibleWithin(type, _typeSymbols.Compilation.Assembly) || type.TypeKind is TypeKind.TypeParameter or TypeKind.Pointer or TypeKind.Error || type.IsRefLikeType || ContainsGenericParameters(type)) @@ -914,19 +916,4 @@ private void RegisterTypeDiagnostic(ITypeSymbol causingType, InvocationDiagnosti } } } - - public static class ParserExtensions - { - public static void RegisterCacheEntry(this Dictionary cache, TKey key, TEntry entry) - where TKey : notnull - where TValue : ICollection, new() - { - if (!cache.TryGetValue(key, out TValue? entryCollection)) - { - cache[key] = entryCollection = new TValue(); - } - - entryCollection.Add(entry); - } - } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs index c7ead12d65589d..c420097d99d6ae 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using SourceGenerators; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { @@ -138,7 +139,7 @@ void EmitMethods(MethodsToGen_ConfigurationBinder method, string additionalParam EmitBlankLineIfRequired(); _writer.WriteLine($"/// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively."); EmitInterceptsLocationAnnotations(interceptorInfoList); - EmitStartBlock($"public static void {Identifier.Bind}_{type.DisplayString.ToIdentifierSubstring()}(this {Identifier.IConfiguration} {Identifier.configuration}, {additionalParams})"); + EmitStartBlock($"public static void {Identifier.Bind}_{type.IdentifierCompatibleSubstring}(this {Identifier.IConfiguration} {Identifier.configuration}, {additionalParams})"); if (type.NeedsMemberBinding) { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs index bb2bd7ac61d15a..089095aa472d5b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs @@ -923,7 +923,7 @@ private static string GetConditionKindExpr(ref bool isFirstType) } private static string GetConfigKeyCacheFieldName(ObjectSpec type) => - $"s_configKeys_{type.DisplayString.ToIdentifierSubstring()}"; + $"s_configKeys_{type.IdentifierCompatibleSubstring}"; } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs index 60ce9f681e077f..fe59e46f73fc0b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs @@ -245,18 +245,7 @@ private bool EmitInitException(TypeSpec type) private string GetIncrementalIdentifier(string prefix) => $"{prefix}{_valueSuffixIndex++}"; private static string GetInitalizeMethodDisplayString(ObjectSpec type) => - $"{nameof(MethodsToGen_CoreBindingHelper.Initialize)}{type.DisplayString.ToIdentifierSubstring()}"; + $"{nameof(MethodsToGen_CoreBindingHelper.Initialize)}{type.IdentifierCompatibleSubstring}"; } } - - internal static class EmitterExtensions - { - public static string ToIdentifierSubstring(this string typeDisplayName) => - typeDisplayName - .Replace("[]", nameof(Array)) - .Replace(", ", string.Empty) - .Replace(".", string.Empty) - .Replace("<", string.Empty) - .Replace(">", string.Empty); - } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/Extensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/Extensions.cs new file mode 100644 index 00000000000000..0ac57e88ed9ee5 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/Extensions.cs @@ -0,0 +1,62 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Text; +using Microsoft.CodeAnalysis; +using SourceGenerators; + +namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration +{ + internal static class ParserExtensions + { + private static readonly SymbolDisplayFormat s_identifierCompatibleFormat = new SymbolDisplayFormat( + globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Omitted, + typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes, + genericsOptions: SymbolDisplayGenericsOptions.None, + miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes); + + public static void RegisterCacheEntry(this Dictionary cache, TKey key, TEntry entry) + where TKey : notnull + where TValue : ICollection, new() + { + if (!cache.TryGetValue(key, out TValue? entryCollection)) + { + cache[key] = entryCollection = new TValue(); + } + + entryCollection.Add(entry); + } + + public static string ToIdentifierCompatibleSubstring(this ITypeSymbol type) + { + if (type is IArrayTypeSymbol arrayType) + { + int rank = arrayType.Rank; + string suffix = rank == 1 ? "Array" : $"Array{rank}D"; // Array, Array2D, Array3D, ... + return ToIdentifierCompatibleSubstring(arrayType.ElementType) + suffix; + } + + string displayString = type.ContainingType is null + ? type.Name + : type.ToDisplayString(s_identifierCompatibleFormat).Replace(".", string.Empty); + + if (type is not INamedTypeSymbol { IsGenericType: true } namedType) + { + return displayString; + } + + StringBuilder sb = new(displayString); + + if (namedType.GetAllTypeArgumentsInScope() is List typeArgsInScope) + { + foreach (ITypeSymbol genericArg in typeArgsInScope) + { + sb.Append(ToIdentifierCompatibleSubstring(genericArg)); + } + } + + return sb.ToString(); + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj index 5b10a6f8e06c6b..f63ddec1f4b72e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj @@ -25,6 +25,7 @@ + @@ -40,6 +41,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/KnownTypeSymbols.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/KnownTypeSymbols.cs index e3a4f67ed396b4..e381dc9c7c43ee 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/KnownTypeSymbols.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/KnownTypeSymbols.cs @@ -13,6 +13,8 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { internal sealed record KnownTypeSymbols { + public CSharpCompilation Compilation { get; } + public INamedTypeSymbol String { get; } public INamedTypeSymbol? CultureInfo { get; } public INamedTypeSymbol? DateOnly { get; } @@ -57,6 +59,8 @@ internal sealed record KnownTypeSymbols public KnownTypeSymbols(CSharpCompilation compilation) { + Compilation = compilation; + // Primitives (needed because they are Microsoft.CodeAnalysis.SpecialType.None) CultureInfo = compilation.GetBestTypeByMetadataName(typeof(CultureInfo)); DateOnly = compilation.GetBestTypeByMetadataName("System.DateOnly"); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/TypeSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/TypeSpec.cs index 6f5e26bf3f6d38..cf03e58e5231b1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/TypeSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/TypeSpec.cs @@ -15,17 +15,19 @@ internal abstract record TypeSpec public TypeSpec(ITypeSymbol type) { - IsValueType = type.IsValueType; Namespace = type.ContainingNamespace?.ToDisplayString(); DisplayString = type.ToDisplayString(s_minimalDisplayFormat); - Name = Namespace + "." + DisplayString.Replace(".", "+"); - IsInterface = type.TypeKind is TypeKind.Interface; + Name = (Namespace is null ? string.Empty : Namespace + ".") + DisplayString.Replace(".", "+"); + IdentifierCompatibleSubstring = type.ToIdentifierCompatibleSubstring(); + IsValueType = type.IsValueType; } public string Name { get; } public string DisplayString { get; } + public string IdentifierCompatibleSubstring { get; } + public string? Namespace { get; } public bool IsValueType { get; } @@ -42,8 +44,6 @@ public TypeSpec(ITypeSymbol type) public virtual TypeSpec EffectiveType => this; - public bool IsInterface { get; } - protected bool CanInitComplexObject() => InitializationStrategy is not InitializationStrategy.None && InitExceptionMessage is null; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/Strings.resx index 3978cbaac6ce48..be66da59c6b5a7 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/Strings.resx @@ -121,7 +121,7 @@ The collection type is not supported: '{0}'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. The target type for a binder call could not be determined diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf index 8c264bc592c9c0..3bc09d74a32702 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf @@ -8,8 +8,8 @@ - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. - Pro volání vazače se nevygenerovala logika vazby. Nepodporované vstupní vzory zahrnují obecná volání a předávání zabalených objektů. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + Pro volání vazače se nevygenerovala logika vazby. Nepodporované vstupní vzory zahrnují obecná volání a předávání zabalených objektů. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf index 37100d25efae20..4ef47bf55a3fb4 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf @@ -8,8 +8,8 @@ - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. - Für einen Binderaufruf wurde keine Bindungslogik generiert. Nicht unterstützte Eingabemuster umfassen generische Aufrufe und übergeben geschachtelte Objekte. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + Für einen Binderaufruf wurde keine Bindungslogik generiert. Nicht unterstützte Eingabemuster umfassen generische Aufrufe und übergeben geschachtelte Objekte. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf index 00bf90592cc311..f74c0d799d2a5d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf @@ -8,8 +8,8 @@ - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. - No se generó la lógica de enlace para una llamada de enlazador. Los patrones de entrada no admitidos incluyen llamadas genéricas y pasar objetos en cuadros. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + No se generó la lógica de enlace para una llamada de enlazador. Los patrones de entrada no admitidos incluyen llamadas genéricas y pasar objetos en cuadros. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf index 847bc6155aaaee..739f6a85c79492 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf @@ -8,8 +8,8 @@ - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. - La logique de liaison n’a pas été générée pour un appel de classeur. Les modèles d’entrée non pris en charge incluent les appels génériques et les objets boxed de passage. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + La logique de liaison n’a pas été générée pour un appel de classeur. Les modèles d’entrée non pris en charge incluent les appels génériques et les objets boxed de passage. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf index 9ee871268cff5a..16a25f5fef4a88 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf @@ -8,8 +8,8 @@ - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. - La logica di binding non è stata generata per una chiamata binder. I modelli di input non supportati includono chiamate generiche e il passaggio di oggetti in caselle. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + La logica di binding non è stata generata per una chiamata binder. I modelli di input non supportati includono chiamate generiche e il passaggio di oggetti in caselle. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf index b7d5becee73ca2..260aa898a04f16 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf @@ -8,8 +8,8 @@ - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. - バインダー呼び出しのバインド ロジックが生成されませんでした。サポートされていない入力パターンとしては、ジェネリック呼び出し、ボックス化されたオブジェクトの受け渡しなどがあります。 + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + バインダー呼び出しのバインド ロジックが生成されませんでした。サポートされていない入力パターンとしては、ジェネリック呼び出し、ボックス化されたオブジェクトの受け渡しなどがあります。 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf index 4c94c55903310e..5b73d60a47d613 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf @@ -8,8 +8,8 @@ - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. - 바인더 호출에 대한 바인딩 논리가 생성되지 않았습니다. 지원되지 않는 입력 패턴에는 제네릭 호출 및 boxed 개체 전달이 포함됩니다. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + 바인더 호출에 대한 바인딩 논리가 생성되지 않았습니다. 지원되지 않는 입력 패턴에는 제네릭 호출 및 boxed 개체 전달이 포함됩니다. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf index 808afa9723f55a..8a675ed3e3fa03 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf @@ -8,8 +8,8 @@ - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. - Nie wygenerowano logiki powiązania dla wywołania integratora. Nieobsługiwane wzorce wejściowe obejmują wywołania ogólne i przekazywanie obiektów w ramce. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + Nie wygenerowano logiki powiązania dla wywołania integratora. Nieobsługiwane wzorce wejściowe obejmują wywołania ogólne i przekazywanie obiektów w ramce. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf index 9f723e7e6af48b..5f54f60e4c13cc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf @@ -8,8 +8,8 @@ - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. - A lógica de associação não foi gerada para uma chamada de associador. Os padrões de entrada sem suporte incluem chamadas genéricas e passagem de objetos em caixa. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + A lógica de associação não foi gerada para uma chamada de associador. Os padrões de entrada sem suporte incluem chamadas genéricas e passagem de objetos em caixa. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf index cc2f61c6e9d514..bf40ee5af2c390 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf @@ -8,8 +8,8 @@ - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. - Логика привязки не была создана для вызова модуля привязки. К неподдерживаемым шаблонам ввода относятся универсальные вызовы и передача упакованных объектов. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + Логика привязки не была создана для вызова модуля привязки. К неподдерживаемым шаблонам ввода относятся универсальные вызовы и передача упакованных объектов. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf index 06aaaded5cf2c1..732554a8893005 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf @@ -8,8 +8,8 @@ - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. - Bir bağlayıcı çağrısı için bağlama mantığı oluşturulmadı. Desteklenmeyen giriş desenleri genel çağrılar ve geçici kutulu nesneler içeriyor. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + Bir bağlayıcı çağrısı için bağlama mantığı oluşturulmadı. Desteklenmeyen giriş desenleri genel çağrılar ve geçici kutulu nesneler içeriyor. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf index ef3affe4e22bcc..f35cf502782512 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -8,8 +8,8 @@ - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. - 未为联编程序调用生成绑定逻辑。不支持的输入模式包括泛型调用和传递装箱对象。 + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + 未为联编程序调用生成绑定逻辑。不支持的输入模式包括泛型调用和传递装箱对象。 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf index 39dd659d8890dd..ff843029507c1f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -8,8 +8,8 @@ - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects. - 未產生文件夾呼叫的繫結邏輯。不支援的輸入模式包括一般呼叫和傳遞方塊物件。 + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + 未產生文件夾呼叫的繫結邏輯。不支援的輸入模式包括一般呼叫和傳遞方塊物件。 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs index a7e0474028172b..3846145f71486a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs @@ -30,7 +30,7 @@ public ConfigurationBinderTestsBase() } } - public sealed partial class ConfigurationBinderTests : ConfigurationBinderTestsBase + public partial class ConfigurationBinderTests : ConfigurationBinderTestsBase { [Fact] public void BindWithNestedTypesWithReadOnlyProperties() diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/EmptyConfigType.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/EmptyConfigType.generated.txt new file mode 100644 index 00000000000000..c3db7a0ff408a5 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/EmptyConfigType.generated.txt @@ -0,0 +1,104 @@ +// +#nullable enable +#pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. + +namespace System.Runtime.CompilerServices +{ + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } +} + +namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration +{ + using Microsoft.Extensions.Configuration; + using System; + using System.CodeDom.Compiler; + using System.Collections.Generic; + using System.Globalization; + using System.Runtime.CompilerServices; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + file static class BindingExtensions + { + #region IConfiguration extensions. + /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. + [InterceptsLocation(@"src-0.cs", 12, 23)] + public static void Bind_TypeWithNoMembers(this IConfiguration configuration, object? instance) + { + } + + /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. + [InterceptsLocation(@"src-0.cs", 15, 23)] + public static void Bind_TypeWithNoMembers_Wrapper(this IConfiguration configuration, object? instance) + { + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + if (instance is null) + { + return; + } + + var typedObj = (TypeWithNoMembers_Wrapper)instance; + BindCore(configuration, ref typedObj, binderOptions: null); + } + #endregion IConfiguration extensions. + + #region Core binding extensions. + private readonly static Lazy> s_configKeys_TypeWithNoMembers_Wrapper = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "Member" }); + + public static void BindCore(IConfiguration configuration, ref TypeWithNoMembers_Wrapper instance, BinderOptions? binderOptions) + { + ValidateConfigurationKeys(typeof(TypeWithNoMembers_Wrapper), s_configKeys_TypeWithNoMembers_Wrapper, configuration, binderOptions); + + if (AsConfigWithChildren(configuration.GetSection("Member")) is IConfigurationSection section0) + { + instance.Member ??= new TypeWithNoMembers(); + } + } + + + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. + public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) + { + if (binderOptions?.ErrorOnUnknownConfiguration is true) + { + List? temp = null; + + foreach (IConfigurationSection section in configuration.GetChildren()) + { + if (!keys.Value.Contains(section.Key)) + { + (temp ??= new List()).Add($"'{section.Key}'"); + } + } + + if (temp is not null) + { + throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); + } + } + } + + public static IConfiguration? AsConfigWithChildren(IConfiguration configuration) + { + foreach (IConfigurationSection _ in configuration.GetChildren()) + { + return configuration; + } + return null; + } + #endregion Core binding extensions. + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBinderTests.Generator.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBinderTests.Generator.cs index 0e4a97b85b548a..1ffb263c836a1c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBinderTests.Generator.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBinderTests.Generator.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Collections.Generic; using Microsoft.Extensions.Configuration; using Xunit; @@ -249,5 +251,169 @@ private static void AssertRecordIsBound(GeolocationRecord record, int longitude, { Assert.Equal((longitude, latitude), (record.Longitude, record.Latitude)); } + + // These are regression tests for https://github.com/dotnet/runtime/issues/90976 + // Ensure that every emitted identifier name is unique, otherwise name clashes + // will occur and cause compilation to fail. + + [Fact] + public void NameClashTests_NamingPatternsThatCouldCauseClashes() + { + // Potential class between type with closed generic & non generic type. + // Both types start with same substring. The generic arg type's name is + // the same as the suffix of the non generic type's name. + // Manifested in https://github.com/dotnet/runtime/issues/90976. + + IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{""Value"":1}"); + + var c1 = new Cint(); + var c2 = new C(); + + configuration.Bind(c1); + configuration.Bind(c2); + Assert.Equal(1, c1.Value); + Assert.Equal(1, c2.Value); + } + + internal class C + { + public int Value { get; set; } + } + + internal class Cint + { + public int Value { get; set; } + } + + [Fact] + public void NameClashTests_SameTypeName() + { + // Both types have the same name, but one is a nested type. + + IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{""Value"":1}"); + + var c1 = new ClassWithThisIdentifier(); + var c2 = new ClassWithThisIdentifier_Wrapper.ClassWithThisIdentifier(); + + configuration.Bind(c1); + configuration.Bind(c2); + Assert.Equal(1, c1.Value); + Assert.Equal(1, c2.Value); + } + + internal class ClassWithThisIdentifier + { + public int Value { get; set; } + } + + internal class ClassWithThisIdentifier_Wrapper + { + internal class ClassWithThisIdentifier + { + public int Value { get; set; } + } + } + + /// + /// These are regression tests for https://github.com/dotnet/runtime/issues/90909. + /// Ensure that we don't emit root interceptors to handle types/members that + /// are inaccessible to the generated helpers. Tests for inaccessbile transitive members + /// are covered in the shared (reflection/src-gen) , + /// e.g. . + /// + /// + /// In these cases, binding calls will fallback to reflection, as with all cases where + /// we can't correctly resolve the type, such as generic call patterns and boxed objects. + /// + [Fact] + public void MemberAccessibility_InaccessibleNestedTypeAsRootConfig() + { + IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{""Value"":1}"); + + // Ensure no compilation errors; types are skipped. + +#pragma warning disable SYSLIB1104 // Binding logic was not generated for a binder call. + var c1 = new InaccessibleClass_1(); + configuration.Bind(c1); + var c2 = configuration.Get(); + var c3 = configuration.Get(); + + // Generic collections. + + configuration = TestHelpers + .GetConfigurationFromJsonString(@"{""Array"": [{""Value"":1}]}") + .GetSection("Array"); + var c4 = configuration.Get(); + var c5 = configuration.Get>(); + + // Generic types. + + Action? configureOptions = options => options.BindNonPublicProperties = true; + string GetNestedObjectPayload(string propName) => $$""" + { + "{{propName}}": { + "Value": 1 + } + } + """; + + configuration = TestHelpers.GetConfigurationFromJsonString(GetNestedObjectPayload("item1")); + var c6 = configuration.Get>(configureOptions); + + configuration = TestHelpers.GetConfigurationFromJsonString(GetNestedObjectPayload("protectedMember")); + var c7 = configuration.Get>(configureOptions); + var c8 = configuration.Get>(configureOptions); + + configuration = TestHelpers.GetConfigurationFromJsonString(GetNestedObjectPayload("publicMember")); + var c9 = configuration.Get>(configureOptions); + var c10 = configuration.Get>(configureOptions); +#pragma warning disable SYSLIB1104 + + // Reflection fallback. + + Assert.Equal(1, c1.Value); + Assert.Equal(1, c2.Value); + Assert.Equal(1, c3.Value); + + Assert.Equal(1, c4[0].Value); + Assert.Equal(1, c5[0].Value); + Assert.Equal(1, c6["item1"].Value); + + Assert.Equal(1, c7.GetProtectedMember.Value); + Assert.Equal(1, c8.GetProtectedMember.Value); + Assert.Equal(1, c9.PublicMember.Value); + Assert.Equal(1, c10.PublicMember.Value); + } + + private class InaccessibleClass_1() + { + public int Value { get; set; } + } + + protected record InaccessibleClass_2(int Value); + + protected internal class InaccessibleClass_3 + { + public InaccessibleClass_3(int value) => Value = value; + + public int Value { get; } + } + + internal class AccessibleGenericClass + { + protected T ProtectedMember { get; set; } + + public T GetProtectedMember => ProtectedMember; + } + + private class InaccessibleGenericClass + { + public T PublicMember { get; set; } + } + + public class AccessibleClass() + { + public int Value { get; set; } + } } } diff --git a/src/libraries/System.Text.Json/gen/Helpers/RoslynExtensions.cs b/src/libraries/System.Text.Json/gen/Helpers/RoslynExtensions.cs index b0cb90e33d1476..7d280ce7603c2d 100644 --- a/src/libraries/System.Text.Json/gen/Helpers/RoslynExtensions.cs +++ b/src/libraries/System.Text.Json/gen/Helpers/RoslynExtensions.cs @@ -209,28 +209,6 @@ public static bool IsNullableValueType(this ITypeSymbol type, [NotNullWhen(true) return false; } - public static ITypeSymbol[] GetAllTypeArgumentsInScope(this INamedTypeSymbol type) - { - if (!type.IsGenericType) - { - return Array.Empty(); - } - - var args = new List(); - TraverseContainingTypes(type); - return args.ToArray(); - - void TraverseContainingTypes(INamedTypeSymbol current) - { - if (current.ContainingType is INamedTypeSymbol parent) - { - TraverseContainingTypes(parent); - } - - args.AddRange(current.TypeArguments); - } - } - public static ITypeSymbol GetMemberType(this ISymbol member) { Debug.Assert(member is IFieldSymbol or IPropertySymbol); diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs index 3242dcc5faa4c2..0f3b11b038bc93 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs @@ -11,6 +11,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; +using SourceGenerators; namespace System.Text.Json.SourceGeneration { @@ -1609,9 +1610,12 @@ private static string GetTypeInfoPropertyName(ITypeSymbol type) sb.Append(name); - foreach (ITypeSymbol genericArg in namedType.GetAllTypeArgumentsInScope()) + if (namedType.GetAllTypeArgumentsInScope() is List typeArgsInScope) { - sb.Append(GetTypeInfoPropertyName(genericArg)); + foreach (ITypeSymbol genericArg in typeArgsInScope) + { + sb.Append(GetTypeInfoPropertyName(genericArg)); + } } return sb.ToString(); diff --git a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets index 364f6e1f6682f7..4020a05cb421db 100644 --- a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets +++ b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets @@ -31,6 +31,7 @@ + From 9cdbc87dadbf358206f20f17fed005cdcb253452 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 15:08:14 -0700 Subject: [PATCH 185/783] Replace newline characters in NoWarn (#92062) Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com> Co-authored-by: Jan Kotas --- .../nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index a4f34ef2225483..e9462399741c5e 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -263,7 +263,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + From f6cee7c5e7a96858460be1f6711a5cb93057cc24 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Fri, 15 Sep 2023 07:31:13 -0700 Subject: [PATCH 186/783] Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2267753 (#92090) --- .../gen/Resources/xlf/Strings.cs.xlf | 2 +- .../gen/Resources/xlf/Strings.de.xlf | 2 +- .../gen/Resources/xlf/Strings.es.xlf | 2 +- .../gen/Resources/xlf/Strings.fr.xlf | 2 +- .../gen/Resources/xlf/Strings.it.xlf | 2 +- .../gen/Resources/xlf/Strings.ja.xlf | 2 +- .../gen/Resources/xlf/Strings.ko.xlf | 2 +- .../gen/Resources/xlf/Strings.pl.xlf | 2 +- .../gen/Resources/xlf/Strings.pt-BR.xlf | 2 +- .../gen/Resources/xlf/Strings.ru.xlf | 2 +- .../gen/Resources/xlf/Strings.tr.xlf | 2 +- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 2 +- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf index 3bc09d74a32702..3f881b123eb971 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Pro volání vazače se nevygenerovala logika vazby. Nepodporované vstupní vzory zahrnují obecná volání a předávání zabalených objektů. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf index 4ef47bf55a3fb4..89583fdc312308 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Für einen Binderaufruf wurde keine Bindungslogik generiert. Nicht unterstützte Eingabemuster umfassen generische Aufrufe und übergeben geschachtelte Objekte. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf index f74c0d799d2a5d..faa309bd384637 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - No se generó la lógica de enlace para una llamada de enlazador. Los patrones de entrada no admitidos incluyen llamadas genéricas y pasar objetos en cuadros. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf index 739f6a85c79492..f8d4c5a5f95d32 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - La logique de liaison n’a pas été générée pour un appel de classeur. Les modèles d’entrée non pris en charge incluent les appels génériques et les objets boxed de passage. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf index 16a25f5fef4a88..54a26a381d6fd1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - La logica di binding non è stata generata per una chiamata binder. I modelli di input non supportati includono chiamate generiche e il passaggio di oggetti in caselle. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf index 260aa898a04f16..b5f1790b0db187 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - バインダー呼び出しのバインド ロジックが生成されませんでした。サポートされていない入力パターンとしては、ジェネリック呼び出し、ボックス化されたオブジェクトの受け渡しなどがあります。 + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf index 5b73d60a47d613..dfcbc040fe3067 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - 바인더 호출에 대한 바인딩 논리가 생성되지 않았습니다. 지원되지 않는 입력 패턴에는 제네릭 호출 및 boxed 개체 전달이 포함됩니다. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf index 8a675ed3e3fa03..1834dac0e73f15 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Nie wygenerowano logiki powiązania dla wywołania integratora. Nieobsługiwane wzorce wejściowe obejmują wywołania ogólne i przekazywanie obiektów w ramce. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf index 5f54f60e4c13cc..e15e781b7abfdc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - A lógica de associação não foi gerada para uma chamada de associador. Os padrões de entrada sem suporte incluem chamadas genéricas e passagem de objetos em caixa. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf index bf40ee5af2c390..00e4d7418b5db6 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Логика привязки не была создана для вызова модуля привязки. К неподдерживаемым шаблонам ввода относятся универсальные вызовы и передача упакованных объектов. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf index 732554a8893005..cd53389a70ed28 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Bir bağlayıcı çağrısı için bağlama mantığı oluşturulmadı. Desteklenmeyen giriş desenleri genel çağrılar ve geçici kutulu nesneler içeriyor. + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf index f35cf502782512..55c321ec0d801f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - 未为联编程序调用生成绑定逻辑。不支持的输入模式包括泛型调用和传递装箱对象。 + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf index ff843029507c1f..edc74d0c17ad97 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - 未產生文件夾呼叫的繫結邏輯。不支援的輸入模式包括一般呼叫和傳遞方塊物件。 + Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. From 740081f22a3ea86d56e98a182a9086f9c07835ad Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 09:36:40 -0700 Subject: [PATCH 187/783] [release/8.0] Update FixupPrecode and StubPrecode types for ARM (#92075) * Update FixupPrecode and StubPrecode types for ARM Co-authored-by: Jan Vorlicek * Update ThisPtrRetBufPrecode and NDirectImportPrecode types for arm Co-authored-by: Jan Vorlicek * Addressing PR feedback - remove unnecessary #ifdef's * FIx riscv64 build break due to NDirectImportPrecode::Type conflict with ThisPtrRetBufPrecode::Type --------- Co-authored-by: Tom McDonald Co-authored-by: Jan Vorlicek --- src/coreclr/vm/arm/cgencpu.h | 2 +- src/coreclr/vm/precode.h | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/coreclr/vm/arm/cgencpu.h b/src/coreclr/vm/arm/cgencpu.h index d31700e3477a40..6538cea705a56a 100644 --- a/src/coreclr/vm/arm/cgencpu.h +++ b/src/coreclr/vm/arm/cgencpu.h @@ -996,7 +996,7 @@ inline BOOL ClrFlushInstructionCache(LPCVOID pCodeAddr, size_t sizeOfCode, bool // Precode to shuffle this and retbuf for closed delegates over static methods with return buffer struct ThisPtrRetBufPrecode { - static const int Type = 0x46; + static const int Type = 0x01; // mov r12, r0 // mov r0, r1 diff --git a/src/coreclr/vm/precode.h b/src/coreclr/vm/precode.h index 158c1ab08f5545..3f6a2f532c4e67 100644 --- a/src/coreclr/vm/precode.h +++ b/src/coreclr/vm/precode.h @@ -36,8 +36,8 @@ EXTERN_C VOID STDCALL PrecodeRemotingThunk(); #elif defined(TARGET_ARM) -#define SIZEOF_PRECODE_BASE CODE_SIZE_ALIGN -#define OFFSETOF_PRECODE_TYPE 3 +#define SIZEOF_PRECODE_BASE CODE_SIZE_ALIGN * 2 +#define OFFSETOF_PRECODE_TYPE 7 #elif defined(TARGET_LOONGARCH64) @@ -100,7 +100,7 @@ struct StubPrecode static const int Type = 0x4A; static const SIZE_T CodeSize = 24; #elif defined(TARGET_ARM) - static const int Type = 0xCF; + static const int Type = 0xFF; static const SIZE_T CodeSize = 12; #elif defined(TARGET_LOONGARCH64) static const int Type = 0x4; @@ -189,7 +189,7 @@ typedef DPTR(StubPrecode) PTR_StubPrecode; // (This is fake precode. VTable slot does not point to it.) struct NDirectImportPrecode : StubPrecode { - static const int Type = 0x01; + static const int Type = 0x05; void Init(NDirectImportPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator); @@ -237,7 +237,7 @@ struct FixupPrecode static const SIZE_T CodeSize = 24; static const int FixupCodeOffset = 8; #elif defined(TARGET_ARM) - static const int Type = 0xFF; + static const int Type = 0xCF; static const SIZE_T CodeSize = 12; static const int FixupCodeOffset = 4 + THUMB_CODE; #elif defined(TARGET_LOONGARCH64) @@ -614,4 +614,8 @@ static_assert_no_msg(FixupPrecode::Type != NDirectImportPrecode::Type); static_assert_no_msg(FixupPrecode::Type != ThisPtrRetBufPrecode::Type); static_assert_no_msg(NDirectImportPrecode::Type != ThisPtrRetBufPrecode::Type); +// Verify that the base type for each precode fits into each specific precode type +static_assert_no_msg(sizeof(Precode) <= sizeof(NDirectImportPrecode)); +static_assert_no_msg(sizeof(Precode) <= sizeof(FixupPrecode)); +static_assert_no_msg(sizeof(Precode) <= sizeof(ThisPtrRetBufPrecode)); #endif // __PRECODE_H__ From d8a419ae772988d7ebaa6cebaf5570d6abd84e7c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 09:40:22 -0700 Subject: [PATCH 188/783] Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20230914.2 (#92121) Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23458.2 -> To Version 3.11.0-beta1.23464.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 69ae2ed593410b..5d31a0830de329 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -371,13 +371,13 @@ https://github.com/dotnet/roslyn 1b7a6f807cb8ce709048debae6b771f4705a697a - + https://github.com/dotnet/roslyn-analyzers - 249601bb0afe8c481f01300012610f1ac182dfa5 + 7ec4e8924bcbc469e00aa2bda84251c3e90aa96e - + https://github.com/dotnet/roslyn-analyzers - 249601bb0afe8c481f01300012610f1ac182dfa5 + 7ec4e8924bcbc469e00aa2bda84251c3e90aa96e https://github.com/dotnet/sdk diff --git a/eng/Versions.props b/eng/Versions.props index 4dc7e62f9ec17c..d5c3bfcb0fd9f0 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,8 +34,8 @@ - 3.11.0-beta1.23458.2 - 8.0.0-preview.23458.2 + 3.11.0-beta1.23464.2 + 8.0.0-preview.23464.2 diff --git a/eng/Versions.props b/eng/Versions.props index d5c3bfcb0fd9f0..9223996861d8fd 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -156,12 +156,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23463.3 - 1.0.0-prerelease.23463.3 - 1.0.0-prerelease.23463.3 - 1.0.0-prerelease.23463.3 - 1.0.0-prerelease.23463.3 - 1.0.0-prerelease.23463.3 + 1.0.0-prerelease.23464.6 + 1.0.0-prerelease.23464.6 + 1.0.0-prerelease.23464.6 + 1.0.0-prerelease.23464.6 + 1.0.0-prerelease.23464.6 + 1.0.0-prerelease.23464.6 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From bb44ca5adee2ee1d139ae3780db8508c752d06de Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 11:19:06 -0700 Subject: [PATCH 192/783] [release/8.0] fix ReceiveFrom with dual mode socket (#92103) * fix ReceiveFrom with dual mode socket * test * feedback --------- Co-authored-by: wfurt Co-authored-by: Anton Firszov --- .../src/Resources/Strings.resx | 2 +- .../src/System/Net/IPEndPoint.cs | 6 +-- .../tests/FunctionalTests/IPEndPointTest.cs | 16 ++++++- .../Net/Sockets/SocketAsyncEventArgs.cs | 17 +++++-- .../tests/FunctionalTests/ReceiveFrom.cs | 46 +++++++++++++++++++ 5 files changed, 76 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.Net.Primitives/src/Resources/Strings.resx b/src/libraries/System.Net.Primitives/src/Resources/Strings.resx index 958a0e2e269f99..65d4809398b3b2 100644 --- a/src/libraries/System.Net.Primitives/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Primitives/src/Resources/Strings.resx @@ -64,7 +64,7 @@ This property is not implemented by this class. - The AddressFamily {0} is not valid for the {1} end point, use {2} instead. + The AddressFamily {0} is not valid for the {1} end point. The supplied {0} is an invalid size for the {1} end point. diff --git a/src/libraries/System.Net.Primitives/src/System/Net/IPEndPoint.cs b/src/libraries/System.Net.Primitives/src/System/Net/IPEndPoint.cs index 3531f266e6c504..ff47d2fbc515ef 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/IPEndPoint.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/IPEndPoint.cs @@ -155,9 +155,9 @@ public override EndPoint Create(SocketAddress socketAddress) { ArgumentNullException.ThrowIfNull(socketAddress); - if (socketAddress.Family != AddressFamily) - { - throw new ArgumentException(SR.Format(SR.net_InvalidAddressFamily, socketAddress.Family.ToString(), GetType().FullName, AddressFamily.ToString()), nameof(socketAddress)); + if (socketAddress.Family is not (AddressFamily.InterNetwork or AddressFamily.InterNetworkV6)) + { + throw new ArgumentException(SR.Format(SR.net_InvalidAddressFamily, socketAddress.Family.ToString(), GetType().FullName), nameof(socketAddress)); } int minSize = AddressFamily == AddressFamily.InterNetworkV6 ? SocketAddress.IPv6AddressSize : SocketAddress.IPv4AddressSize; diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/IPEndPointTest.cs b/src/libraries/System.Net.Primitives/tests/FunctionalTests/IPEndPointTest.cs index bb9b95d438e99f..c233dee628dfeb 100644 --- a/src/libraries/System.Net.Primitives/tests/FunctionalTests/IPEndPointTest.cs +++ b/src/libraries/System.Net.Primitives/tests/FunctionalTests/IPEndPointTest.cs @@ -143,6 +143,19 @@ public static void ToString_Invoke_ReturnsExpected(IPEndPoint endPoint, string e Assert.Equal(expected, endPoint.ToString()); } + [Fact] + public static void Create_DifferentAF_Success() + { + SocketAddress sa = new SocketAddress(AddressFamily.InterNetwork, SocketAddress.GetMaximumAddressSize(AddressFamily.InterNetworkV6)); + var ep = new IPEndPoint(IPAddress.IPv6Any, 0); + Assert.NotNull(ep.Create(sa)); + + sa = new SocketAddress(AddressFamily.InterNetworkV6); + ep = new IPEndPoint(IPAddress.Any, 0); + + Assert.NotNull(ep.Create(sa)); + } + public static IEnumerable Serialize_TestData() { yield return new object[] { new IPAddress(2), 16 }; @@ -195,8 +208,7 @@ public static void Create_NullSocketAddress_ThrowsArgumentNullException() public static IEnumerable Create_InvalidAddressFamily_TestData() { - yield return new object[] { new IPEndPoint(2, 500), new SocketAddress(Sockets.AddressFamily.InterNetworkV6) }; - yield return new object[] { new IPEndPoint(IPAddress.Parse("192.169.0.9"), 500), new SocketAddress(Sockets.AddressFamily.InterNetworkV6) }; + yield return new object[] { new IPEndPoint(2, 500), new SocketAddress(Sockets.AddressFamily.Unknown) }; yield return new object[] { new IPEndPoint(IPAddress.Parse("0:0:0:0:0:0:0:1"), 500), new SocketAddress(Sockets.AddressFamily.InterNetwork) }; } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs index e04739d5fe7a6e..e94d862571a0f8 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs @@ -927,13 +927,13 @@ internal void FinishOperationSyncSuccess(int bytesTransferred, SocketFlags flags { try { - if (_remoteEndPoint!.AddressFamily == _socketAddress!.Family) + if (_remoteEndPoint!.AddressFamily == AddressFamily.InterNetworkV6 && _socketAddress!.Family == AddressFamily.InterNetwork) { - _remoteEndPoint = _remoteEndPoint!.Create(_socketAddress); + _remoteEndPoint = new IPEndPoint(_socketAddress.GetIPAddress().MapToIPv6(), _socketAddress.GetPort()); } - else if (_remoteEndPoint!.AddressFamily == AddressFamily.InterNetworkV6 && _socketAddress.Family == AddressFamily.InterNetwork) + else { - _remoteEndPoint = new IPEndPoint(_socketAddress.GetIPAddress().MapToIPv6(), _socketAddress.GetPort()); + _remoteEndPoint = _remoteEndPoint!.Create(_socketAddress!); } } catch @@ -949,7 +949,14 @@ internal void FinishOperationSyncSuccess(int bytesTransferred, SocketFlags flags { try { - _remoteEndPoint = _remoteEndPoint!.Create(_socketAddress!); + if (_remoteEndPoint!.AddressFamily == AddressFamily.InterNetworkV6 && _socketAddress!.Family == AddressFamily.InterNetwork) + { + _remoteEndPoint = new IPEndPoint(_socketAddress.GetIPAddress().MapToIPv6(), _socketAddress.GetPort()); + } + else + { + _remoteEndPoint = _remoteEndPoint!.Create(_socketAddress!); + } } catch { diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveFrom.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveFrom.cs index 1a5ec7d05d28e9..1ec2adeadcf517 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveFrom.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveFrom.cs @@ -168,6 +168,52 @@ public async Task ReceiveSent_UDP_Success(bool ipv4) } } + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task ReceiveSent_DualMode_Success(bool ipv4) + { + const int Offset = 10; + const int DatagramSize = 256; + const int DatagramsToSend = 16; + + IPAddress address = ipv4 ? IPAddress.Loopback : IPAddress.IPv6Loopback; + using Socket receiver = new Socket(SocketType.Dgram, ProtocolType.Udp); + using Socket sender = new Socket(SocketType.Dgram, ProtocolType.Udp); + if (receiver.DualMode != true || sender.DualMode != true) + { + throw new SkipException("DualMode not available"); + } + + ConfigureNonBlocking(sender); + ConfigureNonBlocking(receiver); + + receiver.BindToAnonymousPort(address); + sender.BindToAnonymousPort(address); + + byte[] sendBuffer = new byte[DatagramSize]; + var receiveInternalBuffer = new byte[DatagramSize + Offset]; + var emptyBuffer = new byte[Offset]; + ArraySegment receiveBuffer = new ArraySegment(receiveInternalBuffer, Offset, DatagramSize); + + Random rnd = new Random(0); + + for (int i = 0; i < DatagramsToSend; i++) + { + rnd.NextBytes(sendBuffer); + sender.SendTo(sendBuffer, receiver.LocalEndPoint); + + IPEndPoint remoteEp = new IPEndPoint(ipv4 ? IPAddress.Any : IPAddress.IPv6Any, 0); + + SocketReceiveFromResult result = await ReceiveFromAsync(receiver, receiveBuffer, remoteEp); + + Assert.Equal(DatagramSize, result.ReceivedBytes); + AssertExtensions.SequenceEqual(emptyBuffer, new ReadOnlySpan(receiveInternalBuffer, 0, Offset)); + AssertExtensions.SequenceEqual(sendBuffer, new ReadOnlySpan(receiveInternalBuffer, Offset, DatagramSize)); + Assert.Equal(sender.LocalEndPoint, result.RemoteEndPoint); + } + } + [Theory] [InlineData(false)] [InlineData(true)] From f262154e0a2129e51313bb1b35aa6aeee4dca4fb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 13:51:31 -0700 Subject: [PATCH 193/783] [release/8.0] [NativeAOT] Switch macOS to mmap thunks like iOS platforms (#92136) * Switch macOS to mmap thunks like iOS platforms * Relax expected binary size --------- Co-authored-by: Filip Navara Co-authored-by: Jan Kotas --- .../BuildIntegration/Microsoft.NETCore.Native.Unix.targets | 2 +- src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt | 2 +- src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Program.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 409fcb654e919d..d30e7e73578eaa 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -121,7 +121,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + diff --git a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt index 3cbaa6e2f253a6..f3d48797c2184a 100644 --- a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt @@ -6,7 +6,7 @@ project(Runtime) # Include auto-generated files on include path set(CMAKE_INCLUDE_CURRENT_DIR ON) -if (CLR_CMAKE_TARGET_APPLE AND NOT CLR_CMAKE_TARGET_OSX) +if (CLR_CMAKE_TARGET_APPLE) list(APPEND RUNTIME_SOURCES_ARCH_ASM ${ARCH_SOURCES_DIR}/ThunkPoolThunks.${ASM_SUFFIX} ) diff --git a/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Program.cs b/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Program.cs index e628938c57db82..52a86654a03166 100644 --- a/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Program.cs +++ b/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Program.cs @@ -22,7 +22,7 @@ static int Main() long lowerBound, upperBound; lowerBound = 1300 * 1024; // ~1.3 MB - upperBound = 1750 * 1024; // ~1.75 MB + upperBound = 1800 * 1024; // ~1.8 MB if (fileSize < lowerBound || fileSize > upperBound) { From 90d54f9f9e68c317cc2c7d1c94ac84d9d2489848 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Fri, 15 Sep 2023 17:41:58 -0700 Subject: [PATCH 194/783] [release/8.0] Improve binder gen binding logic (init, member binding, polymorphism) (#92118) --- .../ConfigurationBindingGenerator.Emitter.cs | 178 ------ .../ConfigurationBindingGenerator.Parser.cs | 279 ++++----- .../Emitter/ConfigurationBinder.cs | 14 +- .../Emitter/CoreBindingHelpers.cs | 588 ++++++++++++------ .../Emitter/ExceptionMessages.cs | 0 .../gen/{Helpers => }/Emitter/Helpers.cs | 18 +- .../OptionsBuilderConfigurationExtensions.cs | 0 ...onfigurationServiceCollectionExtensions.cs | 0 ...nfiguration.Binder.SourceGeneration.csproj | 51 +- .../gen/Model/ConfigurationSectionSpec.cs | 14 - .../gen/Model/InitializationStrategy.cs | 14 - .../{Helpers => }/Parser/BinderInvocation.cs | 0 .../Parser/ConfigurationBinder.cs | 31 +- .../gen/{Helpers => }/Parser/Diagnostics.cs | 0 .../gen/{Helpers => }/Parser/Extensions.cs | 6 + .../OptionsBuilderConfigurationExtensions.cs | 28 +- ...onfigurationServiceCollectionExtensions.cs | 27 +- .../InterceptorLocationInfo.cs | 0 .../gen/{Model => Specs}/KnownTypeSymbols.cs | 0 .../{Model => Specs/Members}/MemberSpec.cs | 0 .../{Model => Specs/Members}/ParameterSpec.cs | 0 .../{Model => Specs/Members}/PropertySpec.cs | 2 +- .../gen/{Helpers => Specs}/MethodsToGen.cs | 0 .../{Model => Specs}/SourceGenerationSpec.cs | 0 .../{Model => Specs/Types}/CollectionSpec.cs | 20 +- .../gen/Specs/Types/ComplexTypeSpec.cs | 29 + .../{Model => Specs/Types}/NullableSpec.cs | 9 +- .../gen/{Model => Specs/Types}/ObjectSpec.cs | 8 +- .../Types/SimpleTypeSpec.cs} | 20 +- .../gen/{Model => Specs/Types}/TypeSpec.cs | 14 +- .../ConfigurationBinderTests.TestClasses.cs | 68 +- .../tests/Common/ConfigurationBinderTests.cs | 135 +++- ...ind_ParseTypeFromMethodParam.generated.txt | 72 +++ .../GeneratorTests.Baselines.cs | 92 +++ .../GeneratorTests.Helpers.cs | 3 +- .../SourceGenerationTests/GeneratorTests.cs | 59 +- 36 files changed, 1064 insertions(+), 715 deletions(-) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => }/Emitter/ConfigurationBinder.cs (94%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => }/Emitter/CoreBindingHelpers.cs (60%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => }/Emitter/ExceptionMessages.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => }/Emitter/Helpers.cs (96%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => }/Emitter/OptionsBuilderConfigurationExtensions.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => }/Emitter/OptionsConfigurationServiceCollectionExtensions.cs (100%) delete mode 100644 src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ConfigurationSectionSpec.cs delete mode 100644 src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/InitializationStrategy.cs rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => }/Parser/BinderInvocation.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => }/Parser/ConfigurationBinder.cs (88%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => }/Parser/Diagnostics.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => }/Parser/Extensions.cs (89%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => }/Parser/OptionsBuilderConfigurationExtensions.cs (77%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => }/Parser/OptionsConfigurationServiceCollectionExtensions.cs (77%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => Specs}/InterceptorLocationInfo.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Model => Specs}/KnownTypeSymbols.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Model => Specs/Members}/MemberSpec.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Model => Specs/Members}/ParameterSpec.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Model => Specs/Members}/PropertySpec.cs (95%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Helpers => Specs}/MethodsToGen.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Model => Specs}/SourceGenerationSpec.cs (100%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Model => Specs/Types}/CollectionSpec.cs (64%) create mode 100644 src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ComplexTypeSpec.cs rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Model => Specs/Types}/NullableSpec.cs (73%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Model => Specs/Types}/ObjectSpec.cs (65%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Model/ParsableFromStringSpec.cs => Specs/Types/SimpleTypeSpec.cs} (71%) rename src/libraries/Microsoft.Extensions.Configuration.Binder/gen/{Model => Specs/Types}/TypeSpec.cs (78%) create mode 100644 src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_ParseTypeFromMethodParam.generated.txt diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs index cb67c7ee1f5fb9..7206d549041147 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs @@ -1,10 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Immutable; -using System.Diagnostics; -using System.Text.RegularExpressions; using Microsoft.CodeAnalysis; using SourceGenerators; @@ -16,12 +13,6 @@ private sealed partial class Emitter { private readonly SourceProductionContext _context; private readonly SourceGenerationSpec _sourceGenSpec; - - private bool _emitBlankLineBeforeNextStatement; - private int _valueSuffixIndex; - - private static readonly Regex s_arrayBracketsRegex = new(Regex.Escape("[]")); - private readonly SourceWriter _writer = new(); public Emitter(SourceProductionContext context, SourceGenerationSpec sourceGenSpec) @@ -64,163 +55,6 @@ file static class {{Identifier.BindingExtensions}} _context.AddSource($"{Identifier.BindingExtensions}.g.cs", _writer.ToSourceText()); } - private void EmitBindCoreCall( - TypeSpec type, - string memberAccessExpr, - string configArgExpr, - InitializationKind initKind, - Action? writeOnSuccess = null) - { - Debug.Assert(type.CanInitialize); - - if (!type.NeedsMemberBinding) - { - EmitObjectInit(memberAccessExpr, initKind); - return; - } - - string tempIdentifier = GetIncrementalIdentifier(Identifier.temp); - if (initKind is InitializationKind.AssignmentWithNullCheck) - { - Debug.Assert(!type.IsValueType); - _writer.WriteLine($"{type.DisplayString}? {tempIdentifier} = {memberAccessExpr};"); - EmitBindCoreCall(tempIdentifier, InitializationKind.AssignmentWithNullCheck); - } - else if (initKind is InitializationKind.None && type.IsValueType) - { - EmitBindCoreCall(tempIdentifier, InitializationKind.Declaration); - _writer.WriteLine($"{memberAccessExpr} = {tempIdentifier};"); - } - else - { - EmitBindCoreCall(memberAccessExpr, initKind); - } - - void EmitBindCoreCall(string instanceExpr, InitializationKind initKind) - { - string bindCoreCall = $@"{nameof(MethodsToGen_CoreBindingHelper.BindCore)}({configArgExpr}, ref {instanceExpr}, {Identifier.binderOptions});"; - EmitObjectInit(instanceExpr, initKind); - _writer.WriteLine(bindCoreCall); - writeOnSuccess?.Invoke(instanceExpr); - } - - void EmitObjectInit(string instanceExpr, InitializationKind initKind) - { - if (initKind is not InitializationKind.None) - { - this.EmitObjectInit(type, instanceExpr, initKind, configArgExpr); - } - } - } - - private void EmitBindLogicFromString( - ParsableFromStringSpec type, - string sectionValueExpr, - string sectionPathExpr, - Action? writeOnSuccess, - bool checkForNullSectionValue, - bool useIncrementalStringValueIdentifier) - { - StringParsableTypeKind typeKind = type.StringParsableTypeKind; - Debug.Assert(typeKind is not StringParsableTypeKind.None); - - string nonNull_StringValue_Identifier = useIncrementalStringValueIdentifier ? GetIncrementalIdentifier(Identifier.value) : Identifier.value; - string stringValueToParse_Expr = checkForNullSectionValue ? nonNull_StringValue_Identifier : sectionValueExpr; - - string parsedValueExpr; - if (typeKind is StringParsableTypeKind.AssignFromSectionValue) - { - parsedValueExpr = stringValueToParse_Expr; - } - else if (typeKind is StringParsableTypeKind.Enum) - { - parsedValueExpr = $"ParseEnum<{type.DisplayString}>({stringValueToParse_Expr}, () => {sectionPathExpr})"; - } - else - { - parsedValueExpr = $"{type.ParseMethodName}({stringValueToParse_Expr}, () => {sectionPathExpr})"; - } - - if (!checkForNullSectionValue) - { - InvokeWriteOnSuccess(); - } - else - { - EmitStartBlock($"if ({sectionValueExpr} is string {nonNull_StringValue_Identifier})"); - InvokeWriteOnSuccess(); - EmitEndBlock(); - } - - void InvokeWriteOnSuccess() => writeOnSuccess?.Invoke(parsedValueExpr); - } - - private bool EmitObjectInit(TypeSpec type, string memberAccessExpr, InitializationKind initKind, string configArgExpr) - { - Debug.Assert(type.CanInitialize && initKind is not InitializationKind.None); - - string initExpr; - CollectionSpec? collectionType = type as CollectionSpec; - - string effectiveDisplayString = type.DisplayString; - if (collectionType is not null) - { - if (collectionType is EnumerableSpec { InitializationStrategy: InitializationStrategy.Array }) - { - initExpr = $"new {s_arrayBracketsRegex.Replace(effectiveDisplayString, "[0]", 1)}"; - } - else - { - effectiveDisplayString = (collectionType.ConcreteType ?? collectionType).DisplayString; - initExpr = $"new {effectiveDisplayString}()"; - } - } - else if (type.InitializationStrategy is InitializationStrategy.ParameterlessConstructor) - { - initExpr = $"new {effectiveDisplayString}()"; - } - else - { - Debug.Assert(type.InitializationStrategy is InitializationStrategy.ParameterizedConstructor); - string initMethodIdentifier = GetInitalizeMethodDisplayString(((ObjectSpec)type)); - initExpr = $"{initMethodIdentifier}({configArgExpr}, {Identifier.binderOptions})"; - } - - if (initKind == InitializationKind.Declaration) - { - Debug.Assert(!memberAccessExpr.Contains(".")); - _writer.WriteLine($"var {memberAccessExpr} = {initExpr};"); - } - else if (initKind == InitializationKind.AssignmentWithNullCheck) - { - if (collectionType is CollectionSpec - { - InitializationStrategy: InitializationStrategy.ParameterizedConstructor or InitializationStrategy.ToEnumerableMethod - }) - { - if (collectionType.InitializationStrategy is InitializationStrategy.ParameterizedConstructor) - { - _writer.WriteLine($"{memberAccessExpr} = {memberAccessExpr} is null ? {initExpr} : new {effectiveDisplayString}({memberAccessExpr});"); - } - else - { - _writer.WriteLine($"{memberAccessExpr} = {memberAccessExpr} is null ? {initExpr} : {memberAccessExpr}.{collectionType.ToEnumerableMethodCall!};"); - } - } - else - { - _writer.WriteLine($"{memberAccessExpr} ??= {initExpr};"); - } - } - else - { - Debug.Assert(initKind is InitializationKind.SimpleAssignment); - _writer.WriteLine($"{memberAccessExpr} = {initExpr};"); - } - - return true; - } - private void EmitInterceptsLocationAttrDecl() { _writer.WriteLine(); @@ -250,18 +84,6 @@ private void EmitUsingStatements() _writer.WriteLine($"using {@namespace};"); } } - - private void EmitIConfigurationHasValueOrChildrenCheck(bool voidReturn) - { - string returnPostfix = voidReturn ? string.Empty : " null"; - _writer.WriteLine($$""" - if (!{{Identifier.HasValueOrChildren}}({{Identifier.configuration}})) - { - return{{returnPostfix}}; - } - """); - _writer.WriteLine(); - } } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs index deb0f4c0aabc0d..2a6f5d2126e8c8 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs @@ -52,15 +52,15 @@ public Parser(SourceProductionContext context, KnownTypeSymbols typeSymbols, Imm if (SymbolEqualityComparer.Default.Equals(candidateBinderType, _typeSymbols.ConfigurationBinder)) { - RegisterMethodInvocation_ConfigurationBinder(invocation); + ParseInvocation_ConfigurationBinder(invocation); } else if (SymbolEqualityComparer.Default.Equals(candidateBinderType, _typeSymbols.OptionsBuilderConfigurationExtensions)) { - RegisterMethodInvocation_OptionsBuilderExt(invocation); + ParseInvocation_OptionsBuilderExt(invocation); } else if (SymbolEqualityComparer.Default.Equals(candidateBinderType, _typeSymbols.OptionsConfigurationServiceCollectionExtensions)) { - RegisterMethodInvocation_ServiceCollectionExt(invocation); + ParseInvocation_ServiceCollectionExt(invocation); } } @@ -120,7 +120,7 @@ type.TypeKind is TypeKind.TypeParameter or TypeKind.Pointer or TypeKind.Error || if (IsNullable(type, out ITypeSymbol? underlyingType)) { - spec = TryGetTypeSpec(underlyingType, Diagnostics.NullableUnderlyingTypeNotSupported, out TypeSpec? underlyingTypeSpec) + spec = MemberTypeIsBindable(type, underlyingType, Diagnostics.NullableUnderlyingTypeNotSupported, out TypeSpec? underlyingTypeSpec) ? new NullableSpec(type, underlyingTypeSpec) : null; } @@ -165,13 +165,7 @@ type.TypeKind is TypeKind.TypeParameter or TypeKind.Pointer or TypeKind.Error || RegisterTypeDiagnostic(type, diag); } - if (spec is null) - { - return null; - } - - string @namespace = spec.Namespace; - if (@namespace is not null and not "") + if (spec is { Namespace: string @namespace } && @namespace is not "") { _sourceGenSpec.Namespaces.Add(@namespace); } @@ -179,28 +173,36 @@ type.TypeKind is TypeKind.TypeParameter or TypeKind.Pointer or TypeKind.Error || return _createdSpecs[type] = spec; } - private void RegisterTypeForBindCoreMainGen(TypeSpec typeSpec) + private bool TryRegisterTypeForBindCoreMainGen(ComplexTypeSpec type) { - if (typeSpec.NeedsMemberBinding) + if (type.HasBindableMembers) { - RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.BindCoreMain, typeSpec); - RegisterTypeForBindCoreGen(typeSpec); - _sourceGenSpec.MethodsToGen_CoreBindingHelper |= MethodsToGen_CoreBindingHelper.AsConfigWithChildren; + bool registeredForBindCoreGen = TryRegisterTypeForBindCoreGen(type); + Debug.Assert(registeredForBindCoreGen); + + RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.BindCoreMain, type); + Register_AsConfigWithChildren_HelperForGen_IfRequired(type); + return true; } + + return false; } - private void RegisterTypeForBindCoreGen(TypeSpec typeSpec) + private bool TryRegisterTypeForBindCoreGen(ComplexTypeSpec type) { - if (typeSpec.NeedsMemberBinding) + if (type.HasBindableMembers) { - RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.BindCore, typeSpec); + RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.BindCore, type); + return true; } + + return false; } private void RegisterTypeForGetCoreGen(TypeSpec typeSpec) { RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.GetCore, typeSpec); - _sourceGenSpec.MethodsToGen_CoreBindingHelper |= MethodsToGen_CoreBindingHelper.AsConfigWithChildren; + Register_AsConfigWithChildren_HelperForGen_IfRequired(typeSpec); } private void RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper method, TypeSpec type) @@ -214,11 +216,19 @@ private void RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper method, Typ _sourceGenSpec.MethodsToGen_CoreBindingHelper |= method; } + private void Register_AsConfigWithChildren_HelperForGen_IfRequired(TypeSpec possibleComplexType) + { + if (possibleComplexType is ComplexTypeSpec) + { + _sourceGenSpec.MethodsToGen_CoreBindingHelper |= MethodsToGen_CoreBindingHelper.AsConfigWithChildren; + } + } + /// /// Registers interceptors for root binding methods, except for ConfigurationBinder.Bind, - /// which is handled by + /// which is handled by /// - private void RegisterAsInterceptor(Enum method, IInvocationOperation operation) => + private void RegisterInterceptor(Enum method, IInvocationOperation operation) => _sourceGenSpec.InterceptionInfo.RegisterCacheEntry(method, new InterceptorLocationInfo(operation)); private static bool IsNullable(ITypeSymbol type, [NotNullWhen(true)] out ITypeSymbol? underlyingType) @@ -339,61 +349,33 @@ private bool IsParsableFromString(ITypeSymbol type, out StringParsableTypeKind t } } - private bool TryGetTypeSpec(ITypeSymbol type, DiagnosticDescriptor descriptor, out TypeSpec? spec) + private EnumerableSpec? CreateArraySpec(IArrayTypeSymbol arrayTypeSymbol) { - spec = GetOrCreateTypeSpec(type); + ITypeSymbol elementTypeSymbol = arrayTypeSymbol.ElementType; - if (spec is null) - { - RegisterUnsupportedType(type, descriptor); - return false; - } - - return true; - } - - private EnumerableSpec? CreateArraySpec(IArrayTypeSymbol arrayType) - { - if (!TryGetTypeSpec(arrayType.ElementType, Diagnostics.ElementTypeNotSupported, out TypeSpec elementSpec)) + if (!MemberTypeIsBindable(arrayTypeSymbol, elementTypeSymbol, Diagnostics.ElementTypeNotSupported, out TypeSpec elementTypeSpec)) { return null; } - // We want a BindCore method for List as a temp holder for the array values. We know the element type is supported. - EnumerableSpec listSpec = (GetOrCreateTypeSpec(_typeSymbols.List.Construct(arrayType.ElementType)) as EnumerableSpec)!; - RegisterTypeForBindCoreGen(listSpec); + // We want a BindCore method for List as a temp holder for the array values. + // Since the element type is supported, we can certainly a list of elements. + EnumerableSpec listTypeSpec = (EnumerableSpec)GetOrCreateTypeSpec(_typeSymbols.List.Construct(elementTypeSymbol)); - EnumerableSpec spec = new EnumerableSpec(arrayType) + EnumerableSpec spec = new EnumerableSpec(arrayTypeSymbol) { - ElementType = elementSpec, - ConcreteType = listSpec, - InitializationStrategy = InitializationStrategy.Array, + ElementType = elementTypeSpec, + InstantiationStrategy = InstantiationStrategy.Array, PopulationStrategy = CollectionPopulationStrategy.Cast_Then_Add, // Using the concrete list type as a temp holder. - ToEnumerableMethodCall = null, + TypeToInstantiate = listTypeSpec, + PopulationCastType = null, }; - Debug.Assert(spec.CanInitialize); - RegisterTypeForBindCoreGen(spec); - + bool registeredForBindCore = TryRegisterTypeForBindCoreGen(listTypeSpec) && TryRegisterTypeForBindCoreGen(spec); + Debug.Assert(registeredForBindCore); return spec; } - private bool IsSupportedArrayType(ITypeSymbol type) - { - if (type is not IArrayTypeSymbol arrayType) - { - return false; - } - - if (arrayType.Rank > 1) - { - RegisterUnsupportedType(arrayType, Diagnostics.MultiDimArraysNotSupported); - return false; - } - - return true; - } - private CollectionSpec? CreateCollectionSpec(INamedTypeSymbol type) { CollectionSpec? spec; @@ -407,38 +389,38 @@ private bool IsSupportedArrayType(ITypeSymbol type) spec = CreateEnumerableSpec(type); } - if (spec is not null) + if (spec is null) { - RegisterTypeForBindCoreGen(spec); - spec.InitExceptionMessage ??= spec.ElementType.InitExceptionMessage; + return null; } + bool registerForBindCoreGen = TryRegisterTypeForBindCoreGen(spec); + Debug.Assert(registerForBindCoreGen); return spec; } private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol keyType, ITypeSymbol elementType) { - if (!TryGetTypeSpec(keyType, Diagnostics.DictionaryKeyNotSupported, out TypeSpec keySpec) || - !TryGetTypeSpec(elementType, Diagnostics.ElementTypeNotSupported, out TypeSpec elementSpec)) + if (!MemberTypeIsBindable(type, keyType, Diagnostics.DictionaryKeyNotSupported, out TypeSpec keySpec) || + !MemberTypeIsBindable(type, elementType, Diagnostics.ElementTypeNotSupported, out TypeSpec elementSpec)) { return null; } - if (keySpec.SpecKind != TypeSpecKind.ParsableFromString) + if (keySpec.SpecKind is not TypeSpecKind.ParsableFromString) { RegisterUnsupportedType(type, Diagnostics.DictionaryKeyNotSupported); return null; } - InitializationStrategy constructionStrategy; + InstantiationStrategy constructionStrategy; CollectionPopulationStrategy populationStrategy; - INamedTypeSymbol? concreteType = null; + INamedTypeSymbol? typeToInstantiate = null; INamedTypeSymbol? populationCastType = null; - string? toEnumerableMethodCall = null; if (HasPublicParameterLessCtor(type)) { - constructionStrategy = InitializationStrategy.ParameterlessConstructor; + constructionStrategy = InstantiationStrategy.ParameterlessConstructor; if (HasAddMethod(type, keyType, elementType)) { @@ -457,17 +439,16 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol k } else if (IsInterfaceMatch(type, _typeSymbols.GenericIDictionary_Unbound) || IsInterfaceMatch(type, _typeSymbols.IDictionary)) { - concreteType = _typeSymbols.Dictionary; - constructionStrategy = InitializationStrategy.ParameterlessConstructor; + typeToInstantiate = _typeSymbols.Dictionary; + constructionStrategy = InstantiationStrategy.ParameterlessConstructor; populationStrategy = CollectionPopulationStrategy.Add; } else if (IsInterfaceMatch(type, _typeSymbols.IReadOnlyDictionary_Unbound)) { - concreteType = _typeSymbols.Dictionary; + typeToInstantiate = _typeSymbols.Dictionary; populationCastType = _typeSymbols.GenericIDictionary; - constructionStrategy = InitializationStrategy.ToEnumerableMethod; + constructionStrategy = InstantiationStrategy.ToEnumerableMethod; populationStrategy = CollectionPopulationStrategy.Cast_Then_Add; - toEnumerableMethodCall = "ToDictionary(pair => pair.Key, pair => pair.Value)"; _sourceGenSpec.Namespaces.Add("System.Linq"); } else @@ -476,38 +457,37 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol k return null; } + Debug.Assert(!(populationStrategy is CollectionPopulationStrategy.Cast_Then_Add && populationCastType is null)); + DictionarySpec spec = new(type) { KeyType = (ParsableFromStringSpec)keySpec, ElementType = elementSpec, - InitializationStrategy = constructionStrategy, + InstantiationStrategy = constructionStrategy, PopulationStrategy = populationStrategy, - ToEnumerableMethodCall = toEnumerableMethodCall, + TypeToInstantiate = ConstructGenericCollectionSpecIfRequired(typeToInstantiate, keyType, elementType) as DictionarySpec, + PopulationCastType = ConstructGenericCollectionSpecIfRequired(populationCastType, keyType, elementType) as DictionarySpec, }; - Debug.Assert(!(populationStrategy is CollectionPopulationStrategy.Cast_Then_Add && populationCastType is null)); - spec.ConcreteType = ConstructGenericCollectionSpecIfRequired(concreteType, keyType, elementType); - spec.PopulationCastType = ConstructGenericCollectionSpecIfRequired(populationCastType, keyType, elementType); - return spec; } private EnumerableSpec? CreateEnumerableSpec(INamedTypeSymbol type) { if (!TryGetElementType(type, out ITypeSymbol? elementType) || - !TryGetTypeSpec(elementType, Diagnostics.ElementTypeNotSupported, out TypeSpec elementSpec)) + !MemberTypeIsBindable(type, elementType, Diagnostics.ElementTypeNotSupported, out TypeSpec elementSpec)) { return null; } - InitializationStrategy constructionStrategy; + InstantiationStrategy instantiationStrategy; CollectionPopulationStrategy populationStrategy; - INamedTypeSymbol? concreteType = null; + INamedTypeSymbol? typeToInstantiate = null; INamedTypeSymbol? populationCastType = null; if (HasPublicParameterLessCtor(type)) { - constructionStrategy = InitializationStrategy.ParameterlessConstructor; + instantiationStrategy = InstantiationStrategy.ParameterlessConstructor; if (HasAddMethod(type, elementType)) { @@ -527,35 +507,35 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol k else if (IsInterfaceMatch(type, _typeSymbols.GenericICollection_Unbound) || IsInterfaceMatch(type, _typeSymbols.GenericIList_Unbound)) { - concreteType = _typeSymbols.List; - constructionStrategy = InitializationStrategy.ParameterlessConstructor; + typeToInstantiate = _typeSymbols.List; + instantiationStrategy = InstantiationStrategy.ParameterlessConstructor; populationStrategy = CollectionPopulationStrategy.Add; } else if (IsInterfaceMatch(type, _typeSymbols.GenericIEnumerable_Unbound)) { - concreteType = _typeSymbols.List; + typeToInstantiate = _typeSymbols.List; populationCastType = _typeSymbols.GenericICollection; - constructionStrategy = InitializationStrategy.ParameterizedConstructor; + instantiationStrategy = InstantiationStrategy.ParameterizedConstructor; populationStrategy = CollectionPopulationStrategy.Cast_Then_Add; } else if (IsInterfaceMatch(type, _typeSymbols.ISet_Unbound)) { - concreteType = _typeSymbols.HashSet; - constructionStrategy = InitializationStrategy.ParameterlessConstructor; + typeToInstantiate = _typeSymbols.HashSet; + instantiationStrategy = InstantiationStrategy.ParameterlessConstructor; populationStrategy = CollectionPopulationStrategy.Add; } else if (IsInterfaceMatch(type, _typeSymbols.IReadOnlySet_Unbound)) { - concreteType = _typeSymbols.HashSet; + typeToInstantiate = _typeSymbols.HashSet; populationCastType = _typeSymbols.ISet; - constructionStrategy = InitializationStrategy.ParameterizedConstructor; + instantiationStrategy = InstantiationStrategy.ParameterizedConstructor; populationStrategy = CollectionPopulationStrategy.Cast_Then_Add; } else if (IsInterfaceMatch(type, _typeSymbols.IReadOnlyList_Unbound) || IsInterfaceMatch(type, _typeSymbols.IReadOnlyCollection_Unbound)) { - concreteType = _typeSymbols.List; + typeToInstantiate = _typeSymbols.List; populationCastType = _typeSymbols.GenericICollection; - constructionStrategy = InitializationStrategy.ParameterizedConstructor; + instantiationStrategy = InstantiationStrategy.ParameterizedConstructor; populationStrategy = CollectionPopulationStrategy.Cast_Then_Add; } else @@ -564,40 +544,37 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol k return null; } - Register_AsConfigWithChildren_HelperForGen_IfRequired(elementSpec); + Debug.Assert(!(populationStrategy is CollectionPopulationStrategy.Cast_Then_Add && populationCastType is null)); EnumerableSpec spec = new(type) { ElementType = elementSpec, - InitializationStrategy = constructionStrategy, + InstantiationStrategy = instantiationStrategy, PopulationStrategy = populationStrategy, - ToEnumerableMethodCall = null, + TypeToInstantiate = ConstructGenericCollectionSpecIfRequired(typeToInstantiate, elementType) as EnumerableSpec, + PopulationCastType = ConstructGenericCollectionSpecIfRequired(populationCastType, elementType) as EnumerableSpec, }; - Debug.Assert(!(populationStrategy is CollectionPopulationStrategy.Cast_Then_Add && populationCastType is null)); - spec.ConcreteType = ConstructGenericCollectionSpecIfRequired(concreteType, elementType); - spec.PopulationCastType = ConstructGenericCollectionSpecIfRequired(populationCastType, elementType); - return spec; } - private ObjectSpec? CreateObjectSpec(INamedTypeSymbol type) + private ObjectSpec? CreateObjectSpec(INamedTypeSymbol objectSymbol) { // Add spec to cache before traversing properties to avoid stack overflow. - ObjectSpec objectSpec = new(type); - _createdSpecs.Add(type, objectSpec); + ObjectSpec objectSpec = new(objectSymbol); + _createdSpecs.Add(objectSymbol, objectSpec); string typeName = objectSpec.Name; IMethodSymbol? ctor = null; - DiagnosticDescriptor? diagnosticDescriptor = null; + DiagnosticDescriptor? initDiagDescriptor = null; - if (!(type.IsAbstract || type.TypeKind is TypeKind.Interface)) + if (!(objectSymbol.IsAbstract || objectSymbol.TypeKind is TypeKind.Interface)) { IMethodSymbol? parameterlessCtor = null; IMethodSymbol? parameterizedCtor = null; bool hasMultipleParameterizedCtors = false; - foreach (IMethodSymbol candidate in type.InstanceConstructors) + foreach (IMethodSymbol candidate in objectSymbol.InstanceConstructors) { if (candidate.DeclaredAccessibility is not Accessibility.Public) { @@ -618,35 +595,36 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol k } } - bool hasPublicParameterlessCtor = type.IsValueType || parameterlessCtor is not null; + bool hasPublicParameterlessCtor = objectSymbol.IsValueType || parameterlessCtor is not null; if (!hasPublicParameterlessCtor && hasMultipleParameterizedCtors) { - diagnosticDescriptor = Diagnostics.MultipleParameterizedConstructors; + initDiagDescriptor = Diagnostics.MultipleParameterizedConstructors; objectSpec.InitExceptionMessage = string.Format(Emitter.ExceptionMessages.MultipleParameterizedConstructors, typeName); } - ctor = type.IsValueType + ctor = objectSymbol.IsValueType // Roslyn ctor fetching APIs include paramerterless ctors for structs, unlike System.Reflection. ? parameterizedCtor ?? parameterlessCtor : parameterlessCtor ?? parameterizedCtor; } - objectSpec.InitializationStrategy = ctor?.Parameters.Length is 0 ? InitializationStrategy.ParameterlessConstructor : InitializationStrategy.ParameterizedConstructor; - if (ctor is null) { - diagnosticDescriptor = Diagnostics.MissingPublicInstanceConstructor; + initDiagDescriptor = Diagnostics.MissingPublicInstanceConstructor; objectSpec.InitExceptionMessage = string.Format(Emitter.ExceptionMessages.MissingPublicInstanceConstructor, typeName); } + else + { + objectSpec.InstantiationStrategy = ctor.Parameters.Length is 0 ? InstantiationStrategy.ParameterlessConstructor : InstantiationStrategy.ParameterizedConstructor; + } - if (diagnosticDescriptor is not null) + if (initDiagDescriptor is not null) { Debug.Assert(objectSpec.InitExceptionMessage is not null); - RegisterUnsupportedType(type, diagnosticDescriptor); - return objectSpec; + RegisterUnsupportedType(objectSymbol, initDiagDescriptor); } - INamedTypeSymbol current = type; + INamedTypeSymbol current = objectSymbol; while (current is not null) { ImmutableArray members = current.GetMembers(); @@ -655,12 +633,12 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol k if (member is IPropertySymbol { IsIndexer: false, IsImplicitlyDeclared: false } property) { string propertyName = property.Name; - TypeSpec? propertyTypeSpec = GetOrCreateTypeSpec(property.Type); + TypeSpec propertyTypeSpec = GetOrCreateTypeSpec(property.Type); - if (propertyTypeSpec?.CanInitialize is not true) + if (propertyTypeSpec?.CanBindTo is not true) { - InvocationDiagnosticInfo propertyDiagnostic = new InvocationDiagnosticInfo(Diagnostics.PropertyNotSupported, new string[] { propertyName, type.ToDisplayString() }); - RegisterTypeDiagnostic(causingType: type, propertyDiagnostic); + InvocationDiagnosticInfo propertyDiagnostic = new InvocationDiagnosticInfo(Diagnostics.PropertyNotSupported, new string[] { propertyName, objectSymbol.ToDisplayString() }); + RegisterTypeDiagnostic(causingType: objectSymbol, propertyDiagnostic); _invocationTargetTypeDiags.Add(propertyDiagnostic); } @@ -668,8 +646,8 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol k { AttributeData? attributeData = property.GetAttributes().FirstOrDefault(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, _typeSymbols.ConfigurationKeyNameAttribute)); string configKeyName = attributeData?.ConstructorArguments.FirstOrDefault().Value as string ?? propertyName; - PropertySpec spec = new(property) { Type = propertyTypeSpec, ConfigurationKeyName = configKeyName }; + objectSpec.Properties[propertyName] = spec; Register_AsConfigWithChildren_HelperForGen_IfRequired(propertyTypeSpec); } @@ -678,7 +656,7 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol k current = current.BaseType; } - if (objectSpec.InitializationStrategy is InitializationStrategy.ParameterizedConstructor) + if (objectSpec.InstantiationStrategy is InstantiationStrategy.ParameterizedConstructor) { List missingParameters = new(); List invalidParameters = new(); @@ -714,9 +692,9 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol k } else if (missingParameters.Count > 0) { - if (type.IsValueType) + if (objectSymbol.IsValueType) { - objectSpec.InitializationStrategy = InitializationStrategy.ParameterlessConstructor; + objectSpec.InstantiationStrategy = InstantiationStrategy.ParameterlessConstructor; } else { @@ -724,7 +702,7 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol k } } - if (objectSpec.CanInitialize) + if (objectSpec.CanInstantiate) { RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.Initialize, objectSpec); } @@ -732,26 +710,25 @@ private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, ITypeSymbol k static string FormatParams(List names) => string.Join(",", names); } - Debug.Assert((objectSpec.CanInitialize && objectSpec.InitExceptionMessage is null) || - (!objectSpec.CanInitialize && objectSpec.InitExceptionMessage is not null)); - - if (objectSpec.NeedsMemberBinding) - { - RegisterTypeForBindCoreGen(objectSpec); - } + Debug.Assert((objectSpec.CanInstantiate && objectSpec.InitExceptionMessage is null) || + (!objectSpec.CanInstantiate && objectSpec.InitExceptionMessage is not null) || + (!objectSpec.CanInstantiate && (objectSymbol.IsAbstract || objectSymbol.TypeKind is TypeKind.Interface))); + TryRegisterTypeForBindCoreGen(objectSpec); return objectSpec; } - private void Register_AsConfigWithChildren_HelperForGen_IfRequired(TypeSpec type) + private bool MemberTypeIsBindable(ITypeSymbol containingTypeSymbol, ITypeSymbol memberTypeSymbol, DiagnosticDescriptor containingTypeDiagDescriptor, out TypeSpec? memberTypeSpec) { - if (type.SpecKind is TypeSpecKind.Object or - TypeSpecKind.Enumerable or - TypeSpecKind.Dictionary) + if (GetOrCreateTypeSpec(memberTypeSymbol) is TypeSpec { CanBindTo: true } spec) { - - _sourceGenSpec.MethodsToGen_CoreBindingHelper |= MethodsToGen_CoreBindingHelper.AsConfigWithChildren; + memberTypeSpec = spec; + return true; } + + RegisterUnsupportedType(containingTypeSymbol, containingTypeDiagDescriptor); + memberTypeSpec = null; + return false; } private bool TryGetElementType(INamedTypeSymbol type, out ITypeSymbol? elementType) @@ -794,6 +771,22 @@ private bool IsCandidateDictionary(INamedTypeSymbol type, out ITypeSymbol? keyTy private bool IsCollection(ITypeSymbol type) => type is INamedTypeSymbol namedType && GetInterface(namedType, _typeSymbols.IEnumerable) is not null; + private bool IsSupportedArrayType(ITypeSymbol type) + { + if (type is not IArrayTypeSymbol arrayType) + { + return false; + } + + if (arrayType.Rank > 1) + { + RegisterUnsupportedType(arrayType, Diagnostics.MultiDimArraysNotSupported); + return false; + } + + return true; + } + private static INamedTypeSymbol? GetInterface(INamedTypeSymbol type, INamedTypeSymbol @interface) { if (IsInterfaceMatch(type, @interface)) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/ConfigurationBinder.cs similarity index 94% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/ConfigurationBinder.cs index c420097d99d6ae..c4f128cffd6c1d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/ConfigurationBinder.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using SourceGenerators; +using System.Diagnostics; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { @@ -132,24 +132,20 @@ private void EmitBindMethods_ConfigurationBinder() void EmitMethods(MethodsToGen_ConfigurationBinder method, string additionalParams, string configExpression, bool configureOptions) { - foreach (KeyValuePair> pair in _sourceGenSpec.InterceptionInfo_ConfigBinder.GetOverloadInfo(method)) + foreach ((ComplexTypeSpec type, List interceptorInfoList) in _sourceGenSpec.InterceptionInfo_ConfigBinder.GetOverloadInfo(method)) { - (TypeSpec type, List interceptorInfoList) = (pair.Key, pair.Value); - EmitBlankLineIfRequired(); _writer.WriteLine($"/// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively."); EmitInterceptsLocationAnnotations(interceptorInfoList); EmitStartBlock($"public static void {Identifier.Bind}_{type.IdentifierCompatibleSubstring}(this {Identifier.IConfiguration} {Identifier.configuration}, {additionalParams})"); - if (type.NeedsMemberBinding) + if (type.HasBindableMembers) { + Debug.Assert(!type.IsValueType); string binderOptionsArg = configureOptions ? $"{Identifier.GetBinderOptions}({Identifier.configureOptions})" : $"{Identifier.binderOptions}: null"; EmitCheckForNullArgument_WithBlankLine(Identifier.configuration); - if (!type.IsValueType) - { - EmitCheckForNullArgument_WithBlankLine(Identifier.instance, voidReturn: true); - } + EmitCheckForNullArgument_WithBlankLine(Identifier.instance, voidReturn: true); _writer.WriteLine($$""" var {{Identifier.typedObj}} = ({{type.EffectiveType.DisplayString}}){{Identifier.instance}}; {{nameof(MethodsToGen_CoreBindingHelper.BindCore)}}({{configExpression}}, ref {{Identifier.typedObj}}, {{binderOptionsArg}}); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs similarity index 60% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs index 089095aa472d5b..7b698544c91514 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs @@ -5,8 +5,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Text.RegularExpressions; using Microsoft.CodeAnalysis; -using SourceGenerators; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { @@ -14,6 +14,10 @@ public sealed partial class ConfigurationBindingGenerator { private sealed partial class Emitter { + private int _valueSuffixIndex; + private bool _emitBlankLineBeforeNextStatement; + private static readonly Regex s_arrayBracketsRegex = new(Regex.Escape("[]")); + private bool ShouldEmitMethods(MethodsToGen_CoreBindingHelper methods) => (_sourceGenSpec.MethodsToGen_CoreBindingHelper & methods) != 0; private void EmitCoreBindingHelpers() @@ -82,36 +86,56 @@ private void EmitGetCoreMethod() EmitStartBlock($"{conditionKindExpr} ({Identifier.type} == typeof({type.DisplayString}))"); - if (effectiveType is ParsableFromStringSpec stringParsableType) + switch (effectiveType) { - _writer.WriteLine($$""" - if ({{Identifier.configuration}} is not {{Identifier.IConfigurationSection}} {{Identifier.section}}) + case ParsableFromStringSpec stringParsableType: { - throw new {{Identifier.InvalidOperationException}}(); + EmitCastToIConfigurationSection(); + EmitBindingLogic( + stringParsableType, + Expression.sectionValue, + Expression.sectionPath, + writeOnSuccess: parsedValueExpr => _writer.WriteLine($"return {parsedValueExpr};"), + checkForNullSectionValue: stringParsableType.StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue, + useIncrementalStringValueIdentifier: false); } - """); - - EmitBindLogicFromString( - stringParsableType, - Expression.sectionValue, - Expression.sectionPath, - writeOnSuccess: parsedValueExpr => _writer.WriteLine($"return {parsedValueExpr};"), - checkForNullSectionValue: stringParsableType.StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue, - useIncrementalStringValueIdentifier: false); - } - else if (!EmitInitException(effectiveType)) - { - EmitBindCoreCall(effectiveType, Identifier.instance, Identifier.configuration, InitializationKind.Declaration); - _writer.WriteLine($"return {Identifier.instance};"); + break; + case ConfigurationSectionSpec configurationSectionSpec: + { + EmitCastToIConfigurationSection(); + _writer.WriteLine($"return {Identifier.section};"); + } + break; + case ComplexTypeSpec complexType: + { + if (complexType.CanInstantiate) + { + EmitBindingLogic(complexType, Identifier.instance, Identifier.configuration, InitializationKind.Declaration); + _writer.WriteLine($"return {Identifier.instance};"); + } + else if (type is ObjectSpec { InitExceptionMessage: string exMsg }) + { + _writer.WriteLine($@"throw new {Identifier.InvalidOperationException}(""{exMsg}"");"); + } + } + break; } - EmitEndBlock(); + EmitEndBlock(); // End if-check for input type. } _writer.WriteLine(); Emit_NotSupportedException_TypeNotDetectedAsInput(); EmitEndBlock(); _emitBlankLineBeforeNextStatement = true; + + void EmitCastToIConfigurationSection() => + _writer.WriteLine($$""" + if ({{Identifier.configuration}} is not {{Identifier.IConfigurationSection}} {{Identifier.section}}) + { + throw new {{Identifier.InvalidOperationException}}(); + } + """); } private void EmitGetValueCoreMethod() @@ -143,7 +167,7 @@ private void EmitGetValueCoreMethod() string conditionKindExpr = GetConditionKindExpr(ref isFirstType); EmitStartBlock($"{conditionKindExpr} ({Identifier.type} == typeof({type.DisplayString}))"); - EmitBindLogicFromString( + EmitBindingLogic( (ParsableFromStringSpec)type.EffectiveType, Identifier.value, Expression.sectionPath, @@ -175,18 +199,16 @@ private void EmitBindCoreMainMethod() _writer.WriteLine(); bool isFirstType = true; - foreach (TypeSpec type in targetTypes) + foreach (ComplexTypeSpec type in targetTypes) { - TypeSpec effectiveType = type.EffectiveType; + ComplexTypeSpec effectiveType = (ComplexTypeSpec)type.EffectiveType; + Debug.Assert(effectiveType.HasBindableMembers); string conditionKindExpr = GetConditionKindExpr(ref isFirstType); EmitStartBlock($"{conditionKindExpr} ({Identifier.type} == typeof({type.DisplayString}))"); - if (!EmitInitException(effectiveType)) - { - _writer.WriteLine($"var {Identifier.temp} = ({effectiveType.DisplayString}){Identifier.instance};"); - EmitBindCoreCall(type, Identifier.temp, Identifier.configuration, InitializationKind.None); - _writer.WriteLine($"return;"); - } + _writer.WriteLine($"var {Identifier.temp} = ({effectiveType.DisplayString}){Identifier.instance};"); + EmitBindingLogic(type, Identifier.temp, Identifier.configuration, InitializationKind.None); + _writer.WriteLine($"return;"); EmitEndBlock(); } @@ -202,23 +224,23 @@ private void EmitBindCoreMethods() return; } - foreach (TypeSpec type in targetTypes) + foreach (ComplexTypeSpec type in targetTypes) { - Debug.Assert(type.NeedsMemberBinding); + Debug.Assert(type.HasBindableMembers); EmitBlankLineIfRequired(); EmitBindCoreMethod(type); } } - private void EmitBindCoreMethod(TypeSpec type) + private void EmitBindCoreMethod(ComplexTypeSpec type) { string objParameterExpression = $"ref {type.DisplayString} {Identifier.instance}"; EmitStartBlock(@$"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCore)}({Identifier.IConfiguration} {Identifier.configuration}, {objParameterExpression}, {Identifier.BinderOptions}? {Identifier.binderOptions})"); - TypeSpec effectiveType = type.EffectiveType; + ComplexTypeSpec effectiveType = (ComplexTypeSpec)type.EffectiveType; if (effectiveType is EnumerableSpec enumerable) { - if (effectiveType.InitializationStrategy is InitializationStrategy.Array) + if (effectiveType.InstantiationStrategy is InstantiationStrategy.Array) { Debug.Assert(type == effectiveType); EmitPopulationImplForArray((EnumerableSpec)type); @@ -256,7 +278,7 @@ private void EmitInitializeMethods() private void EmitInitializeMethod(ObjectSpec type) { - Debug.Assert(type.CanInitialize); + Debug.Assert(type.CanInstantiate); List ctorParams = type.ConstructorParameters; IEnumerable initOnlyProps = type.Properties.Values.Where(prop => prop is { SetOnInit: true }); List ctorArgList = new(); @@ -283,7 +305,7 @@ private void EmitInitializeMethod(ObjectSpec type) foreach (PropertySpec property in initOnlyProps) { - if (property.ShouldBind() && property.MatchingCtorParam is null) + if (property.ShouldBindTo && property.MatchingCtorParam is null) { EmitBindImplForMember(property); } @@ -314,47 +336,47 @@ void EmitBindImplForMember(MemberSpec member) TypeSpec memberType = member.Type; bool errorOnFailedBinding = member.ErrorOnFailedBinding; - string parsedMemberIdentifierDeclarationPrefix = $"{memberType.DisplayString} {member.Name}"; - string parsedMemberIdentifier; + string parsedMemberDeclarationLhs = $"{memberType.DisplayString} {member.Name}"; + string configKeyName = member.ConfigurationKeyName; + string parsedMemberAssignmentLhsExpr; - if (memberType is ParsableFromStringSpec { StringParsableTypeKind: StringParsableTypeKind.AssignFromSectionValue }) + switch (memberType) { - parsedMemberIdentifier = parsedMemberIdentifierDeclarationPrefix; + case ParsableFromStringSpec { StringParsableTypeKind: StringParsableTypeKind.AssignFromSectionValue }: + { + if (errorOnFailedBinding) + { + string condition = $@"if ({Identifier.configuration}[""{configKeyName}""] is not {parsedMemberDeclarationLhs})"; + EmitThrowBlock(condition); + _writer.WriteLine(); + return; + } - if (errorOnFailedBinding) - { - string condition = $@" if ({Identifier.configuration}[""{member.ConfigurationKeyName}""] is not {memberType.DisplayString} {member.Name})"; - EmitThrowBlock(condition); - _writer.WriteLine(); - return; - } - } - else - { - parsedMemberIdentifier = member.Name; + parsedMemberAssignmentLhsExpr = parsedMemberDeclarationLhs; + } + break; + case ConfigurationSectionSpec: + { + _writer.WriteLine($"{parsedMemberDeclarationLhs} = {GetSectionFromConfigurationExpression(configKeyName)};"); + return; + } + default: + { + string bangExpr = memberType.IsValueType ? string.Empty : "!"; + string parsedMemberIdentifierDeclaration = $"{parsedMemberDeclarationLhs} = {member.DefaultValueExpr}{bangExpr};"; - string declarationSuffix; - if (errorOnFailedBinding) - { - declarationSuffix = ";"; - } - else - { - string bangExpr = memberType.IsValueType ? string.Empty : "!"; - declarationSuffix = memberType.CanInitialize - ? $" = {member.DefaultValueExpr}{bangExpr};" - : ";"; - } + _writer.WriteLine(parsedMemberIdentifierDeclaration); + _emitBlankLineBeforeNextStatement = false; - string parsedMemberIdentifierDeclaration = $"{parsedMemberIdentifierDeclarationPrefix}{declarationSuffix}"; - _writer.WriteLine(parsedMemberIdentifierDeclaration); - _emitBlankLineBeforeNextStatement = false; + parsedMemberAssignmentLhsExpr = member.Name; + } + break; } bool canBindToMember = this.EmitBindImplForMember( member, - parsedMemberIdentifier, - sectionPathExpr: GetSectionPathFromConfigurationExpression(member.ConfigurationKeyName), + parsedMemberAssignmentLhsExpr, + sectionPathExpr: GetSectionPathFromConfigurationExpression(configKeyName), canSet: true); if (canBindToMember) @@ -607,11 +629,11 @@ private void EmitPrimitiveParseMethod(ParsableFromStringSpec type) private void EmitPopulationImplForArray(EnumerableSpec type) { - EnumerableSpec concreteType = (EnumerableSpec)type.ConcreteType; + EnumerableSpec typeToInstantiate = (EnumerableSpec)type.TypeToInstantiate; // Create list and bind elements. string tempIdentifier = GetIncrementalIdentifier(Identifier.temp); - EmitBindCoreCall(concreteType, tempIdentifier, Identifier.configuration, InitializationKind.Declaration); + EmitBindingLogic(typeToInstantiate, tempIdentifier, Identifier.configuration, InitializationKind.Declaration); // Resize array and add binded elements. _writer.WriteLine($$""" @@ -627,22 +649,32 @@ private void EmitPopulationImplForEnumerableWithAdd(EnumerableSpec type) Emit_Foreach_Section_In_ConfigChildren_StartBlock(); - TypeSpec elementType = type.ElementType; + string addExpr = $"{instanceIdentifier}.{Identifier.Add}"; - if (elementType is ParsableFromStringSpec stringParsableType) - { - EmitBindLogicFromString( - stringParsableType, - Expression.sectionValue, - Expression.sectionPath, - (parsedValueExpr) => _writer.WriteLine($"{instanceIdentifier}.{Identifier.Add}({parsedValueExpr});"), - checkForNullSectionValue: true, - useIncrementalStringValueIdentifier: false); - } - else + switch (type.ElementType) { - EmitBindCoreCall(elementType, Identifier.value, Identifier.section, InitializationKind.Declaration); - _writer.WriteLine($"{instanceIdentifier}.{Identifier.Add}({Identifier.value});"); + case ParsableFromStringSpec stringParsableType: + { + EmitBindingLogic( + stringParsableType, + Expression.sectionValue, + Expression.sectionPath, + (parsedValueExpr) => _writer.WriteLine($"{addExpr}({parsedValueExpr});"), + checkForNullSectionValue: true, + useIncrementalStringValueIdentifier: false); + } + break; + case ConfigurationSectionSpec configurationSection: + { + _writer.WriteLine($"{addExpr}({Identifier.section});"); + } + break; + case ComplexTypeSpec { CanInstantiate: true } complexType: + { + EmitBindingLogic(complexType, Identifier.value, Identifier.section, InitializationKind.Declaration); + _writer.WriteLine($"{addExpr}({Identifier.value});"); + } + break; } EmitEndBlock(); @@ -658,7 +690,7 @@ private void EmitBindCoreImplForDictionary(DictionarySpec type) TypeSpec elementType = type.ElementType; // Parse key - EmitBindLogicFromString( + EmitBindingLogic( keyType, Expression.sectionKey, Expression.sectionPath, @@ -668,63 +700,56 @@ private void EmitBindCoreImplForDictionary(DictionarySpec type) void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr) { - if (elementType is ParsableFromStringSpec stringParsableElementType) - { - EmitBindLogicFromString( - stringParsableElementType, - Expression.sectionValue, - Expression.sectionPath, - writeOnSuccess: parsedValueExpr => _writer.WriteLine($"{instanceIdentifier}[{parsedKeyExpr}] = {parsedValueExpr};"), - checkForNullSectionValue: true, - useIncrementalStringValueIdentifier: false); - } - else // For complex types: + switch (elementType) { - Debug.Assert(elementType.CanInitialize); - - if (keyType.StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue) - { - // Save value to local to avoid parsing twice - during look-up and during add. - _writer.WriteLine($"{keyType.DisplayString} {Identifier.key} = {parsedKeyExpr};"); - parsedKeyExpr = Identifier.key; - } - - bool isValueType = elementType.IsValueType; - string expressionForElementIsNotNull = $"{Identifier.element} is not null"; - string elementTypeDisplayString = elementType.DisplayString + (elementType.IsValueType ? string.Empty : "?"); - - string expressionForElementExists = $"{instanceIdentifier}.{Identifier.TryGetValue}({parsedKeyExpr}, out {elementTypeDisplayString} {Identifier.element})"; - string conditionToUseExistingElement = expressionForElementExists; - - // If key already exists, bind to existing element instance if not null (for ref types). - if (!isValueType) - { - conditionToUseExistingElement += $" && {expressionForElementIsNotNull}"; - } + case ParsableFromStringSpec stringParsableElementType: + { + EmitBindingLogic( + stringParsableElementType, + Expression.sectionValue, + Expression.sectionPath, + writeOnSuccess: parsedValueExpr => _writer.WriteLine($"{instanceIdentifier}[{parsedKeyExpr}] = {parsedValueExpr};"), + checkForNullSectionValue: true, + useIncrementalStringValueIdentifier: false); + } + break; + case ConfigurationSectionSpec configurationSection: + { + _writer.WriteLine($"{instanceIdentifier}[{parsedKeyExpr}] = {Identifier.section};"); + } + break; + case ComplexTypeSpec complexElementType: + { + Debug.Assert(complexElementType.CanInstantiate); - EmitStartBlock($"if (!({conditionToUseExistingElement}))"); - EmitObjectInit(elementType, Identifier.element, InitializationKind.SimpleAssignment, Identifier.section); - EmitEndBlock(); + if (keyType.StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue) + { + // Save value to local to avoid parsing twice - during look-up and during add. + _writer.WriteLine($"{keyType.DisplayString} {Identifier.key} = {parsedKeyExpr};"); + parsedKeyExpr = Identifier.key; + } - if (elementType is CollectionSpec { InitializationStrategy: InitializationStrategy.ParameterizedConstructor or InitializationStrategy.ToEnumerableMethod } collectionSpec) - { - // This is a read-only collection. If the element exists and is not null, - // we need to copy its contents into a new instance & then append/bind to that. + bool isValueType = complexElementType.IsValueType; + string expressionForElementIsNotNull = $"{Identifier.element} is not null"; + string elementTypeDisplayString = complexElementType.DisplayString + (complexElementType.IsValueType ? string.Empty : "?"); - string initExpression = collectionSpec.InitializationStrategy is InitializationStrategy.ParameterizedConstructor - ? $"new {collectionSpec.ConcreteType.DisplayString}({Identifier.element})" - : $"{Identifier.element}.{collectionSpec.ToEnumerableMethodCall!}"; + string expressionForElementExists = $"{instanceIdentifier}.{Identifier.TryGetValue}({parsedKeyExpr}, out {elementTypeDisplayString} {Identifier.element})"; + string conditionToUseExistingElement = expressionForElementExists; - _writer.WriteLine($$""" - else + // If key already exists, bind to existing element instance if not null (for ref types). + if (!isValueType) { - {{Identifier.element}} = {{initExpression}}; + conditionToUseExistingElement += $" && {expressionForElementIsNotNull}"; } - """); - } - EmitBindCoreCall(elementType, Identifier.element, Identifier.section, InitializationKind.None); - _writer.WriteLine($"{instanceIdentifier}[{parsedKeyExpr}] = {Identifier.element};"); + EmitStartBlock($"if (!({conditionToUseExistingElement}))"); + EmitObjectInit(complexElementType, Identifier.element, InitializationKind.SimpleAssignment, Identifier.section); + EmitEndBlock(); + + EmitBindingLogic(complexElementType, Identifier.element, Identifier.section, InitializationKind.None); + _writer.WriteLine($"{instanceIdentifier}[{parsedKeyExpr}] = {Identifier.element};"); + } + break; } } @@ -733,7 +758,7 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr) private void EmitBindCoreImplForObject(ObjectSpec type) { - Debug.Assert(type.NeedsMemberBinding); + Debug.Assert(type.HasBindableMembers); string keyCacheFieldName = GetConfigKeyCacheFieldName(type); string validateMethodCallExpr = $"{Identifier.ValidateConfigurationKeys}(typeof({type.DisplayString}), {keyCacheFieldName}, {Identifier.configuration}, {Identifier.binderOptions});"; @@ -741,8 +766,8 @@ private void EmitBindCoreImplForObject(ObjectSpec type) foreach (PropertySpec property in type.Properties.Values) { - bool noSetter_And_IsReadonly = !property.CanSet && property.Type is CollectionSpec { InitializationStrategy: InitializationStrategy.ParameterizedConstructor }; - if (property.ShouldBind() && !noSetter_And_IsReadonly) + bool noSetter_And_IsReadonly = !property.CanSet && property.Type is CollectionSpec { InstantiationStrategy: InstantiationStrategy.ParameterizedConstructor }; + if (property.ShouldBindTo && !noSetter_And_IsReadonly) { string containingTypeRef = property.IsStatic ? type.DisplayString : Identifier.instance; EmitBindImplForMember( @@ -761,56 +786,60 @@ private bool EmitBindImplForMember( bool canSet) { TypeSpec effectiveMemberType = member.Type.EffectiveType; - - if (effectiveMemberType is ParsableFromStringSpec stringParsableType) - { - if (canSet) - { - bool checkForNullSectionValue = member is ParameterSpec - ? true - : stringParsableType.StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue; - - string nullBangExpr = checkForNullSectionValue ? string.Empty : "!"; - - EmitBlankLineIfRequired(); - EmitBindLogicFromString( - stringParsableType, - $@"{Identifier.configuration}[""{member.ConfigurationKeyName}""]", - sectionPathExpr, - writeOnSuccess: parsedValueExpr => _writer.WriteLine($"{memberAccessExpr} = {parsedValueExpr}{nullBangExpr};"), - checkForNullSectionValue, - useIncrementalStringValueIdentifier: true); - } - - return true; - } - string sectionParseExpr = GetSectionFromConfigurationExpression(member.ConfigurationKeyName); - EmitBlankLineIfRequired(); - - if (effectiveMemberType.SpecKind is TypeSpecKind.IConfigurationSection) + switch (effectiveMemberType) { - _writer.WriteLine($"{memberAccessExpr} = {sectionParseExpr};"); - return true; - } + case ParsableFromStringSpec stringParsableType: + { + if (canSet) + { + bool checkForNullSectionValue = member is ParameterSpec + ? true + : stringParsableType.StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue; + + string nullBangExpr = checkForNullSectionValue ? string.Empty : "!"; + + EmitBlankLineIfRequired(); + EmitBindingLogic( + stringParsableType, + $@"{Identifier.configuration}[""{member.ConfigurationKeyName}""]", + sectionPathExpr, + writeOnSuccess: parsedValueExpr => _writer.WriteLine($"{memberAccessExpr} = {parsedValueExpr}{nullBangExpr};"), + checkForNullSectionValue, + useIncrementalStringValueIdentifier: true); + } - string sectionValidationCall = $"{MethodsToGen_CoreBindingHelper.AsConfigWithChildren}({sectionParseExpr})"; - string sectionIdentifier = GetIncrementalIdentifier(Identifier.section); + return true; + } + case ConfigurationSectionSpec: + { + if (canSet) + { + EmitBlankLineIfRequired(); + _writer.WriteLine($"{memberAccessExpr} = {sectionParseExpr};"); + } - EmitStartBlock($"if ({sectionValidationCall} is {Identifier.IConfigurationSection} {sectionIdentifier})"); + return true; + } + case ComplexTypeSpec complexType: + { + string sectionValidationCall = $"{MethodsToGen_CoreBindingHelper.AsConfigWithChildren}({sectionParseExpr})"; + string sectionIdentifier = GetIncrementalIdentifier(Identifier.section); - bool canInit = !EmitInitException(effectiveMemberType); - if (canInit) - { - EmitBindCoreCallForMember(member, memberAccessExpr, sectionIdentifier, canSet); - } + EmitBlankLineIfRequired(); + EmitStartBlock($"if ({sectionValidationCall} is {Identifier.IConfigurationSection} {sectionIdentifier})"); + EmitBindingLogicForComplexMember(member, memberAccessExpr, sectionIdentifier, canSet); + EmitEndBlock(); - EmitEndBlock(); - return canInit; + return complexType.CanInstantiate; + } + default: + return false; + } } - private void EmitBindCoreCallForMember( + private void EmitBindingLogicForComplexMember( MemberSpec member, string memberAccessExpr, string configArgExpr, @@ -818,7 +847,7 @@ private void EmitBindCoreCallForMember( { TypeSpec memberType = member.Type; - TypeSpec effectiveMemberType = memberType.EffectiveType; + ComplexTypeSpec effectiveMemberType = (ComplexTypeSpec)memberType.EffectiveType; string tempIdentifier = GetIncrementalIdentifier(Identifier.temp); InitializationKind initKind; @@ -872,7 +901,7 @@ private void EmitBindCoreCallForMember( } }; - EmitBindCoreCall( + EmitBindingLogic( effectiveMemberType, targetObjAccessExpr, configArgExpr, @@ -880,6 +909,205 @@ private void EmitBindCoreCallForMember( writeOnSuccess); } + private void EmitBindingLogic( + ComplexTypeSpec type, + string memberAccessExpr, + string configArgExpr, + InitializationKind initKind, + Action? writeOnSuccess = null) + { + if (!type.HasBindableMembers) + { + if (initKind is not InitializationKind.None) + { + if (type.CanInstantiate) + { + EmitObjectInit(type, memberAccessExpr, initKind, configArgExpr); + } + else if (type is ObjectSpec { InitExceptionMessage: string exMsg }) + { + _writer.WriteLine($@"throw new {Identifier.InvalidOperationException}(""{exMsg}"");"); + } + } + + return; + } + + string tempIdentifier = GetIncrementalIdentifier(Identifier.temp); + if (initKind is InitializationKind.AssignmentWithNullCheck) + { + Debug.Assert(!type.IsValueType); + _writer.WriteLine($"{type.DisplayString}? {tempIdentifier} = {memberAccessExpr};"); + EmitBindingLogic(tempIdentifier, InitializationKind.AssignmentWithNullCheck); + } + else if (initKind is InitializationKind.None && type.IsValueType) + { + EmitBindingLogic(tempIdentifier, InitializationKind.Declaration); + _writer.WriteLine($"{memberAccessExpr} = {tempIdentifier};"); + } + else + { + EmitBindingLogic(memberAccessExpr, initKind); + } + + void EmitBindingLogic(string instanceToBindExpr, InitializationKind initKind) + { + string bindCoreCall = $@"{nameof(MethodsToGen_CoreBindingHelper.BindCore)}({configArgExpr}, ref {instanceToBindExpr}, {Identifier.binderOptions});"; + + if (type.CanInstantiate) + { + if (initKind is not InitializationKind.None) + { + EmitObjectInit(type, instanceToBindExpr, initKind, configArgExpr); + } + + EmitBindCoreCall(); + } + else + { + Debug.Assert(!type.IsValueType); + + if (type is ObjectSpec { InitExceptionMessage: string exMsg }) + { + _writer.WriteLine($@"throw new {Identifier.InvalidOperationException}(""{exMsg}"");"); + } + else + { + EmitStartBlock($"if ({instanceToBindExpr} is not null)"); + EmitBindCoreCall(); + EmitEndBlock(); + } + } + + void EmitBindCoreCall() + { + _writer.WriteLine(bindCoreCall); + writeOnSuccess?.Invoke(instanceToBindExpr); + } + } + } + + private void EmitBindingLogic( + ParsableFromStringSpec type, + string sectionValueExpr, + string sectionPathExpr, + Action? writeOnSuccess, + bool checkForNullSectionValue, + bool useIncrementalStringValueIdentifier) + { + StringParsableTypeKind typeKind = type.StringParsableTypeKind; + Debug.Assert(typeKind is not StringParsableTypeKind.None); + + string nonNull_StringValue_Identifier = useIncrementalStringValueIdentifier ? GetIncrementalIdentifier(Identifier.value) : Identifier.value; + string stringValueToParse_Expr = checkForNullSectionValue ? nonNull_StringValue_Identifier : sectionValueExpr; + string parsedValueExpr = typeKind switch + { + StringParsableTypeKind.AssignFromSectionValue => stringValueToParse_Expr, + StringParsableTypeKind.Enum => $"ParseEnum<{type.DisplayString}>({stringValueToParse_Expr}, () => {sectionPathExpr})", + _ => $"{type.ParseMethodName}({stringValueToParse_Expr}, () => {sectionPathExpr})", + }; + + if (!checkForNullSectionValue) + { + InvokeWriteOnSuccess(); + } + else + { + EmitStartBlock($"if ({sectionValueExpr} is string {nonNull_StringValue_Identifier})"); + InvokeWriteOnSuccess(); + EmitEndBlock(); + } + + void InvokeWriteOnSuccess() => writeOnSuccess?.Invoke(parsedValueExpr); + } + + private bool EmitObjectInit(ComplexTypeSpec type, string memberAccessExpr, InitializationKind initKind, string configArgExpr) + { + CollectionSpec? collectionType = type as CollectionSpec; + string initExpr; + + string effectiveDisplayString = type.DisplayString; + if (collectionType is not null) + { + if (collectionType is EnumerableSpec { InstantiationStrategy: InstantiationStrategy.Array }) + { + initExpr = $"new {s_arrayBracketsRegex.Replace(effectiveDisplayString, "[0]", 1)}"; + } + else + { + effectiveDisplayString = (collectionType.TypeToInstantiate ?? collectionType).DisplayString; + initExpr = $"new {effectiveDisplayString}()"; + } + } + else if (type.InstantiationStrategy is InstantiationStrategy.ParameterlessConstructor) + { + initExpr = $"new {effectiveDisplayString}()"; + } + else + { + Debug.Assert(type.InstantiationStrategy is InstantiationStrategy.ParameterizedConstructor); + string initMethodIdentifier = GetInitalizeMethodDisplayString(((ObjectSpec)type)); + initExpr = $"{initMethodIdentifier}({configArgExpr}, {Identifier.binderOptions})"; + } + + switch (initKind) + { + case InitializationKind.Declaration: + { + Debug.Assert(!memberAccessExpr.Contains(".")); + _writer.WriteLine($"var {memberAccessExpr} = {initExpr};"); + } + break; + case InitializationKind.AssignmentWithNullCheck: + { + if (collectionType is CollectionSpec + { + InstantiationStrategy: InstantiationStrategy.ParameterizedConstructor or InstantiationStrategy.ToEnumerableMethod + }) + { + if (collectionType.InstantiationStrategy is InstantiationStrategy.ParameterizedConstructor) + { + _writer.WriteLine($"{memberAccessExpr} = {memberAccessExpr} is null ? {initExpr} : new {effectiveDisplayString}({memberAccessExpr});"); + } + else + { + Debug.Assert(collectionType is DictionarySpec); + _writer.WriteLine($"{memberAccessExpr} = {memberAccessExpr} is null ? {initExpr} : {memberAccessExpr}.ToDictionary(pair => pair.Key, pair => pair.Value);"); + } + } + else + { + _writer.WriteLine($"{memberAccessExpr} ??= {initExpr};"); + } + } + break; + case InitializationKind.SimpleAssignment: + { + _writer.WriteLine($"{memberAccessExpr} = {initExpr};"); + } + break; + default: + { + Debug.Fail($"Invaild initialization kind: {initKind}"); + } + break; + } + + return true; + } + + private void EmitIConfigurationHasValueOrChildrenCheck(bool voidReturn) + { + string returnPostfix = voidReturn ? string.Empty : " null"; + _writer.WriteLine($$""" + if (!{{Identifier.HasValueOrChildren}}({{Identifier.configuration}})) + { + return{{returnPostfix}}; + } + """); + _writer.WriteLine(); + } + private void EmitCollectionCastIfRequired(CollectionSpec type, out string instanceIdentifier) { instanceIdentifier = Identifier.instance; diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ExceptionMessages.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/ExceptionMessages.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ExceptionMessages.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/ExceptionMessages.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/Helpers.cs similarity index 96% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/Helpers.cs index fe59e46f73fc0b..8bac0f4f5af03d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/Helpers.cs @@ -12,10 +12,10 @@ public sealed partial class ConfigurationBindingGenerator { private sealed partial class Emitter { - private string? _emittedExtsTargetType; - internal static readonly AssemblyName s_assemblyName = typeof(ConfigurationBindingGenerator).Assembly.GetName(); + private string? _emittedExtsTargetType; + private enum InitializationKind { None = 0, @@ -23,6 +23,7 @@ private enum InitializationKind AssignmentWithNullCheck = 2, Declaration = 3, } + private static class Expression { public const string configurationGetSection = "configuration.GetSection"; @@ -229,19 +230,6 @@ private void EmitCheckForNullArgument_WithBlankLine(string paramName, bool voidR _writer.WriteLine(); } - private bool EmitInitException(TypeSpec type) - { - Debug.Assert(type.InitializationStrategy is not InitializationStrategy.None); - - if (!type.CanInitialize) - { - _writer.WriteLine($@"throw new {Identifier.InvalidOperationException}(""{type.InitExceptionMessage}"");"); - return true; - } - - return false; - } - private string GetIncrementalIdentifier(string prefix) => $"{prefix}{_valueSuffixIndex++}"; private static string GetInitalizeMethodDisplayString(ObjectSpec type) => diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/OptionsBuilderConfigurationExtensions.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/OptionsBuilderConfigurationExtensions.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/OptionsConfigurationServiceCollectionExtensions.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/OptionsConfigurationServiceCollectionExtensions.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj index f63ddec1f4b72e..92c4c04cfa67c9 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj @@ -30,31 +30,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ConfigurationSectionSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ConfigurationSectionSpec.cs deleted file mode 100644 index ed1fcac7636ba7..00000000000000 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ConfigurationSectionSpec.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis; - -namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration -{ - internal sealed record ConfigurationSectionSpec : TypeSpec - { - public ConfigurationSectionSpec(ITypeSymbol type) : base(type) { } - - public override TypeSpecKind SpecKind => TypeSpecKind.IConfigurationSection; - } -} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/InitializationStrategy.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/InitializationStrategy.cs deleted file mode 100644 index 866dd254e0181e..00000000000000 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/InitializationStrategy.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration -{ - internal enum InitializationStrategy - { - None = 0, - ParameterlessConstructor = 1, - ParameterizedConstructor = 2, - ToEnumerableMethod = 3, - Array = 4, - } -} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/BinderInvocation.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/BinderInvocation.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/BinderInvocation.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/BinderInvocation.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/ConfigurationBinder.cs similarity index 88% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/ConfigurationBinder.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/ConfigurationBinder.cs index bce30222493841..9feafd72ce7c59 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/ConfigurationBinder.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using Microsoft.CodeAnalysis.Operations; @@ -14,31 +13,29 @@ public sealed partial class ConfigurationBindingGenerator { private sealed partial class Parser { - private void RegisterMethodInvocation_ConfigurationBinder(BinderInvocation invocation) + private void ParseInvocation_ConfigurationBinder(BinderInvocation invocation) { switch (invocation.Operation.TargetMethod.Name) { case nameof(MethodsToGen_ConfigurationBinder.Bind): { - RegisterBindInvocation(invocation); + ParseBindInvocation_ConfigurationBinder(invocation); } break; case nameof(MethodsToGen_ConfigurationBinder.Get): { - RegisterGetInvocation(invocation); + ParseGetInvocation(invocation); } break; case nameof(MethodsToGen_ConfigurationBinder.GetValue): { - RegisterGetValueInvocation(invocation); + ParseGetValueInvocation(invocation); } break; - default: - return; } } - private void RegisterBindInvocation(BinderInvocation invocation) + private void ParseBindInvocation_ConfigurationBinder(BinderInvocation invocation) { IInvocationOperation operation = invocation.Operation!; ImmutableArray @params = operation.TargetMethod.Parameters; @@ -102,7 +99,7 @@ private void RegisterBindInvocation(BinderInvocation invocation) if (GetTargetTypeForRootInvocationCore(type, invocation.Location) is TypeSpec typeSpec) { - RegisterAsInterceptor_ConfigBinder_BindMethod(overload, typeSpec, invocation.Operation); + RegisterInterceptor(overload, typeSpec, invocation.Operation); } static ITypeSymbol? ResolveType(IOperation conversionOperation) => @@ -122,7 +119,7 @@ private void RegisterBindInvocation(BinderInvocation invocation) }; } - private void RegisterGetInvocation(BinderInvocation invocation) + private void ParseGetInvocation(BinderInvocation invocation) { IInvocationOperation operation = invocation.Operation!; IMethodSymbol targetMethod = operation.TargetMethod; @@ -176,13 +173,13 @@ private void RegisterGetInvocation(BinderInvocation invocation) if (GetTargetTypeForRootInvocation(type, invocation.Location) is TypeSpec typeSpec) { - RegisterAsInterceptor_ConfigBinder(overload, invocation.Operation); + RegisterInvocation(overload, invocation.Operation); RegisterTypeForGetCoreGen(typeSpec); } } - private void RegisterGetValueInvocation(BinderInvocation invocation) + private void ParseGetValueInvocation(BinderInvocation invocation) { IInvocationOperation operation = invocation.Operation!; IMethodSymbol targetMethod = operation.TargetMethod; @@ -245,23 +242,23 @@ private void RegisterGetValueInvocation(BinderInvocation invocation) if (IsParsableFromString(effectiveType, out _) && GetTargetTypeForRootInvocationCore(type, invocation.Location) is TypeSpec typeSpec) { - RegisterAsInterceptor_ConfigBinder(overload, invocation.Operation); + RegisterInvocation(overload, invocation.Operation); RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.GetValueCore, typeSpec); } } - private void RegisterAsInterceptor_ConfigBinder(MethodsToGen_ConfigurationBinder overload, IInvocationOperation operation) + private void RegisterInvocation(MethodsToGen_ConfigurationBinder overload, IInvocationOperation operation) { _sourceGenSpec.MethodsToGen_ConfigurationBinder |= overload; - RegisterAsInterceptor(overload, operation); + RegisterInterceptor(overload, operation); } /// /// Registers generated Bind methods as interceptors. This is done differently from other root - /// methods because we need to + /// methods because we need to /// explicitly account for the type to bind, to avoid type-check issues for polymorphic objects. /// - private void RegisterAsInterceptor_ConfigBinder_BindMethod(MethodsToGen_ConfigurationBinder overload, TypeSpec typeSpec, IInvocationOperation operation) + private void RegisterInterceptor(MethodsToGen_ConfigurationBinder overload, TypeSpec typeSpec, IInvocationOperation operation) { _sourceGenSpec.MethodsToGen_ConfigurationBinder |= overload; _sourceGenSpec.InterceptionInfo_ConfigBinder.RegisterOverloadInfo(overload, typeSpec, operation); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/Diagnostics.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/Diagnostics.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/Diagnostics.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/Diagnostics.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/Extensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/Extensions.cs similarity index 89% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/Extensions.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/Extensions.cs index 0ac57e88ed9ee5..fa0b3691ec4047 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/Extensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/Extensions.cs @@ -28,6 +28,12 @@ public static void RegisterCacheEntry(this Dictionary> source, out ComplexTypeSpec Key, out List Value) + { + Key = (ComplexTypeSpec)source.Key; + Value = source.Value; + } + public static string ToIdentifierCompatibleSubstring(this ITypeSymbol type) { if (type is IArrayTypeSymbol arrayType) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsBuilderConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsBuilderConfigurationExtensions.cs similarity index 77% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsBuilderConfigurationExtensions.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsBuilderConfigurationExtensions.cs index f65c67a7878b1a..9cf59a120e1fdc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsBuilderConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsBuilderConfigurationExtensions.cs @@ -12,7 +12,7 @@ public sealed partial class ConfigurationBindingGenerator { private sealed partial class Parser { - private void RegisterMethodInvocation_OptionsBuilderExt(BinderInvocation invocation) + private void ParseInvocation_OptionsBuilderExt(BinderInvocation invocation) { IMethodSymbol targetMethod = invocation.Operation.TargetMethod; ImmutableArray @params = targetMethod.Parameters; @@ -25,20 +25,18 @@ private void RegisterMethodInvocation_OptionsBuilderExt(BinderInvocation invocat return; } - ITypeSymbol? typeSymbol = targetMethod.TypeArguments[0].WithNullableAnnotation(NullableAnnotation.None); // This would violate generic type constraint; any such invocation could not have been included in the initial parser. Debug.Assert(typeSymbol?.IsValueType is not true); - TypeSpec typeSpec = GetTargetTypeForRootInvocation(typeSymbol, invocation.Location); - if (typeSpec is null) + if (GetTargetTypeForRootInvocation(typeSymbol, invocation.Location) is not ComplexTypeSpec typeSpec) { return; } if (targetMethod.Name is "Bind") { - RegisterBindInvocation(invocation, typeSpec); + ParseBindInvocation_OptionsBuilderExt(invocation, typeSpec); } else if (targetMethod.Name is "BindConfiguration") { @@ -46,7 +44,7 @@ private void RegisterMethodInvocation_OptionsBuilderExt(BinderInvocation invocat } } - private void RegisterBindInvocation(BinderInvocation invocation, TypeSpec typeSpec) + private void ParseBindInvocation_OptionsBuilderExt(BinderInvocation invocation, ComplexTypeSpec typeSpec) { IInvocationOperation operation = invocation.Operation!; IMethodSymbol targetMethod = operation.TargetMethod; @@ -68,14 +66,14 @@ 3 when SymbolEqualityComparer.Default.Equals(_typeSymbols.ActionOfBinderOptions, _ => MethodsToGen_Extensions_OptionsBuilder.None }; - if (overload is not MethodsToGen_Extensions_OptionsBuilder.None) + if (overload is not MethodsToGen_Extensions_OptionsBuilder.None && + TryRegisterTypeForMethodGen(MethodsToGen_Extensions_ServiceCollection.Configure_T_name_BinderOptions, typeSpec)) { - RegisterAsInterceptor_OptionsBuilder(overload, operation); - RegisterTypeForMethodGen(MethodsToGen_Extensions_ServiceCollection.Configure_T_name_BinderOptions, typeSpec); + RegisterInvocation(overload, operation); } } - private void ParseBindConfigurationInvocation(BinderInvocation invocation, TypeSpec typeSpec) + private void ParseBindConfigurationInvocation(BinderInvocation invocation, ComplexTypeSpec typeSpec) { IMethodSymbol targetMethod = invocation.Operation.TargetMethod; ImmutableArray @params = targetMethod.Parameters; @@ -85,17 +83,17 @@ private void ParseBindConfigurationInvocation(BinderInvocation invocation, TypeS if (paramCount is 3 && @params[1].Type.SpecialType is SpecialType.System_String && - SymbolEqualityComparer.Default.Equals(_typeSymbols.ActionOfBinderOptions, @params[2].Type)) + SymbolEqualityComparer.Default.Equals(_typeSymbols.ActionOfBinderOptions, @params[2].Type) && + TryRegisterTypeForBindCoreMainGen(typeSpec)) { - RegisterAsInterceptor_OptionsBuilder(MethodsToGen_Extensions_OptionsBuilder.BindConfiguration_T_path_BinderOptions, invocation.Operation); - RegisterTypeForBindCoreMainGen(typeSpec); + RegisterInvocation(MethodsToGen_Extensions_OptionsBuilder.BindConfiguration_T_path_BinderOptions, invocation.Operation); } } - private void RegisterAsInterceptor_OptionsBuilder(MethodsToGen_Extensions_OptionsBuilder overload, IInvocationOperation operation) + private void RegisterInvocation(MethodsToGen_Extensions_OptionsBuilder overload, IInvocationOperation operation) { _sourceGenSpec.MethodsToGen_OptionsBuilderExt |= overload; - RegisterAsInterceptor(overload, operation); + RegisterInterceptor(overload, operation); // Emitting refs to IOptionsChangeTokenSource, ConfigurationChangeTokenSource. _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.Options"); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsConfigurationServiceCollectionExtensions.cs similarity index 77% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsConfigurationServiceCollectionExtensions.cs index d89b124b0695fb..e86231f32e42ab 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Parser/OptionsConfigurationServiceCollectionExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsConfigurationServiceCollectionExtensions.cs @@ -12,7 +12,7 @@ public sealed partial class ConfigurationBindingGenerator { private sealed partial class Parser { - private void RegisterMethodInvocation_ServiceCollectionExt(BinderInvocation invocation) + private void ParseInvocation_ServiceCollectionExt(BinderInvocation invocation) { IInvocationOperation operation = invocation.Operation!; IMethodSymbol targetMethod = operation.TargetMethod; @@ -72,25 +72,26 @@ @params[1].Type.SpecialType is SpecialType.System_String && ITypeSymbol? typeSymbol = targetMethod.TypeArguments[0].WithNullableAnnotation(NullableAnnotation.None); // This would violate generic type constraint; any such invocation could not have been included in the initial parser. Debug.Assert(typeSymbol?.IsValueType is not true); - TypeSpec typeSpec = GetTargetTypeForRootInvocation(typeSymbol, invocation.Location); - if (typeSpec is null) + if (GetTargetTypeForRootInvocation(typeSymbol, invocation.Location) is ComplexTypeSpec typeSpec && + TryRegisterTypeForMethodGen(overload, typeSpec)) { - return; + RegisterInterceptor(overload, operation); } - - RegisterTypeForMethodGen(overload, typeSpec); - RegisterAsInterceptor(overload, operation); } - private void RegisterTypeForMethodGen(MethodsToGen_Extensions_ServiceCollection overload, TypeSpec typeSpec) + private bool TryRegisterTypeForMethodGen(MethodsToGen_Extensions_ServiceCollection overload, ComplexTypeSpec typeSpec) { - RegisterTypeForBindCoreMainGen(typeSpec); + if (TryRegisterTypeForBindCoreMainGen(typeSpec)) + { + _sourceGenSpec.MethodsToGen_ServiceCollectionExt |= overload; + _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.DependencyInjection"); + // Emitting refs to IOptionsChangeTokenSource, ConfigurationChangeTokenSource, IConfigureOptions<>, ConfigureNamedOptions<>. + _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.Options"); + return true; + } - _sourceGenSpec.MethodsToGen_ServiceCollectionExt |= overload; - _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.DependencyInjection"); - // Emitting refs to IOptionsChangeTokenSource, ConfigurationChangeTokenSource, IConfigureOptions<>, ConfigureNamedOptions<>. - _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.Options"); + return false; } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/InterceptorLocationInfo.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/InterceptorLocationInfo.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/InterceptorLocationInfo.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/InterceptorLocationInfo.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/KnownTypeSymbols.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/KnownTypeSymbols.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/KnownTypeSymbols.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/KnownTypeSymbols.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/MemberSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/MemberSpec.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/MemberSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/MemberSpec.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ParameterSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/ParameterSpec.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ParameterSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/ParameterSpec.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/PropertySpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/PropertySpec.cs similarity index 95% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/PropertySpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/PropertySpec.cs index 584e8d570b8a9f..4e9c468c4e3352 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/PropertySpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/PropertySpec.cs @@ -29,6 +29,6 @@ public PropertySpec(IPropertySymbol property) : base(property) public override bool CanSet { get; } - public bool ShouldBind() => CanGet || CanSet; + public bool ShouldBindTo => CanGet || CanSet; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/MethodsToGen.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/MethodsToGen.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/MethodsToGen.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/MethodsToGen.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/SourceGenerationSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/SourceGenerationSpec.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/SourceGenerationSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/SourceGenerationSpec.cs diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/CollectionSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/CollectionSpec.cs similarity index 64% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/CollectionSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/CollectionSpec.cs index 280ecc4c536482..f565d245cc5502 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/CollectionSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/CollectionSpec.cs @@ -5,25 +5,19 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { - internal abstract record CollectionSpec : TypeSpec + internal abstract record CollectionSpec : ComplexTypeSpec { public CollectionSpec(ITypeSymbol type) : base(type) { } - public required TypeSpec ElementType { get; init; } - - public CollectionSpec? ConcreteType { get; set; } + public sealed override bool CanInstantiate => TypeToInstantiate?.CanInstantiate ?? InstantiationStrategy is not InstantiationStrategy.None; - public CollectionSpec? PopulationCastType { get; set; } + public required TypeSpec ElementType { get; init; } public required CollectionPopulationStrategy PopulationStrategy { get; init; } - public override bool CanInitialize => ConcreteType?.CanInitialize ?? CanInitComplexObject(); - - public override required InitializationStrategy InitializationStrategy { get; set; } + public required CollectionSpec? TypeToInstantiate { get; init; } - public required string? ToEnumerableMethodCall { get; init; } - - public sealed override bool NeedsMemberBinding => true; + public required CollectionSpec? PopulationCastType { get; init; } } internal sealed record EnumerableSpec : CollectionSpec @@ -31,6 +25,8 @@ internal sealed record EnumerableSpec : CollectionSpec public EnumerableSpec(ITypeSymbol type) : base(type) { } public override TypeSpecKind SpecKind => TypeSpecKind.Enumerable; + + public override bool HasBindableMembers => PopulationStrategy is not CollectionPopulationStrategy.Unknown && ElementType.CanBindTo; } internal sealed record DictionarySpec : CollectionSpec @@ -39,6 +35,8 @@ public DictionarySpec(INamedTypeSymbol type) : base(type) { } public override TypeSpecKind SpecKind => TypeSpecKind.Dictionary; + public override bool HasBindableMembers => PopulationStrategy is not CollectionPopulationStrategy.Unknown; + public required ParsableFromStringSpec KeyType { get; init; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ComplexTypeSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ComplexTypeSpec.cs new file mode 100644 index 00000000000000..da5a5130141a53 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ComplexTypeSpec.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.CodeAnalysis; + +namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration +{ + internal abstract record ComplexTypeSpec : TypeSpec + { + public ComplexTypeSpec(ITypeSymbol type) : base(type) { } + + public InstantiationStrategy InstantiationStrategy { get; set; } + + public sealed override bool CanBindTo => CanInstantiate || HasBindableMembers; + + public sealed override TypeSpec EffectiveType => this; + + public abstract bool HasBindableMembers { get; } + } + + internal enum InstantiationStrategy + { + None = 0, + ParameterlessConstructor = 1, + ParameterizedConstructor = 2, + ToEnumerableMethod = 3, + Array = 4, + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/NullableSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/NullableSpec.cs similarity index 73% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/NullableSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/NullableSpec.cs index 9dcca27596e7ee..3de6d7d465ad98 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/NullableSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/NullableSpec.cs @@ -9,10 +9,11 @@ internal sealed record NullableSpec : TypeSpec { private readonly TypeSpec _underlyingType; - public NullableSpec(ITypeSymbol type, TypeSpec underlyingType) : base(type) - { - _underlyingType = underlyingType; - } + public NullableSpec(ITypeSymbol type, TypeSpec underlyingType) : base(type) => _underlyingType = underlyingType; + + public override bool CanBindTo => _underlyingType.CanBindTo; + + public override bool CanInstantiate => _underlyingType.CanInstantiate; public override TypeSpecKind SpecKind => TypeSpecKind.Nullable; diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ObjectSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ObjectSpec.cs similarity index 65% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ObjectSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ObjectSpec.cs index 09008dde159ad8..f6978fa9cf470a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ObjectSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ObjectSpec.cs @@ -8,20 +8,20 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { - internal sealed record ObjectSpec : TypeSpec + internal sealed record ObjectSpec : ComplexTypeSpec { public ObjectSpec(INamedTypeSymbol type) : base(type) { } public override TypeSpecKind SpecKind => TypeSpecKind.Object; - public override InitializationStrategy InitializationStrategy { get; set; } + public override bool HasBindableMembers => Properties.Values.Any(p => p.ShouldBindTo); - public override bool CanInitialize => CanInitComplexObject(); + public override bool CanInstantiate => InstantiationStrategy is not InstantiationStrategy.None && InitExceptionMessage is null; public Dictionary Properties { get; } = new(StringComparer.OrdinalIgnoreCase); public List ConstructorParameters { get; } = new(); - public override bool NeedsMemberBinding => Properties.Values.Any(p => p.ShouldBind()); + public string? InitExceptionMessage { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ParsableFromStringSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/SimpleTypeSpec.cs similarity index 71% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ParsableFromStringSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/SimpleTypeSpec.cs index e19e3e61d210f3..50e488008ad68d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/ParsableFromStringSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/SimpleTypeSpec.cs @@ -6,7 +6,25 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { - internal sealed record ParsableFromStringSpec : TypeSpec + internal abstract record SimpleTypeSpec : TypeSpec + { + public SimpleTypeSpec(ITypeSymbol type) : base(type) { } + + public sealed override bool CanBindTo => true; + + public sealed override TypeSpec EffectiveType => this; + + public sealed override bool CanInstantiate => true; + } + + internal sealed record ConfigurationSectionSpec : SimpleTypeSpec + { + public ConfigurationSectionSpec(ITypeSymbol type) : base(type) { } + + public override TypeSpecKind SpecKind => TypeSpecKind.IConfigurationSection; + } + + internal sealed record ParsableFromStringSpec : SimpleTypeSpec { public ParsableFromStringSpec(ITypeSymbol type) : base(type) { } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/TypeSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/TypeSpec.cs similarity index 78% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/TypeSpec.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/TypeSpec.cs index cf03e58e5231b1..651a40639f0ced 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Model/TypeSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/TypeSpec.cs @@ -1,10 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; using Microsoft.CodeAnalysis; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { + [DebuggerDisplay("Name={DisplayString}, Kind={SpecKind}")] internal abstract record TypeSpec { private static readonly SymbolDisplayFormat s_minimalDisplayFormat = new SymbolDisplayFormat( @@ -34,17 +36,11 @@ public TypeSpec(ITypeSymbol type) public abstract TypeSpecKind SpecKind { get; } - public virtual InitializationStrategy InitializationStrategy { get; set; } + public abstract bool CanBindTo { get; } - public virtual string? InitExceptionMessage { get; set; } + public abstract bool CanInstantiate { get; } - public virtual bool CanInitialize => true; - - public virtual bool NeedsMemberBinding { get; } - - public virtual TypeSpec EffectiveType => this; - - protected bool CanInitComplexObject() => InitializationStrategy is not InitializationStrategy.None && InitExceptionMessage is null; + public abstract TypeSpec EffectiveType { get; } } internal enum TypeSpecKind diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs index 76ed9d959e6220..e92ed061808740 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs @@ -3,10 +3,12 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.ComponentModel; using System.Globalization; -using System.Text.Json; using System.Linq; +using System.Net; +using System.Text.Json; using Microsoft.Extensions.Configuration; using Xunit; @@ -730,5 +732,69 @@ public record OidcProviderOptions { public string? Authority { get; set; } } + + public class AClass + { + public EndPointCollection EndPoints { get; init; } = new EndPointCollection(); + + public bool Property { get; set; } = false; + } + + public sealed class EndPointCollection : Collection, IEnumerable + { + public EndPointCollection() { } + + public void Add(string hostAndPort) + { + EndPoint? endpoint; + + if (IPAddress.TryParse(hostAndPort, out IPAddress? address)) + { + endpoint = new IPEndPoint(address, 0); + } + else + { + endpoint = new DnsEndPoint(hostAndPort, 0); + } + + Add(endpoint); + } + } + + internal abstract class AbstractBase + { + public int Value { get; set; } + } + + internal sealed class Derived : AbstractBase { } + + internal sealed class DerivedWithAnotherProp : AbstractBase + { + public int Value2 { get; set; } + } + + internal class ClassWithAbstractCtorParam + { + public AbstractBase AbstractProp { get; } + + public ClassWithAbstractCtorParam(AbstractBase abstractProp) => AbstractProp = abstractProp; + } + + internal class ClassWithOptionalAbstractCtorParam + { + public AbstractBase AbstractProp { get; } + + public ClassWithOptionalAbstractCtorParam(AbstractBase? abstractProp = null) => AbstractProp = abstractProp; + } + + internal class ClassWith_DirectlyAssignable_CtorParams + { + public IConfigurationSection MySection { get; } + public object MyObject { get; } + public string MyString { get; } + + public ClassWith_DirectlyAssignable_CtorParams(IConfigurationSection mySection, object myObject, string myString) => + (MySection, MyObject, MyString) = (mySection, myObject, myString); + } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs index 3846145f71486a..2a6006b38a2711 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs @@ -1940,12 +1940,17 @@ public void BindRootStructIsNoOp() } """); - StructWithNestedStructs.DeeplyNested obj = new(); #pragma warning disable SYSLIB1103 + StructWithNestedStructs.DeeplyNested obj = new(); configuration.Bind(obj); -#pragma warning restore SYSLIB1103 Assert.Equal(0, obj.Int32); Assert.False(obj.Boolean); + + StructWithNestedStructs.DeeplyNested? nullableObj = new(); + configuration.Bind(nullableObj); + Assert.Equal(0, obj.Int32); + Assert.False(obj.Boolean); +#pragma warning restore SYSLIB1103 } [Fact] @@ -2023,7 +2028,7 @@ public void ComplexObj_As_Dictionary_Element() [Fact] public void ComplexObj_As_Enumerable_Element() { - var configuration = TestHelpers.GetConfigurationFromJsonString("""{ "Enumerable": [{ "Latitude": 3, "Longitude": 4 }] }""") + var configuration = TestHelpers.GetConfigurationFromJsonString("""{ "Enumerable": [{ "Latitude": 3, "Longitude": 4 }] }""") .GetSection("Enumerable"); Geolocation obj = configuration.Get>()[0]; @@ -2192,5 +2197,129 @@ public void TestNullHandling_Bind() configuration.Bind(location, _ => { }); configuration.Bind("", location); } + + [Fact] + public void TestAbstractTypeAsNestedMemberForBinding() + { + // Regression test for https://github.com/dotnet/runtime/issues/91324. + + IConfiguration configuration = new ConfigurationBuilder().AddInMemoryCollection( + new KeyValuePair[] + { + new KeyValuePair("ConfigBindRepro:EndPoints:0", "localhost"), + new KeyValuePair("ConfigBindRepro:Property", "true") + }) + .Build(); + + AClass settings = new(); + configuration.GetSection("ConfigBindRepro").Bind(settings); + + Assert.Empty(settings.EndPoints); // Need custom binding feature to map "localhost" string into Endpoint instance. + Assert.True(settings.Property); + } + + [Fact] + public static void TestGettingAbstractType() + { + IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{""Value"":1}"); + Assert.Throws(() => configuration.Get()); + } + + [Fact] + public static void TestBindingAbstractInstance() + { + // Regression tests for https://github.com/dotnet/runtime/issues/90974. + // We only bind members on the declared binding type, i.e. AbstractBase, even + // though the actual instances are derived types that may have their own properties. + + IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{""Value"":1,""Value2"":2}"); + + AbstractBase d = new Derived(); + configuration.Bind(d); + Assert.Equal(1, d.Value); + + d = new DerivedWithAnotherProp(); + configuration.Bind(d); + Assert.Equal(1, d.Value); + +#if BUILDING_SOURCE_GENERATOR_TESTS + // Divergence from reflection impl: reflection binds using instance type, + // while src-gen can only use declared type (everything has to be known AOT). + // This could change if we add an explicit API to indicate the expected runtime type(s). + Assert.Equal(0, ((DerivedWithAnotherProp)d).Value2); +#else + Assert.Equal(2, ((DerivedWithAnotherProp)d).Value2); +#endif + } + + [Fact] + public static void TestBindingAbstractMember_AsCtorParam() + { + IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{ ""AbstractProp"": {""Value"":1} }"); + Assert.Throws(configuration.Get); + Assert.Throws(configuration.Get); + } + + [Fact] + public void GetIConfigurationSection() + { + var configuration = TestHelpers.GetConfigurationFromJsonString(""" + { + "vaLue": "MyString", + } + """); + + var obj = configuration.GetSection("value").Get(); + Assert.Equal("MyString", obj.Value); + + configuration = TestHelpers.GetConfigurationFromJsonString(""" + { + "vaLue": [ "MyString", { "nested": "value" } ], + } + """); + + var list = configuration.GetSection("value").Get>(); + ValidateList(list); + + var dict = configuration.Get>>(); + Assert.Equal(1, dict.Count); + ValidateList(dict["vaLue"]); + + static void ValidateList(List list) + { + Assert.Equal(2, list.Count); + Assert.Equal("0", list[0].Key); + Assert.Equal("MyString", list[0].Value); + + Assert.Equal("1", list[1].Key); + var nestedSection = Assert.IsAssignableFrom(list[1].GetSection("nested")); + Assert.Equal("value", nestedSection.Value); + } + } + + [Fact] + public void NullableDictKeys() + { + var configuration = TestHelpers.GetConfigurationFromJsonString("""{ "1": "MyString" }"""); + var dict = configuration.Get>(); + Assert.Empty(dict); + } + + [Fact] + public void IConfigurationSectionAsCtorParam() + { + var configuration = TestHelpers.GetConfigurationFromJsonString(""" + { + "MySection": "MySection", + "MyObject": "MyObject", + "MyString": "MyString", + } + """); + + var obj = configuration.Get(); + Assert.Equal("MySection", obj.MySection.Value); + Assert.Equal("MyObject", obj.MyObject); + Assert.Equal("MyString", obj.MyString); + } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_ParseTypeFromMethodParam.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_ParseTypeFromMethodParam.generated.txt new file mode 100644 index 00000000000000..14753a4a1f8e4b --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_ParseTypeFromMethodParam.generated.txt @@ -0,0 +1,72 @@ +// +#nullable enable +#pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. + +namespace System.Runtime.CompilerServices +{ + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } +} + +namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration +{ + using Microsoft.Extensions.Configuration; + using System; + using System.CodeDom.Compiler; + using System.Collections.Generic; + using System.Globalization; + using System.Runtime.CompilerServices; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + file static class BindingExtensions + { + #region IConfiguration extensions. + /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. + [InterceptsLocation(@"src-0.cs", 18, 16)] + public static void Bind_ProgramMyClass0(this IConfiguration configuration, object? instance) + { + } + + /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. + [InterceptsLocation(@"src-0.cs", 23, 16)] + public static void Bind_ProgramMyClass1(this IConfiguration configuration, object? instance, Action? configureOptions) + { + } + + /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. + [InterceptsLocation(@"src-0.cs", 28, 16)] + public static void Bind_ProgramMyClass2(this IConfiguration configuration, string key, object? instance) + { + } + #endregion IConfiguration extensions. + + #region Core binding extensions. + public static BinderOptions? GetBinderOptions(Action? configureOptions) + { + if (configureOptions is null) + { + return null; + } + + BinderOptions binderOptions = new(); + configureOptions(binderOptions); + + if (binderOptions.BindNonPublicProperties) + { + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + } + + return binderOptions; + } + #endregion Core binding extensions. + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs index 7b3251e7fc85dc..c48148c74c5891 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs @@ -117,6 +117,49 @@ public class MyClass2 { } await VerifyAgainstBaselineUsingFile("Bind_Key_Instance.generated.txt", source, extType: ExtensionClassType.ConfigurationBinder); } + [Fact] + public async Task Bind_CanParseTargetConfigType_FromMethodParam() + { + string source = """ + using System; + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfiguration config = configurationBuilder.Build(); + + BindOptions(config, new MyClass0()); + BindOptions(config, new MyClass1(), _ => { }); + BindOptions(config, "", new MyClass2()); + } + + private static void BindOptions(IConfiguration config, MyClass0 instance) + { + config.Bind(instance); + } + + private static void BindOptions(IConfiguration config, MyClass1 instance, Action? configureOptions) + { + config.Bind(instance, configureOptions); + } + + private static void BindOptions(IConfiguration config, string path, MyClass2 instance) + { + config.Bind(path, instance); + } + + public class MyClass0 { } + public class MyClass1 { } + public class MyClass2 { } + } + """; + + await VerifyAgainstBaselineUsingFile("Bind_ParseTypeFromMethodParam.generated.txt", source, extType: ExtensionClassType.ConfigurationBinder); + } + [Fact] public async Task Get() { @@ -622,5 +665,54 @@ await VerifyAgainstBaselineUsingFile("Collections.generated.txt", source, valida Assert.Equal(6, d.Where(diag => diag.Id == Diagnostics.PropertyNotSupported.Id).Count()); }); } + + [Fact] + public async Task MinimalGenerationIfNoBindableMembers() + { + string source = """ + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfiguration configuration = configurationBuilder.Build(); + + TypeWithNoMembers obj = new(); + configuration.Bind(obj); + + TypeWithNoMembers_Wrapper obj2 = new(); + configuration.Bind(obj2); + + List obj3 = new(); + configuration.Bind(obj3); + } + } + + public class TypeWithNoMembers + { + } + + public class TypeWithNoMembers_Wrapper + { + public TypeWithNoMembers Member { get; set; } + } + + public abstract class AbstractType_CannotInit + { + } + """; + + await VerifyAgainstBaselineUsingFile( + "EmptyConfigType.generated.txt", + source, + assessDiagnostics: (d) => + { + Assert.Equal(2, d.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); + }, + validateOutputCompDiags: false); + } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs index d8818bcf3c1d4c..0053cb41f37020 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs @@ -145,7 +145,8 @@ private static async Task VerifyAgainstBaselineUsingFile( if (validateOutputCompDiags) { - Assert.False(outputCompilation.GetDiagnostics().Any(d => d.Severity > DiagnosticSeverity.Info)); + ImmutableArray diagnostics = outputCompilation.GetDiagnostics(); + Assert.False(diagnostics.Any(d => d.Severity > DiagnosticSeverity.Info)); } return (runResult.Results[0].Diagnostics, runResult.Results[0].GeneratedSources); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs index 3fddad379397ef..846e64d904d531 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs @@ -177,60 +177,7 @@ public class MyClass { } } [Fact] - public async Task BindCanParseMethodParam() - { - string source = """ - using System; - using Microsoft.AspNetCore.Builder; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.DependencyInjection; - - public class Program - { - public static void Main() - { - ConfigurationBuilder configurationBuilder = new(); - IConfiguration config = configurationBuilder.Build(); - - BindOptions(config, new MyClass0()); - BindOptions(config, new MyClass1(), (_) => { }); - BindOptions(config, "", new MyClass2()); - } - - private void BindOptions(IConfiguration config, MyClass0 instance) - { - config.Bind(instance); - } - - private void BindOptions(IConfiguration config, MyClass1 instance, Action? configureOptions) - { - config.Bind(instance, configureOptions); - } - - private void BindOptions(IConfiguration config, string path, MyClass2 instance) - { - config.Bind(path, instance); - } - - public class MyClass0 { } - public class MyClass1 { } - public class MyClass2 { } - } - """; - - var (d, r) = await RunGenerator(source); - Assert.Single(r); - - string generatedSource = string.Join('\n', r[0].SourceText.Lines.Select(x => x.ToString())); - Assert.Contains("public static void Bind_ProgramMyClass0(this IConfiguration configuration, object? instance)", generatedSource); - Assert.Contains("public static void Bind_ProgramMyClass1(this IConfiguration configuration, object? instance, Action? configureOptions)", generatedSource); - Assert.Contains("public static void Bind_ProgramMyClass2(this IConfiguration configuration, string key, object? instance)", generatedSource); - - Assert.Empty(d); - } - - [Fact] - public async Task SucceedForMinimalInput() + public async Task SucceedWhenGivenMinimumRequiredReferences() { string source = """ using System; @@ -337,8 +284,8 @@ public class AnotherGraphWithUnsupportedMembers var (d, r) = await RunGenerator(source, references: GetAssemblyRefsWithAdditional(typeof(ImmutableArray<>), typeof(Encoding), typeof(JsonSerializer))); Assert.Single(r); - Assert.Equal(12, d.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); - Assert.Equal(10, d.Where(diag => diag.Id == Diagnostics.PropertyNotSupported.Id).Count()); + Assert.Equal(47, d.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); + Assert.Equal(44, d.Where(diag => diag.Id == Diagnostics.PropertyNotSupported.Id).Count()); } } } From 7b324065ebe0149e13960259c91701bc2d2ed156 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 17:44:33 -0700 Subject: [PATCH 195/783] Fix URL for syslib diagnostics (#92160) Co-authored-by: Eric StJohn --- src/libraries/Common/src/Roslyn/DiagnosticDescriptorHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Common/src/Roslyn/DiagnosticDescriptorHelper.cs b/src/libraries/Common/src/Roslyn/DiagnosticDescriptorHelper.cs index d11fdd8b5aaa03..8c5783ff9bd0b4 100644 --- a/src/libraries/Common/src/Roslyn/DiagnosticDescriptorHelper.cs +++ b/src/libraries/Common/src/Roslyn/DiagnosticDescriptorHelper.cs @@ -17,7 +17,7 @@ public static DiagnosticDescriptor Create( LocalizableString? description = null, params string[] customTags) { - string helpLink = $"https://learn.microsoft.com/dotnet/fundamentals/syslib-diagnostics/{id.ToLowerInvariant()}.md"; + string helpLink = $"https://learn.microsoft.com/dotnet/fundamentals/syslib-diagnostics/{id.ToLowerInvariant()}"; return new DiagnosticDescriptor(id, title, messageFormat, category, defaultSeverity, isEnabledByDefault, description, helpLink, customTags); } From c7252a392eee592c98ca509790fb3ed32407317e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 18:26:40 -0700 Subject: [PATCH 196/783] [release/8.0] Fix support of FromKeyedServicesAttribute in ActivatorUtilities.CreateFactory (#92144) * Fix support of FromKeyedServicesAttribute in ActivatorUtilities.CreateFactory * Addressing comment and adding a test --------- Co-authored-by: Benjamin Petit --- .../src/ActivatorUtilities.cs | 121 +++++++++++------- ...edDependencyInjectionSpecificationTests.cs | 36 ++++++ .../tests/DI.Tests/ActivatorUtilitiesTests.cs | 108 ++++++++++++++++ 3 files changed, 217 insertions(+), 48 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs index 6a42373ccc77d4..3ba30724d97f2b 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs @@ -36,7 +36,7 @@ public static class ActivatorUtilities #endif private static readonly MethodInfo GetServiceInfo = - GetMethodInfo>((sp, t, r, c) => GetService(sp, t, r, c)); + GetMethodInfo>((sp, t, r, c, k) => GetService(sp, t, r, c, k)); /// /// Instantiate a type with constructor arguments provided directly and/or from an . @@ -324,9 +324,9 @@ private static MethodInfo GetMethodInfo(Expression expr) return mc.Method; } - private static object? GetService(IServiceProvider sp, Type type, Type requiredBy, bool hasDefaultValue) + private static object? GetService(IServiceProvider sp, Type type, Type requiredBy, bool hasDefaultValue, object? key) { - object? service = sp.GetService(type); + object? service = key == null ? sp.GetService(type) : GetKeyedService(sp, type, key); if (service is null && !hasDefaultValue) { ThrowHelperUnableToResolveService(type, requiredBy); @@ -361,10 +361,12 @@ private static BlockExpression BuildFactoryExpression( } else { + var keyAttribute = (FromKeyedServicesAttribute?) Attribute.GetCustomAttribute(constructorParameter, typeof(FromKeyedServicesAttribute), inherit: false); var parameterTypeExpression = new Expression[] { serviceProvider, Expression.Constant(parameterType, typeof(Type)), Expression.Constant(constructor.DeclaringType, typeof(Type)), - Expression.Constant(hasDefaultValue) }; + Expression.Constant(hasDefaultValue), + Expression.Constant(keyAttribute?.Key) }; constructorArguments[i] = Expression.Call(GetServiceInfo, parameterTypeExpression); } @@ -435,10 +437,10 @@ private static ObjectFactory CreateFactoryReflection( if (matchedArgCount == 0) { // All injected; use a fast path. - Type[] types = GetParameterTypes(); + FactoryParameterContext[] parameters = GetFactoryParameterContext(); return useFixedValues ? - (serviceProvider, arguments) => ReflectionFactoryServiceOnlyFixed(invoker, types, declaringType, serviceProvider) : - (serviceProvider, arguments) => ReflectionFactoryServiceOnlySpan(invoker, types, declaringType, serviceProvider); + (serviceProvider, arguments) => ReflectionFactoryServiceOnlyFixed(invoker, parameters, declaringType, serviceProvider) : + (serviceProvider, arguments) => ReflectionFactoryServiceOnlySpan(invoker, parameters, declaringType, serviceProvider); } if (matchedArgCount == constructorParameters.Length) @@ -456,16 +458,6 @@ ObjectFactory InvokeCanonical() (serviceProvider, arguments) => ReflectionFactoryCanonicalFixed(invoker, parameters, declaringType, serviceProvider, arguments) : (serviceProvider, arguments) => ReflectionFactoryCanonicalSpan(invoker, parameters, declaringType, serviceProvider, arguments); } - - Type[] GetParameterTypes() - { - Type[] types = new Type[constructorParameters.Length]; - for (int i = 0; i < constructorParameters.Length; i++) - { - types[i] = constructorParameters[i].ParameterType; - } - return types; - } #else ParameterInfo[] constructorParameters = constructor.GetParameters(); if (constructorParameters.Length == 0) @@ -484,8 +476,15 @@ FactoryParameterContext[] GetFactoryParameterContext() for (int i = 0; i < constructorParameters.Length; i++) { ParameterInfo constructorParameter = constructorParameters[i]; + FromKeyedServicesAttribute? attr = (FromKeyedServicesAttribute?) + Attribute.GetCustomAttribute(constructorParameter, typeof(FromKeyedServicesAttribute), inherit: false); bool hasDefaultValue = ParameterDefaultValue.TryGetDefaultValue(constructorParameter, out object? defaultValue); - parameters[i] = new FactoryParameterContext(constructorParameter.ParameterType, hasDefaultValue, defaultValue, parameterMap[i] ?? -1); + parameters[i] = new FactoryParameterContext( + constructorParameter.ParameterType, + hasDefaultValue, + defaultValue, + parameterMap[i] ?? -1, + attr?.Key); } return parameters; @@ -495,18 +494,20 @@ FactoryParameterContext[] GetFactoryParameterContext() private readonly struct FactoryParameterContext { - public FactoryParameterContext(Type parameterType, bool hasDefaultValue, object? defaultValue, int argumentIndex) + public FactoryParameterContext(Type parameterType, bool hasDefaultValue, object? defaultValue, int argumentIndex, object? serviceKey) { ParameterType = parameterType; HasDefaultValue = hasDefaultValue; DefaultValue = defaultValue; ArgumentIndex = argumentIndex; + ServiceKey = serviceKey; } public Type ParameterType { get; } public bool HasDefaultValue { get; } public object? DefaultValue { get; } public int ArgumentIndex { get; } + public object? ServiceKey { get; } } private static void FindApplicableConstructor( @@ -825,39 +826,39 @@ private static void ThrowMarkedCtorDoesNotTakeAllProvidedArguments() #if NET8_0_OR_GREATER // Use the faster ConstructorInvoker which also has alloc-free APIs when <= 4 parameters. private static object ReflectionFactoryServiceOnlyFixed( ConstructorInvoker invoker, - Type[] parameterTypes, + FactoryParameterContext[] parameters, Type declaringType, IServiceProvider serviceProvider) { - Debug.Assert(parameterTypes.Length >= 1 && parameterTypes.Length <= FixedArgumentThreshold); + Debug.Assert(parameters.Length >= 1 && parameters.Length <= FixedArgumentThreshold); Debug.Assert(FixedArgumentThreshold == 4); if (serviceProvider is null) ThrowHelperArgumentNullExceptionServiceProvider(); - switch (parameterTypes.Length) + switch (parameters.Length) { case 1: return invoker.Invoke( - GetService(serviceProvider, parameterTypes[0], declaringType, false)); + GetService(serviceProvider, parameters[0].ParameterType, declaringType, false, parameters[0].ServiceKey)); case 2: return invoker.Invoke( - GetService(serviceProvider, parameterTypes[0], declaringType, false), - GetService(serviceProvider, parameterTypes[1], declaringType, false)); + GetService(serviceProvider, parameters[0].ParameterType, declaringType, false, parameters[0].ServiceKey), + GetService(serviceProvider, parameters[1].ParameterType, declaringType, false, parameters[1].ServiceKey)); case 3: return invoker.Invoke( - GetService(serviceProvider, parameterTypes[0], declaringType, false), - GetService(serviceProvider, parameterTypes[1], declaringType, false), - GetService(serviceProvider, parameterTypes[2], declaringType, false)); + GetService(serviceProvider, parameters[0].ParameterType, declaringType, false, parameters[0].ServiceKey), + GetService(serviceProvider, parameters[1].ParameterType, declaringType, false, parameters[1].ServiceKey), + GetService(serviceProvider, parameters[2].ParameterType, declaringType, false, parameters[2].ServiceKey)); case 4: return invoker.Invoke( - GetService(serviceProvider, parameterTypes[0], declaringType, false), - GetService(serviceProvider, parameterTypes[1], declaringType, false), - GetService(serviceProvider, parameterTypes[2], declaringType, false), - GetService(serviceProvider, parameterTypes[3], declaringType, false)); + GetService(serviceProvider, parameters[0].ParameterType, declaringType, false, parameters[0].ServiceKey), + GetService(serviceProvider, parameters[1].ParameterType, declaringType, false, parameters[1].ServiceKey), + GetService(serviceProvider, parameters[2].ParameterType, declaringType, false, parameters[2].ServiceKey), + GetService(serviceProvider, parameters[3].ParameterType, declaringType, false, parameters[3].ServiceKey)); } return null!; @@ -865,17 +866,17 @@ private static object ReflectionFactoryServiceOnlyFixed( private static object ReflectionFactoryServiceOnlySpan( ConstructorInvoker invoker, - Type[] parameterTypes, + FactoryParameterContext[] parameters, Type declaringType, IServiceProvider serviceProvider) { if (serviceProvider is null) ThrowHelperArgumentNullExceptionServiceProvider(); - object?[] arguments = new object?[parameterTypes.Length]; - for (int i = 0; i < parameterTypes.Length; i++) + object?[] arguments = new object?[parameters.Length]; + for (int i = 0; i < parameters.Length; i++) { - arguments[i] = GetService(serviceProvider, parameterTypes[i], declaringType, false); + arguments[i] = GetService(serviceProvider, parameters[i].ParameterType, declaringType, false, parameters[i].ServiceKey); } return invoker.Invoke(arguments.AsSpan()); @@ -907,7 +908,8 @@ private static object ReflectionFactoryCanonicalFixed( serviceProvider, parameter1.ParameterType, declaringType, - parameter1.HasDefaultValue)) ?? parameter1.DefaultValue); + parameter1.HasDefaultValue, + parameter1.ServiceKey)) ?? parameter1.DefaultValue); case 2: { ref FactoryParameterContext parameter2 = ref parameters[1]; @@ -920,7 +922,8 @@ private static object ReflectionFactoryCanonicalFixed( serviceProvider, parameter1.ParameterType, declaringType, - parameter1.HasDefaultValue)) ?? parameter1.DefaultValue, + parameter1.HasDefaultValue, + parameter1.ServiceKey)) ?? parameter1.DefaultValue, ((parameter2.ArgumentIndex != -1) // Throws a NullReferenceException if arguments is null. Consistent with expression-based factory. ? arguments![parameter2.ArgumentIndex] @@ -928,7 +931,8 @@ private static object ReflectionFactoryCanonicalFixed( serviceProvider, parameter2.ParameterType, declaringType, - parameter2.HasDefaultValue)) ?? parameter2.DefaultValue); + parameter2.HasDefaultValue, + parameter2.ServiceKey)) ?? parameter2.DefaultValue); } case 3: { @@ -943,7 +947,8 @@ private static object ReflectionFactoryCanonicalFixed( serviceProvider, parameter1.ParameterType, declaringType, - parameter1.HasDefaultValue)) ?? parameter1.DefaultValue, + parameter1.HasDefaultValue, + parameter1.ServiceKey)) ?? parameter1.DefaultValue, ((parameter2.ArgumentIndex != -1) // Throws a NullReferenceException if arguments is null. Consistent with expression-based factory. ? arguments![parameter2.ArgumentIndex] @@ -951,7 +956,8 @@ private static object ReflectionFactoryCanonicalFixed( serviceProvider, parameter2.ParameterType, declaringType, - parameter2.HasDefaultValue)) ?? parameter2.DefaultValue, + parameter2.HasDefaultValue, + parameter2.ServiceKey)) ?? parameter2.DefaultValue, ((parameter3.ArgumentIndex != -1) // Throws a NullReferenceException if arguments is null. Consistent with expression-based factory. ? arguments![parameter3.ArgumentIndex] @@ -959,7 +965,8 @@ private static object ReflectionFactoryCanonicalFixed( serviceProvider, parameter3.ParameterType, declaringType, - parameter3.HasDefaultValue)) ?? parameter3.DefaultValue); + parameter3.HasDefaultValue, + parameter3.ServiceKey)) ?? parameter3.DefaultValue); } case 4: { @@ -975,7 +982,8 @@ private static object ReflectionFactoryCanonicalFixed( serviceProvider, parameter1.ParameterType, declaringType, - parameter1.HasDefaultValue)) ?? parameter1.DefaultValue, + parameter1.HasDefaultValue, + parameter1.ServiceKey)) ?? parameter1.DefaultValue, ((parameter2.ArgumentIndex != -1) // Throws a NullReferenceException if arguments is null. Consistent with expression-based factory. ? arguments![parameter2.ArgumentIndex] @@ -983,7 +991,8 @@ private static object ReflectionFactoryCanonicalFixed( serviceProvider, parameter2.ParameterType, declaringType, - parameter2.HasDefaultValue)) ?? parameter2.DefaultValue, + parameter2.HasDefaultValue, + parameter2.ServiceKey)) ?? parameter2.DefaultValue, ((parameter3.ArgumentIndex != -1) // Throws a NullReferenceException if arguments is null. Consistent with expression-based factory. ? arguments![parameter3.ArgumentIndex] @@ -991,7 +1000,8 @@ private static object ReflectionFactoryCanonicalFixed( serviceProvider, parameter3.ParameterType, declaringType, - parameter3.HasDefaultValue)) ?? parameter3.DefaultValue, + parameter3.HasDefaultValue, + parameter3.ServiceKey)) ?? parameter3.DefaultValue, ((parameter4.ArgumentIndex != -1) // Throws a NullReferenceException if arguments is null. Consistent with expression-based factory. ? arguments![parameter4.ArgumentIndex] @@ -999,7 +1009,8 @@ private static object ReflectionFactoryCanonicalFixed( serviceProvider, parameter4.ParameterType, declaringType, - parameter4.HasDefaultValue)) ?? parameter4.DefaultValue); + parameter4.HasDefaultValue, + parameter4.ServiceKey)) ?? parameter4.DefaultValue); } } @@ -1028,7 +1039,8 @@ private static object ReflectionFactoryCanonicalSpan( serviceProvider, parameter.ParameterType, declaringType, - parameter.HasDefaultValue)) ?? parameter.DefaultValue; + parameter.HasDefaultValue, + parameter.ServiceKey)) ?? parameter.DefaultValue; } return invoker.Invoke(constructorArguments.AsSpan()); @@ -1078,7 +1090,8 @@ private static object ReflectionFactoryCanonical( serviceProvider, parameter.ParameterType, declaringType, - parameter.HasDefaultValue)) ?? parameter.DefaultValue; + parameter.HasDefaultValue, + parameter.ServiceKey)) ?? parameter.DefaultValue; } return constructor.Invoke(BindingFlags.DoNotWrapExceptions, binder: null, constructorArguments, culture: null); @@ -1099,5 +1112,17 @@ public static void ClearCache(Type[]? _) } } #endif + + private static object? GetKeyedService(IServiceProvider provider, Type type, object? serviceKey) + { + ThrowHelper.ThrowIfNull(provider); + + if (provider is IKeyedServiceProvider keyedServiceProvider) + { + return keyedServiceProvider.GetKeyedService(type, serviceKey); + } + + throw new InvalidOperationException(SR.KeyedServicesNotSupported); + } } } diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/KeyedDependencyInjectionSpecificationTests.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/KeyedDependencyInjectionSpecificationTests.cs index 32112c3e5f7691..a0dc73d58f820b 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/KeyedDependencyInjectionSpecificationTests.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/KeyedDependencyInjectionSpecificationTests.cs @@ -476,5 +476,41 @@ public ServiceProviderAccessor(IServiceProvider serviceProvider) public IServiceProvider ServiceProvider { get; } } + + [Fact] + public void SimpleServiceKeyedResolution() + { + // Arrange + var services = new ServiceCollection(); + services.AddKeyedTransient("simple"); + services.AddKeyedTransient("another"); + services.AddTransient(); + var provider = CreateServiceProvider(services); + var sut = provider.GetService(); + + // Act + var result = sut!.GetService("simple"); + + // Assert + Assert.True(result.GetType() == typeof(SimpleService)); + } + + public class SimpleParentWithDynamicKeyedService + { + private readonly IServiceProvider _serviceProvider; + + public SimpleParentWithDynamicKeyedService(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public ISimpleService GetService(string name) => _serviceProvider.GetKeyedService(name)!; + } + + public interface ISimpleService { } + + public class SimpleService : ISimpleService { } + + public class AnotherSimpleService : ISimpleService { } } } diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs index dda3cafa442eb0..f6e7c2f3a8eb7c 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs @@ -240,6 +240,100 @@ public void CreateFactory_CreatesFactoryMethod_5Types_5Injected() Assert.NotNull(item.Z); } + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [InlineData(true)] +#if NETCOREAPP + [InlineData(false)] +#endif + public void CreateFactory_CreatesFactoryMethod_KeyedParams(bool useDynamicCode) + { + var options = new RemoteInvokeOptions(); + if (!useDynamicCode) + { + DisableDynamicCode(options); + } + + using var remoteHandle = RemoteExecutor.Invoke(static () => + { + var factory = ActivatorUtilities.CreateFactory(Type.EmptyTypes); + + var services = new ServiceCollection(); + services.AddSingleton(new A()); + services.AddKeyedSingleton("b", new B()); + services.AddKeyedSingleton("c", new C()); + using var provider = services.BuildServiceProvider(); + ClassWithAKeyedBKeyedC item = factory(provider, null); + + Assert.IsType>(factory); + Assert.NotNull(item.A); + Assert.NotNull(item.B); + Assert.NotNull(item.C); + }, options); + } + + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [InlineData(true)] +#if NETCOREAPP + [InlineData(false)] +#endif + public void CreateFactory_CreatesFactoryMethod_KeyedParams_5Types(bool useDynamicCode) + { + var options = new RemoteInvokeOptions(); + if (!useDynamicCode) + { + DisableDynamicCode(options); + } + + using var remoteHandle = RemoteExecutor.Invoke(static () => + { + var factory = ActivatorUtilities.CreateFactory(Type.EmptyTypes); + + var services = new ServiceCollection(); + services.AddSingleton(new A()); + services.AddKeyedSingleton("b", new B()); + services.AddKeyedSingleton("c", new C()); + services.AddSingleton(new S()); + services.AddSingleton(new Z()); + using var provider = services.BuildServiceProvider(); + ClassWithAKeyedBKeyedCSZ item = factory(provider, null); + + Assert.IsType>(factory); + Assert.NotNull(item.A); + Assert.NotNull(item.B); + Assert.NotNull(item.C); + }, options); + } + + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [InlineData(true)] +#if NETCOREAPP + [InlineData(false)] +#endif + public void CreateFactory_CreatesFactoryMethod_KeyedParams_1Injected(bool useDynamicCode) + { + var options = new RemoteInvokeOptions(); + if (!useDynamicCode) + { + DisableDynamicCode(options); + } + + using var remoteHandle = RemoteExecutor.Invoke(static () => + { + var factory = ActivatorUtilities.CreateFactory(new Type[] { typeof(A) }); + + var services = new ServiceCollection(); + services.AddKeyedSingleton("b", new B()); + services.AddKeyedSingleton("c", new C()); + using var provider = services.BuildServiceProvider(); + ClassWithAKeyedBKeyedC item = factory(provider, new object?[] { new A() }); + + Assert.IsType>(factory); + Assert.NotNull(item.A); + Assert.NotNull(item.B); + Assert.NotNull(item.C); + }, options); + } + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(true)] #if NETCOREAPP @@ -527,6 +621,13 @@ internal class C { } internal class S { } internal class Z { } + internal class ClassWithAKeyedBKeyedC : ClassWithABC + { + public ClassWithAKeyedBKeyedC(A a, [FromKeyedServices("b")] B b, [FromKeyedServices("c")] C c) + : base(a, b, c) + { } + } + internal class ClassWithABCS : ClassWithABC { public S S { get; } @@ -540,6 +641,13 @@ internal class ClassWithABCSZ : ClassWithABCS public ClassWithABCSZ(A a, B b, C c, S s, Z z) : base(a, b, c, s) { Z = z; } } + internal class ClassWithAKeyedBKeyedCSZ : ClassWithABCSZ + { + public ClassWithAKeyedBKeyedCSZ(A a, [FromKeyedServices("b")] B b, [FromKeyedServices("c")] C c, S s, Z z) + : base(a, b, c, s, z) + { } + } + internal class ClassWithABC_FirstConstructorWithAttribute : ClassWithABC { [ActivatorUtilitiesConstructor] From 01751138fedd6ab8a3092edcd9dde0e6aee8c1c1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 16 Sep 2023 14:05:12 -0700 Subject: [PATCH 197/783] [release/8.0] Fix type parameter mapping logic in ILLink/ILCompiler (#92139) * Fix type parameter mapping bug in illink * Same in ILCompiler * Check dataflow of mapped type parameter * Fix test for analyzer --------- Co-authored-by: Sven Boemer --- .../Compiler/Dataflow/CompilerGeneratedState.cs | 3 +++ .../Linker.Dataflow/CompilerGeneratedState.cs | 6 ++++-- .../DataFlow/CompilerGeneratedTypes.cs | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedState.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedState.cs index 8150abeca61b1e..6a5e2ed77cdf08 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedState.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedState.cs @@ -158,8 +158,10 @@ referencedMethod.OwningType is MetadataType generatedType && break; case ILOpcode.stsfld: + case ILOpcode.ldsfld: { // Same as above, but stsfld instead of a call to the constructor + // Ldsfld may also trigger a cctor that creates a closure environment FieldDesc? field = methodBody.GetObject(reader.ReadILToken()) as FieldDesc; if (field == null) continue; @@ -417,6 +419,7 @@ void MapGeneratedTypeTypeParameters( break; case ILOpcode.stsfld: + case ILOpcode.ldsfld: { if (body.GetObject(reader.ReadILToken()) is FieldDesc { OwningType: MetadataType owningType } && compilerGeneratedType == owningType.GetTypeDefinition()) diff --git a/src/tools/illink/src/linker/Linker.Dataflow/CompilerGeneratedState.cs b/src/tools/illink/src/linker/Linker.Dataflow/CompilerGeneratedState.cs index 5f26219e22fdea..db0f9b2481f8e4 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/CompilerGeneratedState.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/CompilerGeneratedState.cs @@ -180,7 +180,8 @@ referencedMethod.DeclaringType is var generatedType && case OperandType.InlineField: { // Same as above, but stsfld instead of a call to the constructor - if (instruction.OpCode.Code is not Code.Stsfld) + // Ldsfld may also trigger a cctor that creates a closure environment + if (instruction.OpCode.Code is not (Code.Stsfld or Code.Ldsfld)) continue; FieldDefinition? field = _context.TryResolve ((FieldReference) instruction.Operand); @@ -390,7 +391,8 @@ static void MapGeneratedTypeTypeParameters ( handled = true; } break; - case Code.Stsfld: { + case Code.Stsfld: + case Code.Ldsfld: { if (instr.Operand is FieldReference { DeclaringType: GenericInstanceType typeRef } && compilerGeneratedType == context.TryResolve (typeRef)) { return typeRef; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypes.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypes.cs index c414bc252d1280..324e2cbb505f3a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypes.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypes.cs @@ -43,6 +43,7 @@ public static void Main () CapturingLocalFunctionInsideIterator (); LambdaInsideAsync (); LocalFunctionInsideAsync (); + NestedStaticLambda.Test (); } private static void UseIterator () @@ -352,5 +353,21 @@ void LocalFunction () await Task.Delay (0); LocalFunction (); } + + class NestedStaticLambda + { + public static class Container<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> { + public static Func, Func> NestedLambda = + (Func x) => v => x(v); + } + + [ExpectedWarning ("IL2091", "T", nameof (Container), nameof (DynamicallyAccessedMemberTypes.PublicMethods), + // https://github.com/dotnet/runtime/issues/84918 + ProducedBy = Tool.Trimmer | Tool.NativeAot)] + public static void Test () + { + Container.NestedLambda ((T t) => t) (default (T)); + } + } } } From 287c10d2539d47268a1083c4d533cf84124900cf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 16 Sep 2023 14:05:36 -0700 Subject: [PATCH 198/783] [release/8.0] [NativeAOT] Fix iOS library build by linking standard C++ library by default (#92141) * Link with standard C++ library when building a iOS library with NativeAOT * PR feedback --------- Co-authored-by: Ivan Povazan --- .../BuildIntegration/Microsoft.NETCore.Native.Unix.targets | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index d30e7e73578eaa..1f5b2cd681095c 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -50,6 +50,8 @@ The .NET Foundation licenses this file to you under the MIT license. libeventpipe-disabled libeventpipe-enabled + + true From 3e8b479894a7d38b7b084d75bed38d70e766011c Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Sat, 16 Sep 2023 14:10:14 -0700 Subject: [PATCH 199/783] Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2268640 (#92159) --- .../gen/Resources/xlf/Strings.de.xlf | 2 +- .../gen/Resources/xlf/Strings.es.xlf | 2 +- .../gen/Resources/xlf/Strings.fr.xlf | 2 +- .../gen/Resources/xlf/Strings.it.xlf | 2 +- .../gen/Resources/xlf/Strings.ja.xlf | 2 +- .../gen/Resources/xlf/Strings.ko.xlf | 2 +- .../gen/Resources/xlf/Strings.pl.xlf | 2 +- .../gen/Resources/xlf/Strings.ru.xlf | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf index 89583fdc312308..5f98b4d4a396f0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.de.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + Für einen Binderaufruf wurde keine Bindungslogik generiert. Nicht unterstützte Eingabemuster umfassen generische Aufrufe, vorübergehende geschachtelte Objekte und das Übergeben von Typen, die nicht "public" oder "internal" sind. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf index faa309bd384637..446d2f0f7edb8f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.es.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + No se ha generado la lógica de enlace para una llamada de enlace. Entre los patrones de entrada no admitidos se incluyen las llamadas genéricas, el paso de objetos en caja y el paso de tipos que no son "públicos" o "internos". diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf index f8d4c5a5f95d32..517d8ffad0e5cc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.fr.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + La logique de liaison n’a pas été générée pour un appel de classeur. Les modèles d’entrée non pris en charge incluent les appels génériques, le passage d’objets box et les types de passage qui ne sont pas 'public' ou 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf index 54a26a381d6fd1..787d46e9e7339f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.it.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + La logica di associazione non è stata generata per una chiamata del gestore di associazione. I modelli di input non supportati includono chiamate generici, il passaggio di oggetti boxed e il passaggio di tipi non 'public' o 'internal'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf index b5f1790b0db187..57308cabd0da29 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ja.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + バインダー呼び出しのバインド ロジックが生成されませんでした。サポートされていない入力パターンには、ジェネリック呼び出し、ボックス化されたオブジェクトの受け渡し、および 'public' または 'internal' ではない型の受け渡しが含まれます。 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf index dfcbc040fe3067..e97e99e1ac7cd0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ko.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + 바인더 호출에 대한 바인딩 논리가 생성되지 않았습니다. 지원되지 않는 입력 패턴에는 제네릭 호출, boxed 개체 전달 및 'public' 또는 'internal'이 아닌 전달 형식이 포함됩니다. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf index 1834dac0e73f15..d0a4985215c6aa 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pl.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + Logika powiązania nie została wygenerowana dla wywołania integratora. Nieobsługiwane wzorce wejściowe obejmują ogólne wywołania, przekazywanie obiektów w pudełkach i przekazywanie typów, które nie są „publiczne” lub „wewnętrzne”. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf index 00e4d7418b5db6..c230a1edd07d1d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.ru.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + Логика привязки не создана для вызова привязки. Неподдерживаемые шаблоны ввода включают общие вызовы, передачу упакованных объектов и передачу типов, не являющихся "общедоступными" или "внутренними". From a185c2a055496874bff51a79f049c261867f05ff Mon Sep 17 00:00:00 2001 From: Hong Li Date: Mon, 21 Aug 2023 11:55:01 -0700 Subject: [PATCH 200/783] Adding PACKAGE.md to System.Runtime.Caching package (#90701) * Adding PACKAGE.md to System.Runtime.Caching package * add Remarks * move PACKAGE.md to src folder * update per PR feedback * add important block --- .../System.Runtime.Caching/src/PACKAGE.md | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/libraries/System.Runtime.Caching/src/PACKAGE.md diff --git a/src/libraries/System.Runtime.Caching/src/PACKAGE.md b/src/libraries/System.Runtime.Caching/src/PACKAGE.md new file mode 100644 index 00000000000000..172477bb6af149 --- /dev/null +++ b/src/libraries/System.Runtime.Caching/src/PACKAGE.md @@ -0,0 +1,37 @@ +## About + +[System.Runtime.Caching](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.caching?view=dotnet-plat-ext-7.0) ([NuGet package](https://www.nuget.org/packages/System.Runtime.Caching/)) is a packaged set of simple caching API's derived from those of the same namespace available in .Net Framework since 4.0. This package is intended for use as a bridge when porting .Net Framework applications to .Net Core. + +This `System.Runtime.Caching` package can be used with any [.NET implementation](/dotnet/standard/net-standard#net-implementation-support) that targets .NET Standard 2.0 or later. For example: +* .NET Core 3.1 or later. +* .Net Framework 4.5 or later. +* .Net 5.0 or late + +[Microsoft.Extensions.Caching.Memory](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Memory/)/[IMemoryCache](https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-7.0) is recommended over `System.Runtime.Caching`/`MemoryCache` because it's better integrated into ASP.NET Core. For example, `IMemoryCache` works natively with ASP.NET Core [dependency injection](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-7.0). + +> > [!IMPORTANT] +> Use `System.Runtime.Caching`/`MemoryCache` as a compatibility bridge when porting code from .NET 4.x to .NET Core. + + +## Main Types + +The main types provided by this library are: + +* `System.Runtime.Caching.MemoryCache` + +## Remarks + +[MemoryCache.PhysicalMemoryLimit](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.caching.memorycache.physicalmemorylimit?view=dotnet-plat-ext-7.0) property is only supported on windows. + +## Addtional Documentation + +* [Caching in .NET](https://learn.microsoft.com/en-us/dotnet/core/extensions/caching) +* [Cache in-memory in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-7.0 ) + +## Related Packages + +* [Microsoft.Extensions.Caching.Memory](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Memory/) + +## Feedback & Contributing + +System.Runtime.Caching is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file From 7dc1f6febc3472958244f466329b625bf5e1572b Mon Sep 17 00:00:00 2001 From: "MSDN.WhiteKnight" <35516665+MSDN-WhiteKnight@users.noreply.github.com> Date: Mon, 21 Aug 2023 15:44:18 +0500 Subject: [PATCH 201/783] Update Package readme guidelines with new template (#90842) * Update package readme guidelines * Fix typo --- docs/coding-guidelines/libraries-packaging.md | 42 +++++++++++++++++-- src/libraries/System.Text.Json/src/PACKAGE.md | 2 +- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/docs/coding-guidelines/libraries-packaging.md b/docs/coding-guidelines/libraries-packaging.md index 25a2894cfe9ae5..f7c926890bf8e8 100644 --- a/docs/coding-guidelines/libraries-packaging.md +++ b/docs/coding-guidelines/libraries-packaging.md @@ -55,11 +55,47 @@ Packages can include a Markdown Readme file with a short usage documentation. To The package Readme is displayed on the package details page on [NuGet gallery](https://nuget.org/). You can include the following content in it: - A description of the package purpose. +- A list of package key features +- A code example that demostrates how to use the package. - Information when package should be used. For example, if the library is included in the shared framework in .NET, but needs to be installed via NuGet on .NET Framework, it should be mentioned. -- Information on how to get started with the package. -- Links to related documentation. - A list of common entry-point types for the package, with links to their API docs under [.NET API Browser](https://learn.microsoft.com/dotnet/api/). -- A short code example that demostrates the package usage. +- Links to related documentation. +- Information about how to provide feedback on the package and contribute to it. + +Use the following Markdown template for a package Readme: + +``` +## About + + + +## Key Features + + + +## How to Use + + + +## Main Types + + + +## Additional Documentation + +* [Conceptual documentation](...) +* [API documentation](...) + +## Related Packages + + + +## Feedback & Contributing + + + +ExamplePackage is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). +``` For a list of supported Markdown features, see [NuGet documentation](https://learn.microsoft.com/nuget/nuget-org/package-readme-on-nuget-org#supported-markdown-features). diff --git a/src/libraries/System.Text.Json/src/PACKAGE.md b/src/libraries/System.Text.Json/src/PACKAGE.md index 1bfcd1da44e258..7cbbec76e65b32 100644 --- a/src/libraries/System.Text.Json/src/PACKAGE.md +++ b/src/libraries/System.Text.Json/src/PACKAGE.md @@ -237,7 +237,7 @@ The main types provided by this library are: * `System.Text.Json.Nodes.JsonNode` * `System.Text.Json.Serialization.Metadata.JsonTypeInfo` -## Addtional Documentation +## Additional Documentation * [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/overview) * [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.text.json) From 5b4148d0823f3cdfbec840edbf7388e25edbd54b Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 28 Aug 2023 13:59:05 +0200 Subject: [PATCH 202/783] Add package readmes --- .../src/PACKAGE.md | 44 ++++++++++ .../Microsoft.Bcl.Cryptography/src/PACKAGE.md | 44 ++++++++++ .../Microsoft.Bcl.Numerics/src/PACKAGE.md | 44 ++++++++++ .../Microsoft.Bcl.TimeProvider/src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 47 ++++++++-- .../src/PACKAGE.md | 42 ++++++++- .../src/PACKAGE.md | 65 ++++++++------ .../src/PACKAGE.md | 42 ++++++++- .../src/PACKAGE.md | 44 +++++++++- .../src/PACKAGE.md | 85 +++++++++---------- .../src/PACKAGE.md | 42 ++++++++- .../src/PACKAGE.md | 43 +++++++++- .../src/PACKAGE.md | 42 ++++++++- .../src/PACKAGE.md | 38 ++++++++- .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++-- .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../Microsoft.Extensions.Http/src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ src/libraries/System.CodeDom/src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 40 ++++++++- .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../System.Composition.Hosting/src/PACKAGE.md | 44 ++++++++++ .../System.Composition.Runtime/src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../System.Composition/src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 46 ++++++++-- src/libraries/System.Data.Odbc/src/PACKAGE.md | 44 ++++++++++ .../System.Data.OleDb/src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../System.DirectoryServices/src/PACKAGE.md | 44 ++++++++++ .../System.Drawing.Common/src/PACKAGE.md | 44 ++++++++++ .../System.Formats.Cbor/src/PACKAGE.md | 44 ++++++++++ .../System.IO.Hashing/src/PACKAGE.md | 44 ++++++++++ .../System.IO.Packaging/src/PACKAGE.md | 44 ++++++++++ .../System.IO.Pipelines/src/PACKAGE.md | 44 ++++++++++ src/libraries/System.IO.Ports/src/PACKAGE.md | 44 ++++++++++ .../System.Management/src/PACKAGE.md | 44 ++++++++++ .../System.Memory.Data/src/PACKAGE.md | 44 ++++++++++ .../System.Net.Http.Json/src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../System.Numerics.Tensors/src/PACKAGE.md | 44 ++++++++++ .../System.Reflection.Context/src/PACKAGE.md | 44 ++++++++++ .../System.Reflection.Metadata/src/PACKAGE.md | 48 +++++++++-- .../src/PACKAGE.md | 44 ++++++++-- .../src/PACKAGE.md | 44 ++++++++++ .../System.Runtime.Caching/src/PACKAGE.md | 31 +++++-- .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ src/libraries/System.Speech/src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../System.Text.Encodings.Web/src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../System.Threading.Channels/src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ .../src/PACKAGE.md | 44 ++++++++++ src/libraries/System.Threading/src/PACKAGE.md | 44 ++++++++++ .../System.Windows.Extensions/src/PACKAGE.md | 44 ++++++++++ 97 files changed, 4180 insertions(+), 127 deletions(-) create mode 100644 src/libraries/Microsoft.Bcl.AsyncInterfaces/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Bcl.TimeProvider/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Caching.Memory/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.FileProviders.Composite/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Hosting.Systemd/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Logging.Abstractions/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Logging.Configuration/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Logging.Console/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Logging.Debug/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Logging.EventLog/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Logging.EventSource/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Logging/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Options/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Extensions.Primitives/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.NET.WebAssembly.Threading/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Win32.Registry.AccessControl/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.Win32.SystemEvents/src/PACKAGE.md create mode 100644 src/libraries/Microsoft.XmlSerializer.Generator/src/PACKAGE.md create mode 100644 src/libraries/System.CodeDom/src/PACKAGE.md create mode 100644 src/libraries/System.ComponentModel.Composition.Registration/src/PACKAGE.md create mode 100644 src/libraries/System.ComponentModel.Composition/src/PACKAGE.md create mode 100644 src/libraries/System.Composition.AttributedModel/src/PACKAGE.md create mode 100644 src/libraries/System.Composition.Convention/src/PACKAGE.md create mode 100644 src/libraries/System.Composition.Hosting/src/PACKAGE.md create mode 100644 src/libraries/System.Composition.Runtime/src/PACKAGE.md create mode 100644 src/libraries/System.Composition.TypedParts/src/PACKAGE.md create mode 100644 src/libraries/System.Composition/src/PACKAGE.md create mode 100644 src/libraries/System.Data.Odbc/src/PACKAGE.md create mode 100644 src/libraries/System.Data.OleDb/src/PACKAGE.md create mode 100644 src/libraries/System.Diagnostics.DiagnosticSource/src/PACKAGE.md create mode 100644 src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md create mode 100644 src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md create mode 100644 src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md create mode 100644 src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md create mode 100644 src/libraries/System.DirectoryServices/src/PACKAGE.md create mode 100644 src/libraries/System.Drawing.Common/src/PACKAGE.md create mode 100644 src/libraries/System.Formats.Cbor/src/PACKAGE.md create mode 100644 src/libraries/System.IO.Hashing/src/PACKAGE.md create mode 100644 src/libraries/System.IO.Packaging/src/PACKAGE.md create mode 100644 src/libraries/System.IO.Pipelines/src/PACKAGE.md create mode 100644 src/libraries/System.IO.Ports/src/PACKAGE.md create mode 100644 src/libraries/System.Management/src/PACKAGE.md create mode 100644 src/libraries/System.Memory.Data/src/PACKAGE.md create mode 100644 src/libraries/System.Net.Http.Json/src/PACKAGE.md create mode 100644 src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md create mode 100644 src/libraries/System.Numerics.Tensors/src/PACKAGE.md create mode 100644 src/libraries/System.Reflection.Context/src/PACKAGE.md create mode 100644 src/libraries/System.Resources.Extensions/src/PACKAGE.md create mode 100644 src/libraries/System.Runtime.Serialization.Schema/src/PACKAGE.md create mode 100644 src/libraries/System.Security.Cryptography.Cose/src/PACKAGE.md create mode 100644 src/libraries/System.Security.Cryptography.Pkcs/src/PACKAGE.md create mode 100644 src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md create mode 100644 src/libraries/System.Security.Cryptography.Xml/src/PACKAGE.md create mode 100644 src/libraries/System.Security.Permissions/src/PACKAGE.md create mode 100644 src/libraries/System.ServiceModel.Syndication/src/PACKAGE.md create mode 100644 src/libraries/System.ServiceProcess.ServiceController/src/PACKAGE.md create mode 100644 src/libraries/System.Speech/src/PACKAGE.md create mode 100644 src/libraries/System.Text.Encoding.CodePages/src/PACKAGE.md create mode 100644 src/libraries/System.Text.Encodings.Web/src/PACKAGE.md create mode 100644 src/libraries/System.Threading.AccessControl/src/PACKAGE.md create mode 100644 src/libraries/System.Threading.Channels/src/PACKAGE.md create mode 100644 src/libraries/System.Threading.RateLimiting/src/PACKAGE.md create mode 100644 src/libraries/System.Threading.Tasks.Dataflow/src/PACKAGE.md create mode 100644 src/libraries/System.Threading/src/PACKAGE.md create mode 100644 src/libraries/System.Windows.Extensions/src/PACKAGE.md diff --git a/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/PACKAGE.md new file mode 100644 index 00000000000000..7a9788f170fb42 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Bcl.AsyncInterfaces is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md new file mode 100644 index 00000000000000..5a3a8c037bca45 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Bcl.Cryptography is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md new file mode 100644 index 00000000000000..df05c1c906d9b8 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Bcl.Numerics is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Bcl.TimeProvider/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.TimeProvider/src/PACKAGE.md new file mode 100644 index 00000000000000..90901aee2d59c7 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.TimeProvider/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Bcl.TimeProvider is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md new file mode 100644 index 00000000000000..651e3c04c98405 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Caching.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Caching.Memory/src/PACKAGE.md new file mode 100644 index 00000000000000..baa592831d4977 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Caching.Memory is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md index 9a93ad1f76eb74..fb051d69f251b2 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md @@ -1,18 +1,20 @@ ## About + + Provides abstractions of key-value pair based configuration. Interfaces defined in this package are implemented by classes in [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/) and other configuration packages. -Commonly used types: +## Key Features + + -- [Microsoft.Extensions.Configuration.IConfiguration](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfiguration) -- [Microsoft.Extensions.Configuration.IConfigurationBuilder](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfigurationbuilder) -- [Microsoft.Extensions.Configuration.IConfigurationProvider](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfigurationprovider) -- [Microsoft.Extensions.Configuration.IConfigurationRoot](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfigurationroot) -- [Microsoft.Extensions.Configuration.IConfigurationSection](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfigurationsection) +* +* +* -For more information, see the documentation: [Configuration in .NET](https://learn.microsoft.com/dotnet/core/extensions/configuration). +## How to Use -## Example + The example below shows a small code sample using this library and trying out the `ConfigurationKeyName` attribute available since .NET 6: @@ -39,3 +41,32 @@ var config = new ConfigurationBuilder() var options = config.Get(); Console.WriteLine(options.NamedProperty); // returns "value for named property" ``` + +## Main Types + + + +The main types provided by this library are: + +* [`Microsoft.Extensions.Configuration.IConfiguration`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfiguration) +* [`Microsoft.Extensions.Configuration.IConfigurationBuilder`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfigurationbuilder) +* [`Microsoft.Extensions.Configuration.IConfigurationProvider`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfigurationprovider) +* [`Microsoft.Extensions.Configuration.IConfigurationRoot`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfigurationroot) +* [`Microsoft.Extensions.Configuration.IConfigurationSection`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfigurationsection) + +## Additional Documentation + + + +* [Configuration in .NET](https://learn.microsoft.com/dotnet/core/extensions/configuration) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Configuration.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/PACKAGE.md index ffb402bece35f0..f39973daaad6f2 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/PACKAGE.md @@ -1,10 +1,21 @@ ## About + + Provides the functionality to bind an object to data in configuration providers for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to represent the configuration data as strongly-typed classes defined in the application code. To bind a configuration, use the [Microsoft.Extensions.Configuration.ConfigurationBinder.Get](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.configurationbinder.get) extension method on the `IConfiguration` object. To use this package, you also need to install a package for the [configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration#configuration-providers), for example, [Microsoft.Extensions.Configuration.Json](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Json/) for the JSON provider. -For more information, see the documentation: [Configuration in .NET](https://learn.microsoft.com/dotnet/core/extensions/configuration). +## Key Features + + + +* +* +* + +## How to Use + + -## Example The following example shows how to bind a JSON configuration section to .NET objects. ```cs @@ -81,3 +92,30 @@ You can include a configuration file using a code like this in your `.csproj` fi ``` + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Configuration in .NET](https://learn.microsoft.com/dotnet/core/extensions/configuration) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Configuration.Binder is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md index 39daac6e4ec6c0..7d4c1543012d4c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md @@ -1,29 +1,44 @@ ## About + + Command line configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to read configuration parameters from the command line arguments of your application. You can use [CommandLineConfigurationExtensions.AddCommandLine](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.commandlineconfigurationextensions.addcommandline) extension method on `IConfigurationBuilder` to add the command line configuration provider to the configuration builder. -For more information, see the documentation: [Command-line configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#command-line-configuration-provider). - -## Example - -The following example shows how to read application configuration from the command line. You can use a command like `dotnet run --InputPath "c:\fizz" --OutputPath "c:\buzz"` to run it. - -```cs -using System; -using Microsoft.Extensions.Configuration; - -class Program -{ - static void Main(string[] args) - { - // Build a configuration object from command line - IConfiguration config = new ConfigurationBuilder() - .AddCommandLine(args) - .Build(); - - // Read configuration values - Console.WriteLine($"InputPath: {config["InputPath"]}"); - Console.WriteLine($"OutputPath: {config["OutputPath"]}"); - } -} -``` +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Command-line configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#command-line-configuration-provider) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.commandline) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Configuration.CommandLine is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/PACKAGE.md index 84d2d9412cce76..d9612166e7ecd4 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/PACKAGE.md @@ -1,10 +1,21 @@ ## About + + Environment variables configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to read configuration parameters from environment variables. You can use [EnvironmentVariablesExtensions.AddEnvironmentVariables](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.environmentvariablesextensions.addenvironmentvariables) extension method on `IConfigurationBuilder` to add the environment variables configuration provider to the configuration builder. -For more information, see the documentation: [Environment variable configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#environment-variable-configuration-provider). +## Key Features + + + +* +* +* + +## How to Use + + -## Example The following example shows how to read application configuration from environment variables. ```cs @@ -26,3 +37,30 @@ class Program } } ``` + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Environment variable configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#environment-variable-configuration-provider) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.environmentvariables) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Configuration.EnvironmentVariables is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/PACKAGE.md index e43c909d83225c..60b2096828e8ec 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/PACKAGE.md @@ -1,9 +1,45 @@ ## About + + Provides a base class for file-based configuration providers used with [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/) and extension methods for configuring them. -For more information, see the documentation: +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Configuration in .NET](https://learn.microsoft.com/dotnet/core/extensions/configuration) +* [Microsoft.Extensions.Configuration.FileConfigurationProvider](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.fileconfigurationprovider) +* [Microsoft.Extensions.Configuration.FileConfigurationExtensions](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.fileconfigurationextensions) + +## Related Packages + + + +## Feedback & Contributing + + -- [Configuration in .NET](https://learn.microsoft.com/dotnet/core/extensions/configuration) -- [Microsoft.Extensions.Configuration.FileConfigurationProvider](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.fileconfigurationprovider) -- [Microsoft.Extensions.Configuration.FileConfigurationExtensions](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.fileconfigurationextensions) +Microsoft.Extensions.Configuration.FileExtensions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md index 7322364392c600..a86dbd4757ea19 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md @@ -1,49 +1,44 @@ ## About + + INI configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to read configuration parameters from [INI files](https://en.wikipedia.org/wiki/INI_file). You can use [IniConfigurationExtensions.AddIniFile](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iniconfigurationextensions.addinifile) extension method on `IConfigurationBuilder` to add INI configuration provider to the configuration builder. -For more information, see the documentation: [INI configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#ini-configuration-provider). - -## Example -The following example shows how to read the application configuration from INI file. - -```cs -using System; -using Microsoft.Extensions.Configuration; - -class Program -{ - static void Main() - { - // Build a configuration object from INI file - IConfiguration config = new ConfigurationBuilder() - .AddIniFile("appsettings.ini") - .Build(); - - // Get a configuration section - IConfigurationSection section = config.GetSection("Settings"); - - // Read configuration values - Console.WriteLine($"Server: {section["Server"]}"); - Console.WriteLine($"Database: {section["Database"]}"); - } -} -``` - -To run this example, include an `appsettings.ini` file with the following content in your project: - -``` -[Settings] -Server=example.com -Database=Northwind -``` - -You can include a configuration file using a code like this in your `.csproj` file: - -```xml - - - Always - - -``` +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [INI configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#ini-configuration-provider) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.ini) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Configuration.Ini is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration.Json/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Json/src/PACKAGE.md index ae1c6355100f3a..b1b0a8fff8421c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Json/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Json/src/PACKAGE.md @@ -1,10 +1,21 @@ ## About + + JSON configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to read your application's settings from a JSON file. You can use [JsonConfigurationExtensions.AddJsonFile](https://docs.microsoft.com/dotnet/api/microsoft.extensions.configuration.jsonconfigurationextensions.addjsonfile) extension method on `IConfigurationBuilder` to add the JSON configuration provider to the configuration builder. -For more information, see the documentation: [JSON configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#json-configuration-provider). +## Key Features + + + +* +* +* + +## How to Use + + -## Example The following example shows how to read application settings from the JSON configuration file. ```cs @@ -60,3 +71,30 @@ You can include a configuration file using a code like this in your `.csproj` fi ``` + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [JSON configuration provider](https://learn.microsoft.com/en-us/dotnet/core/extensions/configuration-providers#json-configuration-provider) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.json) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Configuration.Json is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/PACKAGE.md index 4dba7ccd6bbb5d..976bf5598f60f4 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/PACKAGE.md @@ -1,8 +1,45 @@ ## About + + User secrets configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). User secrets mechanism enables you to override application configuration settings with values stored in the local secrets file. You can use [UserSecretsConfigurationExtensions.AddUserSecrets](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.usersecretsconfigurationextensions.addusersecrets) extension method on `IConfigurationBuilder` to add user secrets provider to the configuration builder. -For more information, see the documentation: +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Configuration in .NET](https://learn.microsoft.com/dotnet/core/extensions/configuration) +* [Safe storage of app secrets in development in ASP.NET Core](https://learn.microsoft.com/aspnet/core/security/app-secrets) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.usersecrets) + +## Related Packages + + + +## Feedback & Contributing + + -- [Configuration in .NET](https://learn.microsoft.com/dotnet/core/extensions/configuration) -- [Safe storage of app secrets in development in ASP.NET Core](https://learn.microsoft.com/aspnet/core/security/app-secrets) +Microsoft.Extensions.Configuration.UserSecrets is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Xml/src/PACKAGE.md index d47be06c8dea3b..602c919514ddce 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Xml/src/PACKAGE.md @@ -1,10 +1,21 @@ ## About + + XML configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to read configuration parameters from XML files. You can use [XmlConfigurationExtensions.AddXmlFile](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.xmlconfigurationextensions.addxmlfile) extension method on `IConfigurationBuilder` to add XML configuration provider to the configuration builder. -For more information, see the documentation: [XML configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#xml-configuration-provider). +## Key Features + + + +* +* +* + +## How to Use + + -## Example The following example shows how to read the application configuration from XML file. ```cs @@ -59,3 +70,30 @@ You can include a configuration file using a code like this in your `.csproj` fi ``` + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [XML configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#xml-configuration-provider) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.xml) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Configuration.Xml is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md index 92e93652f7a609..13f09693b243a3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md @@ -1,8 +1,44 @@ ## About + + `Microsoft.Extensions.Configuration` is combined with a core configuration abstraction under `Microsoft.Extensions.Configuration.Abstractions` that allows for building different kinds of configuration providers to retrieve key/value pair configuration values from in the form of `IConfiguration`. There are a number of built-in configuration provider implementations to read from environment variables, in-memory collections, JSON, INI or XML files. Aside from the built-in variations, there are more shipped libraries shipped by community for integration with various configuration service and other data sources. -For more information, see the documentation: +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + - [Configuration in .NET](https://learn.microsoft.com/dotnet/core/extensions/configuration) - [Microsoft.Extensions.Configuration namespace](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Configuration is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/PACKAGE.md new file mode 100644 index 00000000000000..9ec0653cb849c6 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.DependencyInjection.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/PACKAGE.md new file mode 100644 index 00000000000000..79b5aea01302e5 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.DependencyInjection.Specification.Tests is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.DependencyInjection/src/PACKAGE.md new file mode 100644 index 00000000000000..dbf19733382c4d --- /dev/null +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.DependencyInjection is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.DependencyModel/src/PACKAGE.md index f4d4a485899ebb..d8bcd473f60d0a 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/PACKAGE.md @@ -1,16 +1,22 @@ ## About + + Provides abstractions for reading `.deps` files. When a .NET application is compiled, the SDK generates a JSON manifest file (`.deps.json`) that contains information about application dependencies. You can use `Microsoft.Extensions.DependencyModel` to read information from this manifest at run time. This is useful when you want to dynamically compile code (for example, using Roslyn Emit API) referencing the same dependencies as your main application. By default, the dependency manifest contains information about the application's target framework and runtime dependencies. Set the [PreserveCompilationContext](https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#preservecompilationcontext) project property to `true` to additionally include information about reference assemblies used during compilation. -For more information, see the documentation: +## Key Features + + -- [.deps.json file format](https://github.com/dotnet/sdk/blob/main/documentation/specs/runtime-configuration-file.md#appnamedepsjson) -- [Microsoft.Extensions.DependencyModel namespace](https://docs.microsoft.com/dotnet/api/microsoft.extensions.dependencymodel) -- [Microsoft.Extensions.DependencyModel.DependencyContext](https://docs.microsoft.com/dotnet/api/microsoft.extensions.dependencymodel.dependencycontext) +* +* +* -## Example +## How to Use + + The following example shows how to display the list of assemblies used when compiling the current application. Include `true` in your project file to run this example. @@ -35,3 +41,31 @@ class Program } } ``` + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [.deps.json file format](https://github.com/dotnet/sdk/blob/main/documentation/specs/runtime-configuration-file.md#appnamedepsjson) +* [Microsoft.Extensions.DependencyModel namespace](https://docs.microsoft.com/dotnet/api/microsoft.extensions.dependencymodel) +* [Microsoft.Extensions.DependencyModel.DependencyContext](https://docs.microsoft.com/dotnet/api/microsoft.extensions.dependencymodel.dependencycontext) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.DependencyModel is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md new file mode 100644 index 00000000000000..efb7ca7c9133cc --- /dev/null +++ b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.FileProviders.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Composite/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileProviders.Composite/src/PACKAGE.md new file mode 100644 index 00000000000000..122fbecfa2ba91 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.FileProviders.Composite/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.FileProviders.Composite is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md new file mode 100644 index 00000000000000..bf3378a56e63dd --- /dev/null +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.FileProviders.Physical is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md new file mode 100644 index 00000000000000..a5d26b28318fda --- /dev/null +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.FileSystemGlobbing is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/PACKAGE.md new file mode 100644 index 00000000000000..b94327b9a0078f --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Hosting.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Hosting.Systemd/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Hosting.Systemd/src/PACKAGE.md new file mode 100644 index 00000000000000..ffb5501c8568fe --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Hosting.Systemd/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Hosting.Systemd is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/PACKAGE.md new file mode 100644 index 00000000000000..e70b7da4ac046f --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Hosting.WindowsServices is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md new file mode 100644 index 00000000000000..4370cde8aa3573 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Hosting is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md new file mode 100644 index 00000000000000..7effd1dfd486cf --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Http is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/PACKAGE.md new file mode 100644 index 00000000000000..534ef37b23d3b0 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Logging.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/PACKAGE.md new file mode 100644 index 00000000000000..7c38fc44d350f7 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Logging.Configuration is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.Console/src/PACKAGE.md new file mode 100644 index 00000000000000..582bba45f12169 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Logging.Console is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Debug/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.Debug/src/PACKAGE.md new file mode 100644 index 00000000000000..b933164215cb84 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Debug/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Logging.Debug is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.EventLog/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.EventLog/src/PACKAGE.md new file mode 100644 index 00000000000000..9f1330aad75f6a --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.EventLog/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Logging.EventLog is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.EventSource/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.EventSource/src/PACKAGE.md new file mode 100644 index 00000000000000..8a67a2888f46db --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.EventSource/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Logging.EventSource is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md new file mode 100644 index 00000000000000..7bab863fa95cc9 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Logging.TraceSource is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging/src/PACKAGE.md new file mode 100644 index 00000000000000..302b93b4956421 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Logging is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/PACKAGE.md new file mode 100644 index 00000000000000..1609a20ac51d7b --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Options.ConfigurationExtensions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md new file mode 100644 index 00000000000000..3bf3280ad4cf1b --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Options.DataAnnotations is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Options/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Options/src/PACKAGE.md new file mode 100644 index 00000000000000..220873bc79027f --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Options is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Primitives/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Primitives/src/PACKAGE.md new file mode 100644 index 00000000000000..db0a84ec52694c --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Primitives/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Primitives is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/PACKAGE.md b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Win32.Registry.AccessControl/src/PACKAGE.md b/src/libraries/Microsoft.Win32.Registry.AccessControl/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/Microsoft.Win32.Registry.AccessControl/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Win32.SystemEvents/src/PACKAGE.md b/src/libraries/Microsoft.Win32.SystemEvents/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/Microsoft.Win32.SystemEvents/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.XmlSerializer.Generator/src/PACKAGE.md b/src/libraries/Microsoft.XmlSerializer.Generator/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/Microsoft.XmlSerializer.Generator/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.CodeDom/src/PACKAGE.md b/src/libraries/System.CodeDom/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.CodeDom/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Collections.Immutable/src/PACKAGE.md b/src/libraries/System.Collections.Immutable/src/PACKAGE.md index cf4995b4cad9ca..1b39d42bb175f0 100644 --- a/src/libraries/System.Collections.Immutable/src/PACKAGE.md +++ b/src/libraries/System.Collections.Immutable/src/PACKAGE.md @@ -1,10 +1,46 @@ ## About + + This package provides collections that are thread safe and guaranteed to never change their contents, also known as immutable collections. Like strings, any methods that perform modifications will not change the existing instance but instead return a new instance. For efficiency reasons, the implementation uses a sharing mechanism to ensure that newly created instances share as much data as possible with the previous instance while ensuring that operations have a predictable time complexity. The `System.Collections.Immutable` library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks. -For more information, see the documentation: +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + - [Collections and Data Structures](https://docs.microsoft.com/dotnet/standard/collections/) -- [System.Collections.Immutable API reference](https://docs.microsoft.com/dotnet/api/system.collections.immutable) +- [API documentation](https://docs.microsoft.com/dotnet/api/system.collections.immutable) + +## Related Packages + + + +## Feedback & Contributing + + + +System.Collections.Immutable is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.Composition.Registration/src/PACKAGE.md b/src/libraries/System.ComponentModel.Composition.Registration/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.ComponentModel.Composition.Registration/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.Composition/src/PACKAGE.md b/src/libraries/System.ComponentModel.Composition/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.ComponentModel.Composition/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Composition.AttributedModel/src/PACKAGE.md b/src/libraries/System.Composition.AttributedModel/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Composition.AttributedModel/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Composition.Convention/src/PACKAGE.md b/src/libraries/System.Composition.Convention/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Composition.Convention/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Composition.Hosting/src/PACKAGE.md b/src/libraries/System.Composition.Hosting/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Composition.Hosting/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Composition.Runtime/src/PACKAGE.md b/src/libraries/System.Composition.Runtime/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Composition.Runtime/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Composition.TypedParts/src/PACKAGE.md b/src/libraries/System.Composition.TypedParts/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Composition.TypedParts/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Composition/src/PACKAGE.md b/src/libraries/System.Composition/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Composition/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/PACKAGE.md b/src/libraries/System.Configuration.ConfigurationManager/src/PACKAGE.md index 8448be2423b11b..fdaea06fddb7e3 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/PACKAGE.md +++ b/src/libraries/System.Configuration.ConfigurationManager/src/PACKAGE.md @@ -1,15 +1,20 @@ ## About + + Provides types that support using XML configuration files (`app.config`). This package exists only to support migrating existing .NET Framework code that already uses System.Configuration. When writing new code, use another configuration system instead, such as [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). -For more information, see the documentation: +## Key Features + + -- [Configure apps by using configuration files](https://docs.microsoft.com/dotnet/framework/configure-apps/) -- [System.Configuration namespace](https://docs.microsoft.com/dotnet/api/system.configuration) -- [System.Configuration.Configuration](https://docs.microsoft.com/dotnet/api/system.configuration.configuration) -- [System.Configuration.ConfigurationManager](https://docs.microsoft.com/dotnet/api/system.configuration.configurationmanager) +* +* +* -## Example +## How to Use + + The following example shows how to read and modify the application configuration settings. @@ -63,3 +68,32 @@ To run this example, include an `app.config` file with the following content in ``` + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Configure apps by using configuration files](https://docs.microsoft.com/dotnet/framework/configure-apps/) +* [System.Configuration namespace](https://docs.microsoft.com/dotnet/api/system.configuration) +* [System.Configuration.Configuration](https://docs.microsoft.com/dotnet/api/system.configuration.configuration) +* [System.Configuration.ConfigurationManager](https://docs.microsoft.com/dotnet/api/system.configuration.configurationmanager) + +## Related Packages + + + +## Feedback & Contributing + + + +System.Configuration.ConfigurationManager is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Data.Odbc/src/PACKAGE.md b/src/libraries/System.Data.Odbc/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Data.Odbc/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Data.OleDb/src/PACKAGE.md b/src/libraries/System.Data.OleDb/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/PACKAGE.md b/src/libraries/System.Diagnostics.DiagnosticSource/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md b/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md b/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md b/src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.DirectoryServices/src/PACKAGE.md b/src/libraries/System.DirectoryServices/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.DirectoryServices/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Drawing.Common/src/PACKAGE.md b/src/libraries/System.Drawing.Common/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Drawing.Common/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Formats.Cbor/src/PACKAGE.md b/src/libraries/System.Formats.Cbor/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Formats.Cbor/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.IO.Hashing/src/PACKAGE.md b/src/libraries/System.IO.Hashing/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.IO.Hashing/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.IO.Packaging/src/PACKAGE.md b/src/libraries/System.IO.Packaging/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.IO.Packaging/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.IO.Pipelines/src/PACKAGE.md b/src/libraries/System.IO.Pipelines/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.IO.Pipelines/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.IO.Ports/src/PACKAGE.md b/src/libraries/System.IO.Ports/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.IO.Ports/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Management/src/PACKAGE.md b/src/libraries/System.Management/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Management/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Memory.Data/src/PACKAGE.md b/src/libraries/System.Memory.Data/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Memory.Data/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Net.Http.Json/src/PACKAGE.md b/src/libraries/System.Net.Http.Json/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Net.Http.Json/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md b/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Numerics.Tensors/src/PACKAGE.md b/src/libraries/System.Numerics.Tensors/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Reflection.Context/src/PACKAGE.md b/src/libraries/System.Reflection.Context/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Reflection.Context/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Reflection.Metadata/src/PACKAGE.md b/src/libraries/System.Reflection.Metadata/src/PACKAGE.md index 43543a703a9123..42ee1764292807 100644 --- a/src/libraries/System.Reflection.Metadata/src/PACKAGE.md +++ b/src/libraries/System.Reflection.Metadata/src/PACKAGE.md @@ -1,18 +1,22 @@ ## About + + This package provides a low-level .NET (ECMA-335) metadata reader and writer. It's geared for performance and is the ideal choice for building higher-level libraries that intend to provide their own object model, such as compilers. The metadata format is defined by the [ECMA-335 - Common Language Infrastructure (CLI)](http://www.ecma-international.org/publications/standards/Ecma-335.htm) specification and [its amendments](https://github.com/dotnet/runtime/blob/main/docs/design/specs/Ecma-335-Augments.md). The `System.Reflection.Metadata` library is included in the .NET Runtime shared framework. The package can be installed when you need to use it in other target frameworks. -For more information, see the documentation: +## Key Features + + -- [System.Reflection.Metadata.MetadataReader](https://docs.microsoft.com/dotnet/api/system.reflection.metadata.metadatareader) -- [System.Reflection.PortableExecutable.PEReader](https://docs.microsoft.com/dotnet/api/system.reflection.portableexecutable.pereader) -- [System.Reflection.Metadata.Ecma335.MetadataBuilder](https://docs.microsoft.com/dotnet/api/system.reflection.metadata.ecma335.metadatabuilder) -- [System.Reflection.PortableExecutable.PEBuilder](https://docs.microsoft.com/dotnet/api/system.reflection.portableexecutable.pebuilder) -- [System.Reflection.PortableExecutable.ManagedPEBuilder](https://docs.microsoft.com/dotnet/api/system.reflection.portableexecutable.managedpebuilder) +* +* +* -## Example +## How to Use + + The following example shows how to read assembly information using PEReader and MetadataReader. @@ -80,3 +84,33 @@ class Program } ``` + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [System.Reflection.Metadata.MetadataReader](https://docs.microsoft.com/dotnet/api/system.reflection.metadata.metadatareader) +* [System.Reflection.PortableExecutable.PEReader](https://docs.microsoft.com/dotnet/api/system.reflection.portableexecutable.pereader) +* [System.Reflection.Metadata.Ecma335.MetadataBuilder](https://docs.microsoft.com/dotnet/api/system.reflection.metadata.ecma335.metadatabuilder) +* [System.Reflection.PortableExecutable.PEBuilder](https://docs.microsoft.com/dotnet/api/system.reflection.portableexecutable.pebuilder) +* [System.Reflection.PortableExecutable.ManagedPEBuilder](https://docs.microsoft.com/dotnet/api/system.reflection.portableexecutable.managedpebuilder) + +## Related Packages + + + +## Feedback & Contributing + + + +System.Reflection.Metadata is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/PACKAGE.md b/src/libraries/System.Reflection.MetadataLoadContext/src/PACKAGE.md index 7e351acc94fe75..1f0e974b2bab60 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/PACKAGE.md +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/PACKAGE.md @@ -1,14 +1,20 @@ ## About + + Provides read-only reflection on assemblies in an isolated context with support for assemblies that target different processor architectures and runtimes. Using MetadataLoadContext enables you to inspect assemblies without loading them into the main execution context. Assemblies in MetadataLoadContext are treated only as metadata, that is, you can read information about their members, but cannot execute any code contained in them. -For more information, see the documentation: +## Key Features + + -- [How to: Inspect assembly contents using MetadataLoadContext](https://docs.microsoft.com/dotnet/standard/assembly/inspect-contents-using-metadataloadcontext) -- [System.Reflection.MetadataLoadContext](https://docs.microsoft.com/dotnet/api/system.reflection.metadataloadcontext) -- [System.Reflection.MetadataAssemblyResolver](https://docs.microsoft.com/dotnet/api/system.reflection.metadataassemblyresolver) +* +* +* -## Example +## How to Use + + The following example shows how to print the list of types defined in an assembly. @@ -38,3 +44,31 @@ class Program } } ``` + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [How to: Inspect assembly contents using MetadataLoadContext](https://docs.microsoft.com/dotnet/standard/assembly/inspect-contents-using-metadataloadcontext) +* [System.Reflection.MetadataLoadContext](https://docs.microsoft.com/dotnet/api/system.reflection.metadataloadcontext) +* [System.Reflection.MetadataAssemblyResolver](https://docs.microsoft.com/dotnet/api/system.reflection.metadataassemblyresolver) + +## Related Packages + + + +## Feedback & Contributing + + + +System.Reflection.MetadataLoadContext is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Resources.Extensions/src/PACKAGE.md b/src/libraries/System.Resources.Extensions/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Resources.Extensions/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Runtime.Caching/src/PACKAGE.md b/src/libraries/System.Runtime.Caching/src/PACKAGE.md index 172477bb6af149..56b8069b131681 100644 --- a/src/libraries/System.Runtime.Caching/src/PACKAGE.md +++ b/src/libraries/System.Runtime.Caching/src/PACKAGE.md @@ -1,11 +1,8 @@ ## About -[System.Runtime.Caching](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.caching?view=dotnet-plat-ext-7.0) ([NuGet package](https://www.nuget.org/packages/System.Runtime.Caching/)) is a packaged set of simple caching API's derived from those of the same namespace available in .Net Framework since 4.0. This package is intended for use as a bridge when porting .Net Framework applications to .Net Core. + -This `System.Runtime.Caching` package can be used with any [.NET implementation](/dotnet/standard/net-standard#net-implementation-support) that targets .NET Standard 2.0 or later. For example: -* .NET Core 3.1 or later. -* .Net Framework 4.5 or later. -* .Net 5.0 or late +Packaged set of simple caching API's derived from those of the same namespace available in .NET Framework since 4.0. This package is intended for use as a bridge when porting .NET Framework applications to .NET. [Microsoft.Extensions.Caching.Memory](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Memory/)/[IMemoryCache](https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-7.0) is recommended over `System.Runtime.Caching`/`MemoryCache` because it's better integrated into ASP.NET Core. For example, `IMemoryCache` works natively with ASP.NET Core [dependency injection](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-7.0). @@ -13,25 +10,43 @@ This `System.Runtime.Caching` package can be used with any [.NET implementation] > Use `System.Runtime.Caching`/`MemoryCache` as a compatibility bridge when porting code from .NET 4.x to .NET Core. +## Key Features + + + +* +* +* + +## How to Use + + + ## Main Types + + The main types provided by this library are: * `System.Runtime.Caching.MemoryCache` -## Remarks +## Additional Documentation -[MemoryCache.PhysicalMemoryLimit](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.caching.memorycache.physicalmemorylimit?view=dotnet-plat-ext-7.0) property is only supported on windows. + -## Addtional Documentation +[MemoryCache.PhysicalMemoryLimit](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.caching.memorycache.physicalmemorylimit?view=dotnet-plat-ext-7.0) property is only supported on windows. * [Caching in .NET](https://learn.microsoft.com/en-us/dotnet/core/extensions/caching) * [Cache in-memory in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-7.0 ) ## Related Packages + + * [Microsoft.Extensions.Caching.Memory](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Memory/) ## Feedback & Contributing + + System.Runtime.Caching is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Runtime.Serialization.Schema/src/PACKAGE.md b/src/libraries/System.Runtime.Serialization.Schema/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Runtime.Serialization.Schema/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Cose/src/PACKAGE.md b/src/libraries/System.Security.Cryptography.Cose/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Security.Cryptography.Cose/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/PACKAGE.md b/src/libraries/System.Security.Cryptography.Pkcs/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md b/src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Xml/src/PACKAGE.md b/src/libraries/System.Security.Cryptography.Xml/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Security.Cryptography.Xml/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Security.Permissions/src/PACKAGE.md b/src/libraries/System.Security.Permissions/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Security.Permissions/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.ServiceModel.Syndication/src/PACKAGE.md b/src/libraries/System.ServiceModel.Syndication/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.ServiceModel.Syndication/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/PACKAGE.md b/src/libraries/System.ServiceProcess.ServiceController/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.ServiceProcess.ServiceController/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Speech/src/PACKAGE.md b/src/libraries/System.Speech/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Speech/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Text.Encoding.CodePages/src/PACKAGE.md b/src/libraries/System.Text.Encoding.CodePages/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Text.Encoding.CodePages/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Text.Encodings.Web/src/PACKAGE.md b/src/libraries/System.Text.Encodings.Web/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Text.Encodings.Web/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Threading.AccessControl/src/PACKAGE.md b/src/libraries/System.Threading.AccessControl/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Threading.AccessControl/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Threading.Channels/src/PACKAGE.md b/src/libraries/System.Threading.Channels/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Threading.Channels/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Threading.RateLimiting/src/PACKAGE.md b/src/libraries/System.Threading.RateLimiting/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Threading.RateLimiting/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/PACKAGE.md b/src/libraries/System.Threading.Tasks.Dataflow/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Threading/src/PACKAGE.md b/src/libraries/System.Threading/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Threading/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Windows.Extensions/src/PACKAGE.md b/src/libraries/System.Windows.Extensions/src/PACKAGE.md new file mode 100644 index 00000000000000..2709a6e84e284f --- /dev/null +++ b/src/libraries/System.Windows.Extensions/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file From 66d76142b246f70699eecc44b237438aad32f381 Mon Sep 17 00:00:00 2001 From: carlossanlop <1175054+carlossanlop@users.noreply.github.com> Date: Thu, 31 Aug 2023 19:06:26 -0700 Subject: [PATCH 203/783] System.Diagnostics.EventLog --- .../src/PACKAGE.md | 95 +++++++++++++++++-- 1 file changed, 86 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md b/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md index 2709a6e84e284f..1cb7eae3a470b3 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md +++ b/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md @@ -2,43 +2,120 @@ +When an error occurs in a Windows machine, the system administrator or support representative must determine what caused the error, attempt to recover any lost data, and prevent the error from recurring. It is helpful if applications, the operating system, and other system services record important events, such as low-memory conditions or excessive attempts to access a disk. The system administrator can then use the Windows Event Log to help determine what conditions caused the error and identify the context in which it occurred. +This package provides the `System.Diagnostics.EventLog.dll` assembly, which contains types that allow applications to interact with the Windows Event Log service. ## Key Features -* -* -* +* Allows reading from existing logs. +* Allows writing entries to logs. +* Can create or delete event sources. +* Can delete logs. +* Can respond to log entries. +* Can create new logs when creating an event source. ## How to Use +```cs +if(!EventLog.SourceExists("MySource")) +{ + // An event log source should not be created and immediately used. + // There is a latency time to enable the source, it should be created + // prior to executing the application that uses the source. + // Execute this sample a second time to use the new source. + EventLog.CreateEventSource("MySource", "MyNewLog"); + Console.WriteLine("Event source created. Exiting, execute the application a second time to use the source."); + // The source is created. Exit the application to allow it to be registered. + return; +} + +EventLog myLog = new(); +myLog.Source = "MySource"; +myLog.WriteEntry("Writing an informational entry to the event log."); +``` + +Notes: + +- This assembly is only supported on Windows operating systems. +- Starting with Windows Vista, you must run the application as an administrator to interact with the Windows Event Log service using the `System.Diagnostics.EventLog` class. + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +Under the [`System.Diagnostics`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics) namespace: + +- [`System.Diagnostics.EntryWrittenEventArgs`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EntryWrittenEventArgs) +- [`System.Diagnostics.EntryWrittenEventHandler`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EntryWrittenEventHandler) +- [`System.Diagnostics.EventInstance`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventInstance) +- [`System.Diagnostics.EventLog`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLog) +- [`System.Diagnostics.EventLogEntry`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLogEntry) +- [`System.Diagnostics.EventLogEntryCollection`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLogEntryCollection) +- [`System.Diagnostics.EventLogEntryType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLogEntryType) +- [`System.Diagnostics.EventLogTraceListener`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLogTraceListener) +- [`System.Diagnostics.EventSourceCreationData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventSourceCreationData) +- [`System.Diagnostics.OverflowAction`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.OverflowAction) + +Under the[`System.Diagnostics.Eventing.Reader`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader) namespace: + +- [`System.Diagnostics.Eventing.Reader.EventBookmark`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventBookmark) +- [`System.Diagnostics.Eventing.Reader.EventKeyword`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventKeyword) +- [`System.Diagnostics.Eventing.Reader.EventLevel`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLevel) +- [`System.Diagnostics.Eventing.Reader.EventLogConfiguration`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogConfiguration) +- [`System.Diagnostics.Eventing.Reader.EventLogException`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogException) +- [`System.Diagnostics.Eventing.Reader.EventLogInformation`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogInformation) +- [`System.Diagnostics.Eventing.Reader.EventLogInvalidDataException`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogInvalidDataException) +- [`System.Diagnostics.Eventing.Reader.EventLogIsolation`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogIsolation) +- [`System.Diagnostics.Eventing.Reader.EventLogLink`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogLink) +- [`System.Diagnostics.Eventing.Reader.EventLogMode`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogMode) +- [`System.Diagnostics.Eventing.Reader.EventLogNotFoundException`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogNotFoundException) +- [`System.Diagnostics.Eventing.Reader.EventLogPropertySelector`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogPropertySelector) +- [`System.Diagnostics.Eventing.Reader.EventLogProviderDisabledException`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogProviderDisabledException) +- [`System.Diagnostics.Eventing.Reader.EventLogQuery`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogQuery) +- [`System.Diagnostics.Eventing.Reader.EventLogReader`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogReader) +- [`System.Diagnostics.Eventing.Reader.EventLogReadingException`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogReadingException) +- [`System.Diagnostics.Eventing.Reader.EventLogRecord`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogRecord) +- [`System.Diagnostics.Eventing.Reader.EventLogSession`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogSession) +- [`System.Diagnostics.Eventing.Reader.EventLogStatus`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogStatus) +- [`System.Diagnostics.Eventing.Reader.EventLogType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogType) +- [`System.Diagnostics.Eventing.Reader.EventLogWatcher`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogWatcher) +- [`System.Diagnostics.Eventing.Reader.EventMetadata`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventMetadata) +- [`System.Diagnostics.Eventing.Reader.EventOpcode`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventOpcode) +- [`System.Diagnostics.Eventing.Reader.EventProperty`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventProperty) +- [`System.Diagnostics.Eventing.Reader.EventRecord`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventRecord) +- [`System.Diagnostics.Eventing.Reader.EventRecordWrittenEventArgs`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventRecordWrittenEventArgs) +- [`System.Diagnostics.Eventing.Reader.EventTask`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventTask) +- [`System.Diagnostics.Eventing.Reader.PathType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.PathType) +- [`System.Diagnostics.Eventing.Reader.ProviderMetadata`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.ProviderMetadata) +- [`System.Diagnostics.Eventing.Reader.SessionAuthentication`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.SessionAuthentication) +- [`System.Diagnostics.Eventing.Reader.StandardEventKeywords`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.StandardEventKeywords) +- [`System.Diagnostics.Eventing.Reader.StandardEventLevel`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.StandardEventLevel) +- [`System.Diagnostics.Eventing.Reader.StandardEventOpcode`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.StandardEventOpcode) +- [`System.Diagnostics.Eventing.Reader.StandardEventTask`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.StandardEventTask) ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +- [Microsoft Learn - System.Diagnostics.EventLog API reference](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLog) +- [Windows App Development - Event logging](https://learn.microsoft.com/en-us/windows/win32/eventlog/event-logging) +- [GitHub - Source code](https://github.com/dotnet/runtime/tree/main/src/libraries/System.Diagnostics.EventLog) ## Related Packages +- [System.Diagnostics.PerformanceCounter](https://www.nuget.org/packages/System.Diagnostics.PerformanceCounter) + ## Feedback & Contributing -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +**System.Diagnostics.EventLog** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 3b1268dc46b57d137b85823eea36cf31e963e06c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Fri, 1 Sep 2023 10:25:06 -0700 Subject: [PATCH 204/783] System.Diagnostics.PerformanceCounter --- .../src/PACKAGE.md | 211 +++++++++++++++++- 1 file changed, 202 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md b/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md index 2709a6e84e284f..1fecb16e569611 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md @@ -2,43 +2,236 @@ +Windows allows you to examine how programs you run affect your computer's performance, both in real time and by collecting log data for later analysis. You can do this via the Windows Performance Monitor tool, which uses performance counters, among other features. +Windows performance counters provide a high-level abstraction layer that provides a consistent interface for collecting various kinds of system data such as CPU, memory, and disk usage. They can be included in the operating system or can be part of individual applications. Windows Performance Monitor requests the current value of performance counters at specifiedtime intervals. + +System administrators often use performance counters to monitor systems for performance or behavior problems. Software developers often use performance counters to examine the resource usage of their programs. + +This package provides the `System.Diagnostics.PerformanceCounter.dll` assembly, which contains types that allow applications to interact with the Windows performance counters. ## Key Features -* -* -* +* Can be used to read existing predefined or custom counters. +* Can be used for publishing (writing) data to custom counters. +* Can collect performance counters from the local machine or from a remote machine. ## How to Use +```cs +using System; +using System.Collections.Generic; +using System.Diagnostics; + +public class App +{ + public static void Main() + { + List samples = []; + + // If the category does not exist, create the category and exit. + // Performance counters should not be created and immediately used. + // There is a latency time to enable the counters, they should be created + // prior to executing the application that uses the counters. + // Execute this sample a second time to use the category. + if (SetupCategory()) + { + return; + } + + CollectSamples(samples); + CalculateResults(samples); + } + + private static bool SetupCategory() + { + if (PerformanceCounterCategory.Exists("AverageCounter64SampleCategory")) + { + Console.WriteLine("Category exists - AverageCounter64SampleCategory"); + return false; + } + + CounterCreationDataCollection counterDataCollection = []; + + // Add the counter. + CounterCreationData averageCount64 = new() + { + CounterType = PerformanceCounterType.AverageCount64, + CounterName = "AverageCounter64Sample" + }; + counterDataCollection.Add(averageCount64); + + // Add the base counter. + CounterCreationData averageCount64Base = new() + { + CounterType = PerformanceCounterType.AverageBase, + CounterName = "AverageCounter64SampleBase" + }; + counterDataCollection.Add(averageCount64Base); + + // Create the category. + PerformanceCounterCategory.Create("AverageCounter64SampleCategory", + "Demonstrates usage of the AverageCounter64 performance counter type.", + PerformanceCounterCategoryType.SingleInstance, counterDataCollection); + + return true; + } + + private static void CollectSamples(List samples) + { + // Create the counters + + PerformanceCounter avgCounter64Sample = new PerformanceCounter("AverageCounter64SampleCategory", + "AverageCounter64Sample", + false) + { + RawValue = 0 + }; + + PerformanceCounter avgCounter64SampleBase = new PerformanceCounter("AverageCounter64SampleCategory", + "AverageCounter64SampleBase", + false) + { + RawValue = 0 + }; + + Random r = new(DateTime.Now.Millisecond); + + for (int j = 0; j < 100; j++) + { + int value = r.Next(1, 10); + Console.Write(j + " = " + value); + + avgCounter64Sample.IncrementBy(value); + + avgCounter64SampleBase.Increment(); + + if ((j % 10) == 9) + { + OutputSample(avgCounter64Sample.NextSample()); + samples.Add(avgCounter64Sample.NextSample()); + } + else + { + Console.WriteLine(); + } + + System.Threading.Thread.Sleep(50); + } + } + + private static void CalculateResults(List samples) + { + for (int i = 0; i < (samples.Count - 1); i++) + { + // Output the sample. + OutputSample(samples[i]); + OutputSample(samples[i + 1]); + + // Use .NET to calculate the counter value. + Console.WriteLine($".NET computed counter value = {CounterSampleCalculator.ComputeCounterValue(samples[i], samples[i + 1])}"); + + // Calculate the counter value manually. + Console.WriteLine($"My computed counter value = {MyComputeCounterValue(samples[i], samples[i + 1])}"); + } + } + + // Description - This counter type shows how many items are processed, on average, + // during an operation. Counters of this type display a ratio of the items + // processed (such as bytes sent) to the number of operations completed. The + // ratio is calculated by comparing the number of items processed during the + // last interval to the number of operations completed during the last interval. + // Generic type - Average + // Formula - (N1 - N0) / (D1 - D0), where the numerator (N) represents the number + // of items processed during the last sample interval and the denominator (D) + // represents the number of operations completed during the last two sample + // intervals. + // Average (Nx - N0) / (Dx - D0) + // Example PhysicalDisk\ Avg. Disk Bytes/Transfer + private static float MyComputeCounterValue(CounterSample s0, CounterSample s1) + { + float numerator = (float)s1.RawValue - s0.RawValue; + float denomenator = (float)s1.BaseValue - s0.BaseValue; + float counterValue = numerator / denomenator; + return counterValue; + } + + private static void OutputSample(CounterSample s) + { + Console.WriteLine("\r\n+++++++++++"); + Console.WriteLine("Sample values - \r\n"); + Console.WriteLine($" BaseValue = {s.BaseValue}"); + Console.WriteLine($" CounterFrequency = {s.CounterFrequency}"); + Console.WriteLine($" CounterTimeStamp = {s.CounterTimeStamp}"); + Console.WriteLine($" CounterType = {s.CounterType}"); + Console.WriteLine($" RawValue = {s.RawValue}"); + Console.WriteLine($" SystemFrequency = {s.SystemFrequency}"); + Console.WriteLine($" TimeStamp = {s.TimeStamp}"); + Console.WriteLine($" TimeStamp100nSec = {s.TimeStamp100nSec}"); + Console.WriteLine("++++++++++++++++++++++"); + } +} +``` + +Notes: + +* This assembly is only supported on Windows operating systems. +* Only the administrator of the computer or users in the Performance Logs User Group can log counter data. Users in the Administrator group can log counter data only if the tool they use to log counter data is started from a Command Prompt window that is opened with `Run as administrator...`. Any users in interactive logon sessions can view counter data. However, users in non-interactive logon sessions must be in the Performance Monitoring Users group to view counter data. + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +Under the [`System.Diagnostics`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics) namespace: + +* [`System.Diagnostics.CounterCreationData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.CounterCreationData) +* [`System.Diagnostics.CounterCreationDataCollection`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.CounterCreationDataCollection) +* [`System.Diagnostics.CounterSample`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.CounterSample) +* [`System.Diagnostics.CounterSampleCalculator`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.CounterSampleCalculator) +* [`System.Diagnostics.ICollectData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.ICollectData) +* [`System.Diagnostics.InstanceData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.InstanceData) +* [`System.Diagnostics.InstanceDataCollection`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.InstanceDataCollection) +* [`System.Diagnostics.InstanceDataCollectionCollection`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.InstanceDataCollectionCollection) +* [`System.Diagnostics.PerformanceCounter`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceCounter) +* [`System.Diagnostics.PerformanceCounterCategory`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceCounterCategory) +* [`System.Diagnostics.PerformanceCounterCategoryType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceCounterCategoryType) +* [`System.Diagnostics.PerformanceCounterInstanceLifetime`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceCounterInstanceLifetime) +* [`System.Diagnostics.PerformanceCounterManager`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceCounterManager) +* [`System.Diagnostics.PerformanceCounterType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceCounterType) + +Under the [`System.Diagnostics.PerformanceData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData) namespace: + +* [`System.Diagnostics.PerformanceData.CounterData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterData) +* [`System.Diagnostics.PerformanceData.CounterSet`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterSet) +* [`System.Diagnostics.PerformanceData.CounterSetInstance`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterSetInstance) +* [`System.Diagnostics.PerformanceData.CounterSetInstanceCounterDataSet`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterSetInstanceCounterDataSet) +* [`System.Diagnostics.PerformanceData.CounterSetInstanceType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterSetInstanceType) +* [`System.Diagnostics.PerformanceData.CounterType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterType) ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Microsoft Learn - System.Diagnostics.PerformanceCounter API reference](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.performancecounter?view=dotnet-plat-ext-7.0) +* [Windows App Development - Performance Counters](https://learn.microsoft.com/en-us/windows/win32/perfctrs/performance-counters-portal) +* [Windows Performance and Reliability - Windows Performance Monitor](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc749249(v=ws.11)) +* [Windows Server - perfmon](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/perfmon) +* [GitHub - Source code](https://github.com/dotnet/runtime/tree/main/src/libraries/System.Diagnostics.PerformanceCounter) ## Related Packages +* [System.Diagnostics.EventLog](https://www.nuget.org/packages/System.Diagnostics.EventLog) + ## Feedback & Contributing -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +**System.Diagnostics.PerformanceCounter** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 5cc655db0c358e0352425984e47c7bfb1e186fe8 Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Tue, 5 Sep 2023 10:12:30 -0700 Subject: [PATCH 205/783] Add package readme for System.Speech --- src/libraries/System.Speech/src/PACKAGE.md | 85 ++++++++++++++++++---- 1 file changed, 71 insertions(+), 14 deletions(-) diff --git a/src/libraries/System.Speech/src/PACKAGE.md b/src/libraries/System.Speech/src/PACKAGE.md index 2709a6e84e284f..76c80a6075f025 100644 --- a/src/libraries/System.Speech/src/PACKAGE.md +++ b/src/libraries/System.Speech/src/PACKAGE.md @@ -1,44 +1,101 @@ ## About +Provides APIs for speech recognition and synthesis built on the [Microsoft Speech API](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms723627(v=vs.85)) in Windows. Not supported on other non-Windows platforms. - +This package is provided primarily for compatibility with code being ported from .NETFramework and is not accepting new features. ## Key Features -* -* -* +* Recognize speech as text in a given language and grammar. +* Synthesize text as speech. +* Support for [Speech Recognition Grammar v1.0](https://www.w3.org/TR/speech-grammar/) documents ## How to Use +### Synthesis example +```C# +using System.Speech.Synthesis; + +// Initialize a new instance of the SpeechSynthesizer. +SpeechSynthesizer synth = new SpeechSynthesizer(); + +// Configure the audio output. +synth.SetOutputToDefaultAudioDevice(); + +// Speak a string, synchronously +synth.Speak("Hello World!"); + +// Speak a string asynchronously +var prompt = synth.SpeakAsync("Goodnight Moon!"); + +while(!prompt.IsCompleted) +{ + Console.WriteLine("speaking..."); + Thread.Sleep(500); +} +``` + +### Recognition example +```C# +// Create a new SpeechRecognitionEngine instance. +using SpeechRecognizer recognizer = new SpeechRecognizer(); +using ManualResetEvent exit = new ManualResetEvent(false); + +// Create a simple grammar that recognizes "red", "green", "blue", or "exit". +Choices choices = new Choices(); +choices.Add(new string[] { "red", "green", "blue", "exit" }); + +// Create a GrammarBuilder object and append the Choices object. +GrammarBuilder gb = new GrammarBuilder(); +gb.Append(choices); + +// Create the Grammar instance and load it into the speech recognition engine. +Grammar g = new Grammar(gb); +recognizer.LoadGrammar(g); + +// Register a handler for the SpeechRecognized event. +recognizer.SpeechRecognized += (s, e) => +{ + Console.WriteLine($"Recognized: {e.Result.Text}, Confidence: {e.Result.Confidence}"); + if (e.Result.Text == "exit") + { + exit.Set(); + } +}; + +// Emulate +Console.WriteLine("Emulating \"red\"."); +recognizer.EmulateRecognize("red"); + +Console.WriteLine("Speak red, green, blue, or exit please..."); + +exit.WaitOne(); +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `System.Speech.Recognition.SpeechRecognizer` +* `System.Speech.Synthesis.SpeechSynthesizer` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - +* [Conceptual documentation](https://learn.microsoft.com/en-us/previous-versions/office/developer/speech-technologies/hh361625(v%3doffice.14)) +* [Speech.Recognition API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.speech.recognition) +* [Speech.Synthesis API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.speech.synthesis) ## Feedback & Contributing -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +**System.Speech** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From a8b30f8fc19cad1a5ef50f7f85378df258ad5ab2 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Tue, 5 Sep 2023 11:20:28 -0700 Subject: [PATCH 206/783] Fill Microsoft.Extensions.Logging.Abstraction doc --- .../src/PACKAGE.md | 136 ++++++++++++++++-- 1 file changed, 128 insertions(+), 8 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/PACKAGE.md index 534ef37b23d3b0..400958a0a194a4 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/PACKAGE.md @@ -2,40 +2,160 @@ +`Microsoft.Extensions.Logging.Abstractions` provides abstractions of logging. Interfaces defined in this package are implemented by classes in [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging/) and other logging packages. +This package includes a logging source generator that produces highly efficient and optimized code for logging message methods. ## Key Features -* -* -* +* Define main logging abstraction interfaces like ILogger, ILoggerFactory, ILoggerProvider, etc. ## How to Use +#### Custom logger provider implementation example + +```C# +using Microsoft.Extensions.Logging; + +public sealed class ColorConsoleLogger : ILogger +{ + private readonly string _name; + private readonly Func _getCurrentConfig; + + public ColorConsoleLogger( + string name, + Func getCurrentConfig) => + (_name, _getCurrentConfig) = (name, getCurrentConfig); + + public IDisposable? BeginScope(TState state) where TState : notnull => default!; + + public bool IsEnabled(LogLevel logLevel) => + _getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel); + + public void Log( + LogLevel logLevel, + EventId eventId, + TState state, + Exception? exception, + Func formatter) + { + if (!IsEnabled(logLevel)) + { + return; + } + + ColorConsoleLoggerConfiguration config = _getCurrentConfig(); + if (config.EventId == 0 || config.EventId == eventId.Id) + { + ConsoleColor originalColor = Console.ForegroundColor; + + Console.ForegroundColor = config.LogLevelToColorMap[logLevel]; + Console.WriteLine($"[{eventId.Id,2}: {logLevel,-12}]"); + + Console.ForegroundColor = originalColor; + Console.Write($" {_name} - "); + + Console.ForegroundColor = config.LogLevelToColorMap[logLevel]; + Console.Write($"{formatter(state, exception)}"); + + Console.ForegroundColor = originalColor; + Console.WriteLine(); + } + } +} + +``` + +#### Create logs + +```csharp + +// Worker class that uses logger implementation of teh interface ILogger + +public sealed class Worker : BackgroundService +{ + private readonly ILogger _logger; + + public Worker(ILogger logger) => + _logger = logger; + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + while (!stoppingToken.IsCancellationRequested) + { + _logger.LogInformation("Worker running at: {time}", DateTimeOffset.UtcNow); + await Task.Delay(1_000, stoppingToken); + } + } +} + +``` + +#### Use source generator + +```csharp +public static partial class Log +{ + [LoggerMessage( + EventId = 0, + Level = LogLevel.Critical, + Message = "Could not open socket to `{hostName}`")] + public static partial void CouldNotOpenSocket(this ILogger logger, string hostName); +} + +public partial class InstanceLoggingExample +{ + private readonly ILogger _logger; + + public InstanceLoggingExample(ILogger logger) + { + _logger = logger; + } + + [LoggerMessage( + EventId = 0, + Level = LogLevel.Critical, + Message = "Could not open socket to `{hostName}`")] + public partial void CouldNotOpenSocket(string hostName); +} + +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `Microsoft.Extensions.Logging.ILogger` +* `Microsoft.Extensions.Logging.ILoggerProvider` +* `Microsoft.Extensions.Logging.ILoggerFactory` +* `Microsoft.Extensions.Logging.ILogger` +* `Microsoft.Extensions.Logging.LogLevel` +* `Microsoft.Extensions.Logging.Logger` +* `Microsoft.Extensions.Logging.LoggerMessage` +* `Microsoft.Extensions.Logging.Abstractions.NullLogger` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/dotnet/core/extensions/logging) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging) ## Related Packages +[Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging) +[Microsoft.Extensions.Logging.Console](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Console) +[Microsoft.Extensions.Logging.Debug](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Debug) +[Microsoft.Extensions.Logging.EventSource](https://www.nuget.org/packages/Microsoft.Extensions.Logging.EventSource) +[Microsoft.Extensions.Logging.EventLog](https://www.nuget.org/packages/Microsoft.Extensions.Logging.EventLog) +[Microsoft.Extensions.Logging.TraceSource](https://www.nuget.org/packages/Microsoft.Extensions.Logging.TraceSource) ## Feedback & Contributing From de6fd761b82f9112ee177f8656f527a255cf4f1c Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Tue, 5 Sep 2023 12:09:35 -0700 Subject: [PATCH 207/783] Fill Microsoft.Extensions.Logging doc --- .../src/PACKAGE.md | 121 ++++++++++++++++-- 1 file changed, 111 insertions(+), 10 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging/src/PACKAGE.md index 302b93b4956421..607283d3eb7486 100644 --- a/src/libraries/Microsoft.Extensions.Logging/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Logging/src/PACKAGE.md @@ -1,20 +1,112 @@ ## About - - +`Microsoft.Extensions.Logging` is combined with a core logging abstraction under `Microsoft.Extensions.Logging.Abstractions`. This abstraction is available in our basic built-in implementations like console, event log, and debug (Debug.WriteLine) logging. ## Key Features -* -* -* +* Provide concrete implementations of ILoggerFactory +* Provide extension methods for service collections, logger builder, and activity tracking +* Provide logging filtering extension methods for logger builder ## How to Use +Prior to .NET 6, we only had two forms possible for doing logging, using `Microsoft.Extensions.Logging`: + +```cs +public class LoggingSample1 +{ + private ILogger _logger; + + public LoggingSample1(ILogger logger) + { + _logger = logger; + } + + public void LogMethod(string name) + { + _logger.LogInformation("Hello {name}", name); + } +} +``` + +Here are some problems with the LoggingSample1 sample using `LogInformation`, `LogWarning`, etc.: + +1. We can provide event ID through these APIs, but they are not required today. Which leads to bad usages in real systems that want to react or detect specific event issues being logged. +2. Parameters passed are processed before LogLevel checks; this leads to unnecessary code paths getting triggered even when logging is disabled for a log level. +3. It requires parsing of message string on every use to find templates to substitute. + +Because of these problems, the more efficient runtime approach recommended as best practices is to use LoggerMessage.Define APIs instead, illustrated below with LoggingSample2: + +```cs +public class LoggingSample2 +{ + private ILogger _logger; + + public LoggingSample2(ILogger logger) + { + _logger = logger; + } + + public void LogMethod(string name) + { + Log.LogName(_logger, name); + } + + private static class Log + { + private static readonly Action _logName = LoggerMessage.Define(LogLevel.Information, 0, @"Hello {name}"); + + public static void LogName(ILogger logger, string name) + { + _logName(logger, name, null!); + } + } +} +``` + +To reach a balance between performance and usability we added the compile-time logging source generator feature in .NET 6, to learn more about it and learn how to use a source generator to create log messages check out [this documentation](https://learn.microsoft.com/dotnet/core/extensions/logger-message-generator). + +```csharp + +public partial class InstanceLoggingExample +{ + private readonly ILogger _logger; + + public InstanceLoggingExample(ILogger logger) + { + _logger = logger; + } + + [LoggerMessage( + EventId = 0, + Level = LogLevel.Critical, + Message = "Could not open socket to `{hostName}`")] + public partial void CouldNotOpenSocket(string hostName); +} +``` + +#### Baggage and Tags for `ActivityTrackingOptions` + +.NET 5.0 exposed a new feature that allows configuring the logger builder with the `ActivityTrackingOption` to add the tracing context Span Id, Trace Id, Parent Id, Trace state, and Trace flags to the logging scope. The tracing context usually carried in `Activity.Current`. + +.NET 6.0 Preview 1 extended this feature to include more tracing context properties which are the Baggage and the Tags: + +```cs + var loggerFactory = LoggerFactory.Create(logging => + { + logging.Configure(options => + { + options.ActivityTrackingOptions = ActivityTrackingOptions.Tags | ActivityTrackingOptions.Baggage; + }).AddSimpleConsole(options => + { + options.IncludeScopes = true; + }); + }); +``` ## Main Types @@ -22,20 +114,29 @@ The main types provided by this library are: -* `` -* `` -* `` +* LoggingServiceCollectionExtensions +* LoggerFactory +* LoggerFactoryOptions +* LoggingBuilderExtensions +* ActivityTrackingOptions +* FilterLoggingBuilderExtensions ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/dotnet/core/extensions/logging) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging) ## Related Packages +[Microsoft.Extensions.Logging.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Abstractions) +[Microsoft.Extensions.Logging.Console](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Console) +[Microsoft.Extensions.Logging.Debug](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Debug) +[Microsoft.Extensions.Logging.EventSource](https://www.nuget.org/packages/Microsoft.Extensions.Logging.EventSource) +[Microsoft.Extensions.Logging.EventLog](https://www.nuget.org/packages/Microsoft.Extensions.Logging.EventLog) +[Microsoft.Extensions.Logging.TraceSource](https://www.nuget.org/packages/Microsoft.Extensions.Logging.TraceSource) ## Feedback & Contributing From 0c4d908af8af33ef1feddc4bbf164e96e681e3ea Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Tue, 5 Sep 2023 12:36:37 -0700 Subject: [PATCH 208/783] Fill Microsoft.Extensions.Logging.Console doc --- .../src/PACKAGE.md | 83 ++++++++++++++++--- 1 file changed, 73 insertions(+), 10 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.Console/src/PACKAGE.md index 582bba45f12169..b35f529af9c06c 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/PACKAGE.md @@ -1,20 +1,71 @@ ## About - - +`Microsoft.Extensions.Logging.Console` provides a Console logger provider implementation for Microsoft.Extensions.Logging. It provides extension methods for the [ILoggingBuilder](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.iloggingbuilder) and [ILoggerProviderConfiguration](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.configuration.iloggerproviderconfiguration-1) classes. ## Key Features -* -* -* +* Allow logging to the console using the [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging/) package. +* Provide extension methods for the [ILoggingBuilder](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.iloggingbuilder) and [ILoggerProviderConfiguration](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.configuration.iloggerproviderconfiguration-1) classes. + ## How to Use +```csharp +using System; +using Microsoft.Extensions.Logging; + +namespace ConsoleLoggerSample +{ + class Program + { + static void Main(string[] args) + { + // Create a logger factory with a console provider + using ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); + + // Create a logger with the category name of the current class + ILogger logger = loggerFactory.CreateLogger(); + + // Log some messages with different log levels and message templates + logger.LogTrace("This is a trace message."); + logger.LogDebug("This is a debug message."); + logger.LogInformation("Hello {Name}!", "World"); + logger.LogWarning("This is a warning message."); + logger.LogError("This is an error message."); + logger.LogCritical("This is a critical message."); + + // Use structured logging to capture complex data + var person = new Person { Name = "Alice", Age = 25 }; + logger.LogInformation("Created a new person: {@Person}", person); + + // Use exception logging to capture the details of an exception + try + { + throw new Exception("Something went wrong."); + } + catch (Exception ex) + { + logger.LogError(ex, "An exception occurred."); + } + + Console.WriteLine("Press any key to exit."); + Console.ReadKey(); + } + } + + // A simple class to demonstrate structured logging + class Person + { + public string Name { get; set; } + public int Age { get; set; } + } +} + +``` ## Main Types @@ -22,20 +73,32 @@ The main types provided by this library are: -* `` -* `` -* `` +* `ConsoleLoggerProvider` +* `ConsoleLoggerSettings` +* `ConsoleLoggerOptions` +* `ConsoleLoggerExtensions` +* `ConsoleFormatter` +* `ConsoleFormatterOptions` +* `JsonConsoleFormatterOptions` +* `SimpleConsoleFormatterOptions` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/dotnet/core/extensions/logging) +* [Console log formatter](https://learn.microsoft.com/dotnet/core/extensions/console-log-formatter) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging) ## Related Packages +[Microsoft.Extensions.Logging.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Abstractions) +[Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging) +[Microsoft.Extensions.Logging.Debug](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Debug) +[Microsoft.Extensions.Logging.EventSource](https://www.nuget.org/packages/Microsoft.Extensions.Logging.EventSource) +[Microsoft.Extensions.Logging.EventLog](https://www.nuget.org/packages/Microsoft.Extensions.Logging.EventLog) +[Microsoft.Extensions.Logging.TraceSource](https://www.nuget.org/packages/Microsoft.Extensions.Logging.TraceSource) ## Feedback & Contributing From 9e084bea10bfc762cf80dcdc9da5b87e0fced09f Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Tue, 5 Sep 2023 12:57:26 -0700 Subject: [PATCH 209/783] Fill Microsoft.Extensions.Logging.Debug doc --- .../src/PACKAGE.md | 75 ++++++++++++++++--- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Debug/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.Debug/src/PACKAGE.md index b933164215cb84..8a5c652290643e 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Debug/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Logging.Debug/src/PACKAGE.md @@ -1,20 +1,72 @@ ## About - +`Microsoft.Extensions.Logging.Debug` provides a Debug output logger provider implementation for Microsoft.Extensions.Logging. This logger logs messages to a debugger monitor by writing messages with `System.Diagnostics.Debug.WriteLine()`. ## Key Features -* -* -* +* Allow logging to the debugger output. +* Provide extensions method for the [ILoggingBuilder](https://docs.microsoft.com/dotnet/api/microsoft.extensions.logging.iloggingbuilder) class to easily enable this Debug logger. ## How to Use +```csharp +using System; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Debug; + +namespace DebugLoggerSample +{ + class Program + { + static void Main(string[] args) + { + // Create a logger factory with a debug provider + using ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder.AddDebug()); + + // Create a logger with the category name of the current class + ILogger logger = loggerFactory.CreateLogger(); + + // Log some messages with different log levels and message templates + logger.LogTrace("This is a trace message."); + logger.LogDebug("This is a debug message."); + logger.LogInformation("Hello {Name}!", "World"); + logger.LogWarning("This is a warning message."); + logger.LogError("This is an error message."); + logger.LogCritical("This is a critical message."); + + // Use structured logging to capture complex data + var person = new Person { Name = "Alice", Age = 25 }; + logger.LogInformation("Created a new person: {@Person}", person); + + // Use exception logging to capture the details of an exception + try + { + throw new Exception("Something went wrong."); + } + catch (Exception ex) + { + logger.LogError(ex, "An exception occurred."); + } + + Console.WriteLine("Press any key to exit."); + Console.ReadKey(); + } + } + + // A simple class to demonstrate structured logging + class Person + { + public string Name { get; set; } + public int Age { get; set; } + } +} + +``` ## Main Types @@ -22,18 +74,23 @@ The main types provided by this library are: -* `` -* `` -* `` +* `DebugLoggerProvider` +* `DebugLoggerFactoryExtensions` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/dotnet/core/extensions/logging) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging) ## Related Packages +[Microsoft.Extensions.Logging.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Abstractions) +[Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging) +[Microsoft.Extensions.Logging.Console](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Console) +[Microsoft.Extensions.Logging.EventSource](https://www.nuget.org/packages/Microsoft.Extensions.Logging.EventSource) +[Microsoft.Extensions.Logging.EventLog](https://www.nuget.org/packages/Microsoft.Extensions.Logging.EventLog) +[Microsoft.Extensions.Logging.TraceSource](https://www.nuget.org/packages/Microsoft.Extensions.Logging.TraceSource) From 030a4db778ab02074b1ba43beb1dbed1a1a8261b Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Tue, 5 Sep 2023 17:34:15 -0400 Subject: [PATCH 210/783] Add Microsoft.Bcl.Async package.md details --- .../src/PACKAGE.md | 50 +++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/PACKAGE.md index 7a9788f170fb42..a4a5af4a370f6f 100644 --- a/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/PACKAGE.md +++ b/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/PACKAGE.md @@ -1,41 +1,61 @@ ## About - - - +As of C# 8, the C# language has support for producing and consuming asynchronous iterators. The library types in support of those features are available in .NET Core 3.0 and newer as well as in .NET Standard 2.1. This library provides the necessary definitions of those types to support these language features on .NET Framework and on .NET Standard 2.0. This library is not necessary nor recommended when targeting versions of .NET that include the relevant support. ## Key Features -* -* -* +* Enables the use of C# async iterators on older .NET platforms ## How to Use +```C# +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +internal static class Program +{ + private static async Task Main() + { + Console.WriteLine("Starting..."); + await foreach (var value in GetValuesAsync()) + { + Console.WriteLine(value); + } + Console.WriteLine("Finished!"); + + static async IAsyncEnumerable GetValuesAsync() + { + for (int i = 0; i < 10; i++) + { + await Task.Delay(TimeSpan.FromSeconds(1)); + yield return i; + } + } + } +} +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `IAsyncEnumerable` +* `IAsyncEnumerator` +* `IAsyncDisposable` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - +* [C# Feature Specification](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/async-streams) +* [Walkthrough article](https://learn.microsoft.com/archive/msdn-magazine/2019/november/csharp-iterating-with-async-enumerables-in-csharp-8) ## Feedback & Contributing From 00c840673390caf4ca72c526a0e09776d30d4091 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Tue, 5 Sep 2023 17:43:54 -0400 Subject: [PATCH 211/783] Add System.Threading.Channels package.md details --- .../System.Threading.Channels/src/PACKAGE.md | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Threading.Channels/src/PACKAGE.md b/src/libraries/System.Threading.Channels/src/PACKAGE.md index 2709a6e84e284f..cd9c6b829e10bb 100644 --- a/src/libraries/System.Threading.Channels/src/PACKAGE.md +++ b/src/libraries/System.Threading.Channels/src/PACKAGE.md @@ -2,43 +2,72 @@ - +The `System.Threading.Channels` library provides types for passing data asynchronously between producers and consumers. ## Key Features -* -* -* +* Abstractions representing channels for one or more producers to publish data to one or more consumers +* APIs focused on asynchronous production and consumption of data +* Factory methods for producing multiple kinds of channels ## How to Use +```C# +using System; +using System.Threading.Channels; +using System.Threading.Tasks; + +Channel channel = Channel.CreateUnbounded(); + +Task producer = Task.Run(async () => +{ + int i = 0; + while (true) + { + channel.Writer.TryWrite(i++); + await Task.Delay(TimeSpan.FromSeconds(1)); + } +}); + +Task consumer = Task.Run(async () => +{ + await foreach (int value in channel.Reader.ReadAllAsync()) + { + Console.WriteLine(value); + } +}); + +await Task.WhenAll(producer, consumer); +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `System.Threading.Channel` +* `System.Threading.Channel` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Overview](https://devblogs.microsoft.com/dotnet/an-introduction-to-system-threading-channels/) +* [API documentation](https://learn.microsoft.com/dotnet/api/system.threading.channels) ## Related Packages +https://www.nuget.org/packages/System.Threading.Tasks.Dataflow/ + ## Feedback & Contributing -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +**System.Threading.Channels** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file From 9c0253dbe4b8e86f47b780ca0a047431c0423040 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Tue, 5 Sep 2023 15:00:48 -0700 Subject: [PATCH 212/783] Fill Microsoft.Extensions.Primitives doc --- .../src/PACKAGE.md | 109 ++++++++++++++---- 1 file changed, 87 insertions(+), 22 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Primitives/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Primitives/src/PACKAGE.md index db0a84ec52694c..432abfa969f057 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Primitives/src/PACKAGE.md @@ -1,44 +1,109 @@ ## About - - - +`Microsoft.Extensions.Primitives` contains isolated types that are used in many places within console or ASP.NET Core applications using framework extensions. ## Key Features - - -* -* -* +* IChangeToken: An interface that represents a token that can notify when a change occurs. This can be used to trigger actions or invalidate caches when something changes. For example, the configuration and file providers libraries use this interface to reload settings or files when they are modified. +* StringValues: A struct that represents a single string or an array of strings. This can be used to efficiently store and manipulate multiple values that are logically a single value. For example, the HTTP headers and query strings libraries use this struct to handle multiple values for the same key. +* StringSegment: A struct that represents a substring of another string. This can be used to avoid allocating new strings when performing operations on parts of a string. For example, the configuration and logging libraries use this struct to parse and format strings. ## How to Use - - +#### IChangeToken with configuration example + +```C# +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Primitives; +using System; + +class Program +{ + static void Main(string[] args) + { + // Create a configuration builder + var configurationBuilder = new ConfigurationBuilder() + .SetBasePath(Environment.CurrentDirectory) + // appsettings.json expected to have the following contents: + // { + // "SomeKey": "SomeValue" + // } + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); + + // Build the configuration + IConfiguration configuration = configurationBuilder.Build(); + + // Create a change token for the configuration + IChangeToken changeToken = configuration.GetReloadToken(); + + // Attach a change callback + IDisposable changeTokenRegistration = changeToken.RegisterChangeCallback(state => + { + Console.WriteLine("Configuration changed!"); + IConfigurationRoot root = (IConfigurationRoot)state; + var someValue = root["SomeKey"]; // Access the updated configuration value + Console.WriteLine($"New value of SomeKey: {someValue}"); + }, configuration); + + // go and update the value of the key SomeKey in appsettings.json. + // The change callback will be invoked when the file is saved. + Console.WriteLine("Listening for configuration changes. Press any key to exit."); + Console.ReadKey(); + + // Clean up the change token registration when no longer needed + changeTokenRegistration.Dispose(); + } +} +``` +#### StringValues example + +```C# +using System; +using Microsoft.Extensions.Primitives; + +namespace StringValuesSample +{ + class Program + { + static void Main(string[] args) + { + // Create a StringValues object from a single string or an array of strings + StringValues single = "Hello"; + StringValues multiple = new string[] { "Hello", "World" }; + + // Use the implicit conversion to string or the ToString method to get the values + Console.WriteLine($"Single: {single}"); // Single: Hello + Console.WriteLine($"Multiple: {multiple}"); // Multiple: Hello,World + + // Use the indexer, the Count property, and the IsNullOrEmpty method to access the values + Console.WriteLine($"Multiple[1]: {multiple[1]}"); // Multiple[1]: World + Console.WriteLine($"Single.Count: {single.Count}"); // Single.Count: 1 + Console.WriteLine($"Multiple.IsNullOrEmpty: {StringValues.IsNullOrEmpty(multiple)}"); // Multiple.IsNullOrEmpty: False + + // Use the Equals method or the == operator to compare two StringValues objects + Console.WriteLine($"single == \"Hello\": {single == "Hello"}"); // single == "Hello": True + Console.WriteLine($"multiple == \"Hello\": {multiple == "Hello"}"); // multiple == "Hello": False + } + } +} +``` ## Main Types - - The main types provided by this library are: -* `` -* `` -* `` +* `IChangeToken` +* `StringValues` +* `StringSegment` ## Additional Documentation - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/dotnet/core/extensions/primitives) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.primitives) ## Related Packages - +* [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration) ## Feedback & Contributing - - Microsoft.Extensions.Primitives is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file From 685a2138a27a543aedd9d04e15018a95f1113252 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Tue, 5 Sep 2023 15:51:53 -0700 Subject: [PATCH 213/783] Remove trailing spaces from Speech doc file --- src/libraries/System.Speech/src/PACKAGE.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Speech/src/PACKAGE.md b/src/libraries/System.Speech/src/PACKAGE.md index 76c80a6075f025..0b39583a424016 100644 --- a/src/libraries/System.Speech/src/PACKAGE.md +++ b/src/libraries/System.Speech/src/PACKAGE.md @@ -1,7 +1,7 @@ ## About -Provides APIs for speech recognition and synthesis built on the [Microsoft Speech API](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms723627(v=vs.85)) in Windows. Not supported on other non-Windows platforms. +Provides APIs for speech recognition and synthesis built on the [Microsoft Speech API](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms723627(v=vs.85)) in Windows. Not supported on other non-Windows platforms. This package is provided primarily for compatibility with code being ported from .NETFramework and is not accepting new features. @@ -18,14 +18,14 @@ This package is provided primarily for compatibility with code being ported from ### Synthesis example -```C# +```C# using System.Speech.Synthesis; -// Initialize a new instance of the SpeechSynthesizer. -SpeechSynthesizer synth = new SpeechSynthesizer(); +// Initialize a new instance of the SpeechSynthesizer. +SpeechSynthesizer synth = new SpeechSynthesizer(); -// Configure the audio output. -synth.SetOutputToDefaultAudioDevice(); +// Configure the audio output. +synth.SetOutputToDefaultAudioDevice(); // Speak a string, synchronously synth.Speak("Hello World!"); @@ -64,11 +64,11 @@ recognizer.SpeechRecognized += (s, e) => Console.WriteLine($"Recognized: {e.Result.Text}, Confidence: {e.Result.Confidence}"); if (e.Result.Text == "exit") { - exit.Set(); + exit.Set(); } }; -// Emulate +// Emulate Console.WriteLine("Emulating \"red\"."); recognizer.EmulateRecognize("red"); From 57f6eedd05ce784d66a9bd7a2dc3312a6a2eaa89 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Tue, 5 Sep 2023 16:52:01 -0700 Subject: [PATCH 214/783] Fill Microsoft.Extensions.Options doc --- .../src/PACKAGE.md | 166 +++++++++++++++--- 1 file changed, 146 insertions(+), 20 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Options/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Options/src/PACKAGE.md index 220873bc79027f..ee0cc2ab6f99ee 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Options/src/PACKAGE.md @@ -1,44 +1,170 @@ ## About +`Microsoft.Extensions.Options` provides a strongly typed way of specifying and accessing settings using dependency injection and acts as a bridge between configuration, DI, and higher level libraries. This library is the glue for how an app developer uses DI to configure the behavior of a library like HttpClient Factory. This also enables user to get a strongly-typed view of their configuration. - +Within this package, you'll find an options validation source generator that generates exceptionally efficient and optimized code for validating options. +## Key Features +* Offer the IValidateOptions interface for the validation of options, along with several generic ValidateOptions classes that implement this interface. +* OptionsBuilder to configure options. +* Provide extension methods for service collections and options builder to register options and validate options. +* Supply a set of generic ConfigureNamedOptions classes that implement the IConfigureNamedOptions interface for configuring named options. +* Provide a source generator that generates validation code for options. +* Options caching, managing and monitoring. -## Key Features +## How to Use - +#### Options validation example -* -* -* +```C# +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; -## How to Use +var builder = WebApplication.CreateBuilder(args); - +builder.Services.AddControllersWithViews(); -## Main Types +// Load the configuration and validate it +builder.Services.AddOptions() + .Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig)) + .ValidateDataAnnotations(); +var app = builder.Build(); - + +// Declare the option class to validate +public class MyConfigOptions +{ + public const string MyConfig = "MyConfig"; + + [RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$")] + public string Key1 { get; set; } + [Range(0, 1000, + ErrorMessage = "Value for {0} must be between {1} and {2}.")] + public int Key2 { get; set; } + public int Key3 { get; set; } +} +``` + +#### Using IValidateOptions to validate options + +```C# +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllersWithViews(); + +// Configuration to validate +builder.Services.Configure(builder.Configuration.GetSection( + MyConfigOptions.MyConfig)); + +// OPtions validation through the DI container +builder.Services.AddSingleton, MyConfigValidation>(); + +var app = builder.Build(); + +public class MyConfigValidation : IValidateOptions +{ + public MyConfigOptions _config { get; private set; } + + public MyConfigValidation(IConfiguration config) + { + _config = config.GetSection(MyConfigOptions.MyConfig) + .Get(); + } + + public ValidateOptionsResult Validate(string name, MyConfigOptions options) + { + string? vor = null; + var rx = new Regex(@"^[a-zA-Z''-'\s]{1,40}$"); + var match = rx.Match(options.Key1!); + + if (string.IsNullOrEmpty(match.Value)) + { + vor = $"{options.Key1} doesn't match RegEx \n"; + } + + if ( options.Key2 < 0 || options.Key2 > 1000) + { + vor = $"{options.Key2} doesn't match Range 0 - 1000 \n"; + } + + if (_config.Key2 != default) + { + if(_config.Key3 <= _config.Key2) + { + vor += "Key3 must be > than Key2."; + } + } + + if (vor != null) + { + return ValidateOptionsResult.Fail(vor); + } + + return ValidateOptionsResult.Success; + } +} + +``` + +#### Options Validation Source Generator Example + +```C# +using System; +using System.ComponentModel.DataAnnotations; +using Microsoft.Extensions.Options; + +public class MyConfigOptions +{ + [RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$")] + public string Key1 { get; set; } + + [Range(0, 1000, + ErrorMessage = "Value for {0} must be between {1} and {2}.")] + public int Key2 { get; set; } + public int Key3 { get; set; } +} + +[OptionsValidator] +public partial class MyConfigValidation : IValidateOptions +{ + // Source generator will automatically provide the implementation of IValidateOptions + // Then you can add the validation to the DI Container using the following code: + // + // builder.Services.AddSingleton, MyConfigValidation>(); + // builder.Services.AddOptions() + // .Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig)) + // .ValidateDataAnnotations(); +} + +``` + +## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `IOptions`, `IOptionsFactory`, and `IOptionsMonitor` +* `IValidateOptions` and `ValidateOptions` +* `OptionsBuilder`, `OptionsFactory`, `OptionsMonitor`, and `OptionsManager` +* `OptionsServiceCollectionExtensions` +* `OptionsValidatorAttribute` ## Additional Documentation - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/aspnet/core/fundamentals/configuration/options) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.options) ## Related Packages - +[Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging) +[Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration) ## Feedback & Contributing - - Microsoft.Extensions.Options is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file From e6202a785d6ef5db2cf0723e357a3c16dc44db8f Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Tue, 5 Sep 2023 17:33:29 -0700 Subject: [PATCH 215/783] Fill System.Text.Encoding.CodePages doc --- .../src/PACKAGE.md | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/libraries/System.Text.Encoding.CodePages/src/PACKAGE.md b/src/libraries/System.Text.Encoding.CodePages/src/PACKAGE.md index 2709a6e84e284f..87e4c8054b2fd6 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/PACKAGE.md +++ b/src/libraries/System.Text.Encoding.CodePages/src/PACKAGE.md @@ -1,44 +1,39 @@ ## About - +`System.Text.Encoding.CodePages` enable creating single and double bytes encodings for code pages that otherwise are available only in the desktop .NET Framework. +## Key Features +* Support single and double byte encodings for code pages that are not available in .NET Core. -## Key Features +## How to Use - +```csharp +using System.Text; -* -* -* +// Register the CodePages encoding provider at application startup to enable using single and double byte encodings. +Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); -## How to Use +// Now can create single and double byte encodings for code pages that are not available in .NET Core. +Encoding windows1252Encoding = Encoding.GetEncoding(1252); // Western European (Windows) +byte[] encodedBytes = windows1252Encoding.GetBytes("String to encode"); - +``` ## Main Types - - The main types provided by this library are: -* `` -* `` -* `` +* `CodePagesEncodingProvider` ## Additional Documentation - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [API documentation](https://learn.microsoft.com/dotnet/api/system.text.codepagesencodingprovider) ## Related Packages - +* [System.Text.Encodings.Web](https://www.nuget.org/packages/System.Text.Encodings.Web) ## Feedback & Contributing - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +System.Text.Encoding.CodePages is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file From 795122ab786eb3075a8d114e694890581e18c452 Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Wed, 6 Sep 2023 09:27:14 +0200 Subject: [PATCH 216/783] Add System.IO.Ports --- src/libraries/System.IO.Ports/src/PACKAGE.md | 38 +++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.IO.Ports/src/PACKAGE.md b/src/libraries/System.IO.Ports/src/PACKAGE.md index 2709a6e84e284f..b450bd4318cb3e 100644 --- a/src/libraries/System.IO.Ports/src/PACKAGE.md +++ b/src/libraries/System.IO.Ports/src/PACKAGE.md @@ -1,44 +1,58 @@ ## About - - +[System.IO.Ports](https://www.nuget.org/packages/System.IO.Ports) package provides synchronous serial port file resource. Additionally, the functionality of this class can be wrapped in an internal `Stream` object, accessible through the `BaseStream` property, and passed to classes that wrap or use streams. ## Key Features -* -* -* +* synchronous and event-driven I/O +* access to pin and break states +* access to serial driver properties +* access to `Stream` object through the `BaseStream` property ## How to Use +```C# +using System.IO.Ports; + +// Provides list of available serial ports +string[] portNames = SerialPort.GetPortNames(); + +// First available port +string myPortName = portNames[0]; +int baudRate = 9600; + +SerialPort sp = new SerialPort(myPortName, baudRate); +sp.Open(); +sp.WriteLine("Hello World!"); +``` + ## Main Types -The main types provided by this library are: +The main type provided by this library is: -* `` -* `` -* `` +* `SerialPort` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [SerialPort class documentation](https://learn.microsoft.com/en-us/dotnet/api/system.io.ports.serialport?view=dotnet-plat-ext-7.0) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/System.IO.Ports) ## Related Packages +- [System.IO.Ports](https://www.nuget.org/packages/System.IO.Ports) ## Feedback & Contributing -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +**System.IO.Ports** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 225186ae0beee426f181839473a75545bdd3c0d4 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Wed, 6 Sep 2023 16:40:23 +0100 Subject: [PATCH 217/783] Add System.Net.Http.Json README --- .../System.Net.Http.Json/src/PACKAGE.md | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/src/libraries/System.Net.Http.Json/src/PACKAGE.md b/src/libraries/System.Net.Http.Json/src/PACKAGE.md index 2709a6e84e284f..5c084900142c12 100644 --- a/src/libraries/System.Net.Http.Json/src/PACKAGE.md +++ b/src/libraries/System.Net.Http.Json/src/PACKAGE.md @@ -1,44 +1,50 @@ ## About - +Provides extension methods for `System.Net.Http.HttpClient` and `System.Net.Http.HttpContent` that facilitate serialization and deserialization of HTTP requests using System.Text.Json. +## Key Features +* Extension methods for deserializing HTTP response JSON bodies. +* Extension methods for serializing HTTP request JSON bodies. +* Extension methods for deserializing JSON from `HttpContent` instances. -## Key Features +## How to Use - +```C# +using System.Net.Http.Json; -* -* -* +using var client = new HttpClient(); -## How to Use +// Get the list of all books +Book[] books = await client.GetFromJsonAsync("https://api.contoso.com/books"); - +// Send a POST request to add a new book +var book = new Book(id: 42, "Title", "Author", publishedYear: 2023); +HttpResponseMessage response = await client.PostAsJsonAsync($"https://api.contoso.com/books/{book.id}", book); -## Main Types +if (response.IsSuccessStatusCode) + Console.WriteLine("Book added successfully."); +else + Console.WriteLine($"HTTP request failed with status code: {response.StatusCode}"); - +public record Book(int id, string title, string author, int publishedYear); +``` + +## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `HttpClientJsonExtensions` +* `HttpContentJsonExtensions` ## Additional Documentation - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [API documentation](https://learn.microsoft.com/dotnet/api/system.net.http.json) ## Related Packages - +* [System.Text.Json](https://www.nuget.org/packages/System.Text.Json) ## Feedback & Contributing - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +**System.Net.Http.Json** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 0597c3730f643d338efebfd6bd05135f06f411c7 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 6 Sep 2023 18:18:55 +0200 Subject: [PATCH 218/783] Readme for WinHttpHandler --- .../src/PACKAGE.md | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md b/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md index 2709a6e84e284f..ab0ba9b13aab92 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md @@ -1,44 +1,48 @@ ## About - +This package provides an [`HttpMessageHandler`](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpmessagehandler) implementation backed by [Windows HTTP Services (WinHTTP)](https://learn.microsoft.com/en-us/windows/win32/winhttp/winhttp-start-page). +While the use of the default `HttpClientHandler` is highly recommended for applications targeting modern .NET, `WinHttpHandler` might help migration scenarios by providing an alternative HTTP backend for Windows that works consistently accross .NET Framework and modern .NET. +## Key Features +* Enables sending *asynchronous* HTTP requests with `HttpClient` on Windows. +* Handles authentication and credentials. +* Exposes a subset of WinHTTP options as C# properties on `WinHttpHandler`. +* Use custom proxy. +* Handle cookies. -## Key Features +## How to Use - +```C# +using System.Net; -* -* -* +using WinHttpHandler handler = new() +{ + ServerCredentials = new NetworkCredential("usr", "pwd") +}; -## How to Use +using HttpClient client = new(handler); +using HttpRequestMessage request = new(HttpMethod.Get, "https://httpbin.org/basic-auth/usr/pwd"); +using HttpResponseMessage response = await client.SendAsync(request); - +Console.WriteLine($"Status: {response.StatusCode}"); +if (response.IsSuccessStatusCode) +{ + string content = await response.Content.ReadAsStringAsync(); + Console.WriteLine(content); +} +``` ## Main Types - - The main types provided by this library are: -* `` -* `` -* `` +* `System.Net.Http.WinHttpHandler` ## Additional Documentation - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.winhttphandler) ## Feedback & Contributing - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +**System.Net.Http.WinHttpHandler** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From f17e38184583b07994146f9ab6395795ab4d4ea3 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Wed, 6 Sep 2023 11:39:41 -0700 Subject: [PATCH 219/783] Fill Microsoft.Extensions.Options.ConfigurationExtensions doc --- .../src/PACKAGE.md | 143 +++++++++++++++--- 1 file changed, 122 insertions(+), 21 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/PACKAGE.md index 1609a20ac51d7b..c893fd4f0e3204 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/PACKAGE.md @@ -1,44 +1,145 @@ ## About - - - +`Microsoft.Extensions.Options.ConfigurationExtensions` provides additional configuration-specific functionality related to Options. ## Key Features - - -* -* -* +* Extension methods for OptionsBuilder for configuration binding +* Extension methods for IServiceCollection for Options configuration +* ConfigurationChangeTokenSource for monitoring configuration changes ## How to Use - +#### Options Configuration binding + +```csharp +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +class Program +{ + // appsettings.json contents: + // { + // "MyOptions": { + // "Setting1": "Value1", + // "Setting2": "Value2" + // } + // } + + static void Main(string[] args) + { + IConfiguration configuration = new ConfigurationBuilder() + .SetBasePath(Environment.CurrentDirectory) + .AddJsonFile("appsettings.json") + .Build(); + + IServiceCollection services = new ServiceCollection(); + + // Bind the configuration to MyOptions + services.Configure(configuration.GetSection("MyOptions")); + + IServiceProvider serviceProvider = services.BuildServiceProvider(); + + // Retrieve MyOptions using dependency injection + var myOptions = serviceProvider.GetRequiredService>().Value; + + // Access the bound configuration values + Console.WriteLine($"Setting1: {myOptions.Setting1}"); + Console.WriteLine($"Setting2: {myOptions.Setting2}"); + } +} + +public class MyOptions +{ + public string Setting1 { get; set; } + public string Setting2 { get; set; } +} + +``` + +#### Monitoring options configuration changes + +```csharp +// Assume we have a class that represents some options +public class MyOptions +{ + public string Name { get; set; } + public int Age { get; set; } +} + +// appsettings.json contents: +// { +// "MyOptions": { +// "Name": "Alice", +// "Age": 25 +// } +// } + +// Assume we have a configuration object that contains some settings +var config = new ConfigurationBuilder() + .AddJsonFile("appsettings.json") + .Build(); + +// We can use the ConfigurationChangeTokenSource to create a change token source for the options +var changeTokenSource = new ConfigurationChangeTokenSource(config.GetSection("MyOptions")); + +// We can register the change token source with the options monitor +services.AddOptions() + .Configure(options => + { + // Configure the options with the configuration values + config.GetSection("MyOptions").Bind(options); + }) + .AddChangeTokenSource(changeTokenSource); + +// Now we can inject the options monitor into any class that needs them +public class MyClass +{ + private readonly IOptionsMonitor _optionsMonitor; + + public MyClass(IOptionsMonitor optionsMonitor) + { + _optionsMonitor = optionsMonitor; + } + + public void DoSomething() + { + // Can access the current options value like this + var options = _optionsMonitor.CurrentValue; + var name = options.Name; + var age = options.Age; + // Do something with name and age + + // Can also register a callback to be notified when the options change + _optionsMonitor.OnChange(newOptions => + { + // Do something when the options change + }); + } +} + +``` ## Main Types - - The main types provided by this library are: -* `` -* `` -* `` +* `ConfigurationChangeTokenSource` +* `OptionsBuilderConfigurationExtensions` +* `OptionsConfigurationServiceCollectionExtensions` ## Additional Documentation - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/aspnet/core/fundamentals/configuration/options) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.options) ## Related Packages - +* [Microsoft.Extensions.Options](https://www.nuget.org/packages/Microsoft.Extensions.Options) +* [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration) +* [Microsoft.Extensions.DependencyInjection](https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection) ## Feedback & Contributing - - Microsoft.Extensions.Options.ConfigurationExtensions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file From c5653f7700797178516d757851625c488b58691a Mon Sep 17 00:00:00 2001 From: Natalia Kondratyeva Date: Wed, 6 Sep 2023 22:04:45 +0200 Subject: [PATCH 220/783] Update Microsoft.Extensions.Http --- .../Microsoft.Extensions.Http/src/PACKAGE.md | 57 +++++++++++++++---- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md index 7effd1dfd486cf..bf1cc0ef79e7e2 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md @@ -2,43 +2,80 @@ - +[Microsoft.Extensions.Http](https://www.nuget.org/packages/Microsoft.Extensions.Http) package provides `AddHttpClient` extension methods for `IServiceCollection`, `IHttpClientFactory` interface and its default implementation. This provides the ability to set up named `HttpClient` configurations in a DI container and later retrieve them via an injected `IHttpClientFactory` instance. ## Key Features -* -* -* +* The package allows to fluently set up multiple `HttpClient` configurations for applications that use DI via `AddHttpClient` extension method. +* `HttpClientFactory` caches `HttpMessageHandler` instances per configuration name, which allows to reuse resources between `HttpClient` instances to avoid port exhaustion. +* `HttpClientFactory` manages lifetime of `HttpMessageHandler` instances and recycles connections to avoid losing DNS changes. ## How to Use +Note that lifetime management of `HttpClient` instances created by `HttpClientFactory` is completely different from instances created manually. The strategies are to use either short-lived clients created by `HttpClientFactory` or long-lived clients with `PooledConnectionLifetime` set up. For more information, see the [HttpClient lifetime management section](https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory#httpclient-lifetime-management) in the conceptual docs and [Guidelines for using HTTP clients](https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient-guidelines). + +### Configuring HttpClient + +```c# +builder.Services.AddHttpClient("foo"); // adding an HttpClient named "foo" with a default configuration + +builder.Services.AddHttpClient("example", c => c.BaseAddress = new Uri("https://www.example.com")) // configuring HttpClient itself + .AddHttpMessageHandler() // adding additional delegating handlers to form a message handler chain + .ConfigurePrimaryHttpMessageHandler(b => new HttpClientHandler() { AllowAutoRedirect = false }) // configuring primary handler + .SetHandlerLifetime(TimeSpan.FromMinutes(30)); // changing the handler recycling interval +``` + +### Using the configured HttpClient + +```c# +public class MyService +{ + public MyService(IHttpClientFactory httpClientFactory) + { + _httpClientFactory = httpClientFactory; // injecting the factory + } + + private Task GetExampleAsync(Uri uri, CancellationToken ct) + { + HttpClient exampleClient = _httpClientFactory.CreateClient("example"); // creating the client for the specified name + return exampleClient.GetStringAsync(uri, ct); // using the client + } +} +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `IHttpClientFactory` +* `IHttpMessageHandlerFactory` +* `HttpClientFactoryServiceCollectionExtensions` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory) + * Also see [HttpClient guidelines](https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient-guidelines) conceptual doc +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.net.http?view=dotnet-plat-ext-7.0) + * Also see [`AddHttpClient` extension method](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.httpclientfactoryservicecollectionextensions?view=dotnet-plat-ext-7.0) API doc ## Related Packages +* [Microsoft.Extensions.DependencyInjection](https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection/) +* [Microsoft.Extensions.Http.Polly](https://www.nuget.org/packages/Microsoft.Extensions.Http.Polly) +* [Microsoft.Extensions.Http.Telemetry](https://www.nuget.org/packages/Microsoft.Extensions.Http.Telemetry) + ## Feedback & Contributing -Microsoft.Extensions.Http is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.Http is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From dd2fa092fbf69aac8d72d0bd554774d220e78f06 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Wed, 6 Sep 2023 13:56:28 -0700 Subject: [PATCH 221/783] Fill Microsoft.Bcl.TimeProvider doc --- .../Microsoft.Bcl.TimeProvider/src/PACKAGE.md | 60 ++++++++++++------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/src/libraries/Microsoft.Bcl.TimeProvider/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.TimeProvider/src/PACKAGE.md index 90901aee2d59c7..bf767f3354d39a 100644 --- a/src/libraries/Microsoft.Bcl.TimeProvider/src/PACKAGE.md +++ b/src/libraries/Microsoft.Bcl.TimeProvider/src/PACKAGE.md @@ -1,44 +1,58 @@ ## About - - - +Microsoft.Bcl.TimeProvider provides time abstraction support for apps targeting .NET 7 and earlier, as well as those intended for the .NET Framework. For apps targeting .NET 8 and newer versions, referencing this package is unnecessary, as the types it contains are already included in the .NET 8 and higher platform versions. ## Key Features - - -* -* -* +* Provides a common abstraction for time-related operations. ## How to Use - +```csharp +using System; + +// A class that uses TimeProvider to get the current time in Utc coordinates +public class UtcClock +{ + private readonly TimeProvider _timeProvider; + + // Constructor that takes a TimeProvider as a dependency + public Clock(TimeProvider timeProvider) + { + _timeProvider = timeProvider; + } + + // A method that returns the current time as a string + public string GetTime() + { + return _timeProvider.GetLocalNow().ToString("HH:mm:ss"); + } +} + +// A class that inherits from TimeProvider and overrides the GetLocalNow method +public class UtcTimeProvider : TimeProvider +{ + // Override the GetLocalNow method to always return UTC time + public override DateTimeOffset GetLocalNow() + { + return TimeProvider.System.GetUtcNow(); + } +} + +``` ## Main Types - - The main types provided by this library are: -* `` -* `` -* `` +* `TimeProvider` +* `TimeProviderTaskExtensions` ## Additional Documentation - +* [API documentation](https://learn.microsoft.com/dotnet/api/system.timeprovider) -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - ## Feedback & Contributing - - Microsoft.Bcl.TimeProvider is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file From 8856a04e4647c2087927273475449fa6bf8b0dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Cant=C3=BA?= Date: Thu, 7 Sep 2023 10:54:12 -0500 Subject: [PATCH 222/783] Add Microsoft.Extensions.Caching.Memory package.md details --- .../src/PACKAGE.md | 65 ++++++++++++++++--- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Caching.Memory/src/PACKAGE.md index baa592831d4977..8798aa1ff8f38f 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/src/PACKAGE.md @@ -2,43 +2,88 @@ - +Provides implementations for local and distributed in-memory cache. It stores and retrieves data in a fast and efficient way. ## Key Features -* -* -* +* A concrete implementation of the IMemoryCache interface, which represents a local in-memory cache that stores and retrieves data in a fast and efficient way +* A distributed cache that supports higher scale-out than local cache +* Expiration and eviction policies for its entries +* Entry prioritization for when the cache size limit is exceeded and needs to be compacted by entry eviction +* Track of cache statictics ## How to Use +Use Microsoft.Extensions.Caching.Memory over System.Runtime.Caching when working with ASP.NET Core as it provides better integration support. For example, IMemoryCache works natively with ASP.NET Core dependency injection. + +Local in-memory serialization: +```csharp +using Microsoft.Extensions.Caching.Memory; + +using MemoryCache cache = new(new MemoryCacheOptions()); + +object valueToCache = new(); +string key = "key"; + +using (ICacheEntry entry = cache.CreateEntry(key)) +{ + // Entries are committed after they are disposed therefore it does not exist yet. + Console.WriteLine($"Exists: {cache.TryGetValue(key, out _)}\n"); + + entry.Value = valueToCache; + entry.SlidingExpiration = TimeSpan.FromSeconds(2); +} + +bool exists = cache.TryGetValue(key, out object? cachedValue); +Console.WriteLine($"Exists: {exists}" ); +Console.WriteLine($"cachedValue is valueToCache? {object.ReferenceEquals(cachedValue, valueToCache)}\n"); + +Console.WriteLine("Wait for the sliding expiration..."); +Thread.Sleep(TimeSpan.FromSeconds(2)); + +Console.WriteLine("Exists: " + cache.TryGetValue(key, out _)); + +// You can also use the acceleration extensions to set and get entries +string key2 = "key2"; +object value2 = new(); + +cache.Set("key2", value2); + +object? cachedValue2 = cache.Get(key2); +Console.WriteLine($"cachedValue2 is value2? {object.ReferenceEquals(cachedValue2, value2)}"); +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `Microsoft.Extensions.Caching.Memory.MemoryCache` +* `Microsoft.Extensions.Caching.Memory.MemoryCacheOptions` +* `Microsoft.Extensions.Caching.Distributed.MemoryDistributedCache` +* `Microsoft.Extensions.Caching.Memory.MemoryDistributedCacheOptions` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/dotnet/core/extensions/caching) +* [Cache in-memory in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.caching.memory) ## Related Packages +[Microsoft.Extensions.Caching.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Abstractions) + ## Feedback & Contributing -Microsoft.Extensions.Caching.Memory is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.Caching.Memory is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 8f4b862be53a66b76ce9836539840ffd49af6498 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Thu, 7 Sep 2023 11:10:45 -0500 Subject: [PATCH 223/783] Add Microsoft.Extensions.DependencyInjection --- .../src/PACKAGE.md | 66 ++++++++++--------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.DependencyInjection/src/PACKAGE.md index dbf19733382c4d..5ebf199c4d144a 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/PACKAGE.md @@ -1,44 +1,50 @@ ## About - - - - +Supports the dependency injection (DI) software design pattern which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. ## Key Features - - - -* -* -* +Provides an implementation of the DI interfaces found in the `Microsoft.Extensions.DependencyInjection.Abstractions` package. ## How to Use - - +```cs +ServiceCollection services = new (); +services.AddSingleton(); +using ServiceProvider provider = services.BuildServiceProvider(); + +// The code below, following the IoC pattern, is typically only aware of the IMessageWriter interface, not the implementation. +IMessageWriter messageWriter = provider.GetService()!; +messageWriter.Write("Hello"); + +public interface IMessageWriter +{ + void Write(string message); +} + +internal class MessageWriter : IMessageWriter +{ + public void Write(string message) + { + Console.WriteLine($"MessageWriter.Write(message: \"{message}\")"); + } +} +``` ## Main Types - - - The main types provided by this library are: - -* `` -* `` -* `` +* `Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory` +* `Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions` +* `Microsoft.Extensions.DependencyInjection.ServiceProvider` ## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/dotnet/core/extensions/dependency-injection) +* API documentation + - [DefaultServiceProviderFactory](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.defaultserviceproviderfactory) + - [ServiceCollectionContainerBuilderExtensions](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.servicecollectioncontainerbuilderextensions) + - [ServiceProvider](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.serviceprovider) ## Related Packages - - +- `Microsoft.Extensions.DependencyInjection.Abstractions` +- `Microsoft.Extensions.Hosting` +- `Microsoft.Extensions.Options` ## Feedback & Contributing - - - -Microsoft.Extensions.DependencyInjection is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.DependencyInjection is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 124d40abc463a12641835537599de5bb9422e236 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Thu, 7 Sep 2023 11:58:44 -0500 Subject: [PATCH 224/783] Add Microsoft.Extensions.DependencyInjections.Abstractions --- .../src/PACKAGE.md | 50 ++++++++----------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/PACKAGE.md index 9ec0653cb849c6..6c8a654b7f4ff1 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/PACKAGE.md @@ -1,44 +1,34 @@ ## About - - - - +Supports the lower-level abstractions for the dependency injection (DI) software design pattern which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. ## Key Features - - - -* -* -* +- Interfaces for DI implementations which are provided in other packages including `Microsoft.Extensions.DependencyInjection`. +- An implementation of a service collection, which is used to add services to and later retrieve them either directly or through constructor injection. +- Interfaces, attributes and extensions methods to support various DI concepts including specifying a service's lifetime and supporting keyed services. ## How to Use - - +This package is typically used with an implementation of the DI abstractions, such as `Microsoft.Extensions.DependencyInjection`. ## Main Types - - - The main types provided by this library are: - -* `` -* `` -* `` +* `Microsoft.Extensions.DependencyInjection.ActivatorUtilities` +* `Microsoft.Extensions.DependencyInjection.IServiceCollection` +* `Microsoft.Extensions.DependencyInjection.ServiceCollection` +* `Microsoft.Extensions.DependencyInjection.ServiceCollectionDescriptorExtensions` +* `Microsoft.Extensions.DependencyInjection.ServiceDescriptor` +* `Microsoft.Extensions.DependencyInjection.IServiceProviderFactory` ## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/dotnet/core/extensions/dependency-injection) +* API documentation + - [ActivatorUtilities](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.defaultserviceproviderfactory) + - [ServiceCollection](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.servicecollection) + - [ServiceDescriptor](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.servicedescriptor) ## Related Packages - - +- `Microsoft.Extensions.DependencyInjection` +- `Microsoft.Extensions.Hosting` +- `Microsoft.Extensions.Options` ## Feedback & Contributing - - - -Microsoft.Extensions.DependencyInjection.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.DependencyInjection.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From a1ddb5eecdc4ac7b33c0e836dd02fe64358350bc Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Thu, 7 Sep 2023 12:55:33 -0500 Subject: [PATCH 225/783] Add Microsoft.Extensions.Hosting --- .../src/PACKAGE.md | 76 ++++++++++++------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md index 4370cde8aa3573..0887f275672ddc 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md @@ -1,44 +1,68 @@ ## About +Contains the .NET Generic Host `HostBuilder` which layers on the `Microsoft.Extensions.Hosting.Abstractions` package. - - - +A host encapsulates an app's resources and lifetime functionality, such as: +- Dependency injection (DI). +- Logging. +- Configuration. +- The `IHostedService` implementation which supports starting and stopping. ## Key Features - - - -* -* -* +* Contains the .NET Generic Host `HostBuilder`. ## How to Use - - +For a console app project: +```cs + using (IHost host = new HostBuilder().Build()) + { + var lifetime = host.Services.GetRequiredService(); + + lifetime.ApplicationStarted.Register(() => + { + Console.WriteLine("Started"); + }); + lifetime.ApplicationStopping.Register(() => + { + Console.WriteLine("Stopping firing"); + Console.WriteLine("Stopping end"); + }); + lifetime.ApplicationStopped.Register(() => + { + Console.WriteLine("Stopped firing"); + Console.WriteLine("Stopped end"); + }); + + host.Start(); + + // Listens for Ctrl-C. + host.WaitForShutdown(); + } +``` ## Main Types - - - The main types provided by this library are: - -* `` -* `` -* `` +* `Microsoft.Extensions.Host`. +* `Microsoft.Extensions.Hosting.HostApplicationBuilder` +* `Microsoft.Extensions.Hosting.HostBuilder` +* `Microsoft.Extensions.Hosting.IHostedService` +* `Microsoft.Extensions.Hosting.IHostedLifecycleService` ## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Generic host](https://learn.microsoft.com/en-us/dotnet/core/extensions/generic-host) +* API documentation + - [Host](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.host) + - [HostApplicationBuilder](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.hostapplicationbuilder) + - [HostBuilder](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.hostbuilder) ## Related Packages - - +- `Microsoft.Extensions.Configuration` +- `Microsoft.Extensions.DependencyInjection` +- `Microsoft.Extensions.Hosting.Abstractions` +- `Microsoft.Extensions.Logging` +- `Microsoft.Extensions.Options` ## Feedback & Contributing -Microsoft.Extensions.Hosting is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.Hosting is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From eb7a5a70681fdd2028559d5e20c34f82ef8ddcb0 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Thu, 7 Sep 2023 14:33:55 -0500 Subject: [PATCH 226/783] Add Microsoft.Extensions.Hosting.WindowsServices --- .../src/PACKAGE.md | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/PACKAGE.md index e70b7da4ac046f..65908c6aaa7b63 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/PACKAGE.md @@ -1,44 +1,44 @@ ## About - - - - +Supports using Windows Services with the hosting infrastructure. ## Key Features - - - -* -* -* +* Can configure a host to be a Windows Service. ## How to Use - - +From a Worker Service app created using the Visual Studio template: +```cs +IHost host = Host.CreateDefaultBuilder(args) + .ConfigureServices(services => + { + services.AddHostedService(); + }) + // Configure as a Windows Service + .UseWindowsService(options => + { + options.ServiceName = "My Service"; + }) + .Build(); + +host.Run(); +``` ## Main Types - - - The main types provided by this library are: - -* `` -* `` -* `` +* `Microsoft.Extensions.Hosting.WindowsServiceLifetimeHostBuilderExtensions` +* `Microsoft.Extensions.Hosting.WindowsServices.WindowsServiceLifetime` ## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [WindowsServiceLifetime](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.windowsservices.windowsservicelifetime) +* [WindowsServiceLifetimeHostBuilderExtensions](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.windowsservicelifetimehostbuilderextensions) +* [Create Windows Service using BackgroundService](https://learn.microsoft.com/dotnet/core/extensions/windows-service) +* [Host ASP.NET Core in a Windows Service](https://learn.microsoft.com/aspnet/core/host-and-deploy/windows-service?tabs=visual-studio) ## Related Packages - - +- `Microsoft.Extensions.Hosting` +- `System.ServiceProcess.ServiceController` ## Feedback & Contributing -Microsoft.Extensions.Hosting.WindowsServices is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.Hosting.WindowsServices is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From e343d81c15fb7989df97b958195ec36fdb8718d9 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 7 Sep 2023 13:47:14 -0700 Subject: [PATCH 227/783] Update PACKAGE.md for System.DirectoryServices --- .../System.DirectoryServices/src/PACKAGE.md | 62 +++++++++++++++---- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.DirectoryServices/src/PACKAGE.md b/src/libraries/System.DirectoryServices/src/PACKAGE.md index 2709a6e84e284f..ed4f115006da62 100644 --- a/src/libraries/System.DirectoryServices/src/PACKAGE.md +++ b/src/libraries/System.DirectoryServices/src/PACKAGE.md @@ -2,43 +2,81 @@ - +Provides easy access to [Active Directory Domain Services](https://learn.microsoft.com/windows/win32/ad/active-directory-domain-services) from managed code. `Microsoft Active Directory Domain Services` are the foundation for distributed networks built on Windows 2000 Server, Windows Server 2003 and Microsoft Windows Server 2008 operating systems that use domain controllers. The namespace contains two component classes, [DirectoryEntry](https://learn.microsoft.com/dotnet/api/system.directoryservices.directoryentry) and [DirectorySearcher](https://learn.microsoft.com/dotnet/api/system.directoryservices.directorysearcher), which use the Active Directory Services Interfaces (ADSI) technology. ADSI is the set of interfaces that Microsoft provides as a flexible tool for working with a variety of network providers. ADSI gives the administrator the ability to locate and manage resources on a network with relative ease, regardless of the size of the network. ## Key Features -* -* -* +Active Directory Domain Services use a tree structure. Each node in the tree contains a set of properties. Use this library to traverse, search, and modify the tree, and read and write to the properties of a node. + +* The [DirectoryEntry](https://learn.microsoft.com/dotnet/api/system.directoryservices.directoryentry) class encapsulates a node or object in the Active Directory Domain Services hierarchy. Use this class for binding to objects, reading properties, and updating attributes. Together with helper classes, DirectoryEntry provides support for life-cycle management and navigation methods, including creating, deleting, renaming, moving a child node, and enumerating children. +* Use the [DirectorySearcher](https://learn.microsoft.com/dotnet/api/system.directoryservices.directorysearcher) class to perform queries against the Active Directory Domain Services hierarchy. LDAP is the only system-supplied Active Directory Service Interfaces (ADSI) provider that supports searching. A search of the Active Directory Domain Services hierarchy through [DirectorySearcher](https://learn.microsoft.com/dotnet/api/system.directoryservices.directorysearcher) returns instances of [SearchResult](https://learn.microsoft.com/dotnet/api/system.directoryservices.searchresult), which are contained in an instance of the [SearchResultCollection](https://learn.microsoft.com/dotnet/api/system.directoryservices.searchresultcollection) class. +* Network administrators write scripts and applications that access Active Directory Domain Services to automate common administrative tasks, such as adding users and groups, managing printers, and setting permissions for network resources. ## How to Use +Install the `System.DirectoryServices` library from nuget + +```dotnetcli +dotnet add package System.DirectoryServices --version 7.0.1 +``` + +The sample need a real path to an Active Directory server to work properly: + +```cs +using System.DirectoryServices; + +namespace TestDirectoryServices +{ + internal class Program + { + static void Main(string[] args) + { + DirectoryEntry rootDse = new DirectoryEntry("LDAP://RootDSE"); + string configNamingContext = rootDse.Properties["configurationNamingContext"].Value.ToString(); + + DirectoryEntry certTemplates = new DirectoryEntry("LDAP://CN=Certificate Templates,CN=Public Key Services,CN=Services," + configNamingContext); + DirectorySearcher templatesSearch = new DirectorySearcher(certTemplates, "(objectClass=pKICertificateTemplate)", null, SearchScope.OneLevel); + + SearchResultCollection templates = templatesSearch.FindAll(); + + foreach (SearchResult template in templates) + { + Console.WriteLine($"Name: {template.Properties["name"][0]} ({template.Properties["displayName"][0]})"); + Console.WriteLine($"Flags: {template.Properties["msPKI-Enrollment-Flag"][0]}"); + } + } + } +} +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `System.DirectoryServices.DirectoryEntry` +* `System.DirectoryServices.DirectorySearcher` ## Additional Documentation - +* [API documentation](https://learn.microsoft.com/dotnet/api/system.directoryservices) +* [Active Directory Domain Services](https://learn.microsoft.com/windows/win32/ad/active-directory-domain-services) +* [Active Directory Service Interfaces](https://learn.microsoft.com/windows/win32/adsi/active-directory-service-interfaces-adsi) +* [Lightweight Directory Access Protocol (LDAP)](https://learn.microsoft.com/previous-versions/windows/desktop/ldap/lightweight-directory-access-protocol-ldap-api) -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) ## Related Packages - +* [System.DirectoryServices.AccountManagement](https://learn.microsoft.com/dotnet/api/system.directoryservices.accountmanagement) +* [System.DirectoryServices.Protocols](https://learn.microsoft.com/dotnet/api/system.directoryservices.protocols) ## Feedback & Contributing -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +**System.DirectoryServices** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From d7ad871f2bb99875de89bbedafdd0cfe4246b6ee Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 7 Sep 2023 14:32:13 -0700 Subject: [PATCH 228/783] Apply suggestions from code review --- .../Microsoft.Extensions.DependencyInjection/src/PACKAGE.md | 2 +- src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.DependencyInjection/src/PACKAGE.md index 5ebf199c4d144a..91474fd46a2f29 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/PACKAGE.md @@ -39,7 +39,7 @@ The main types provided by this library are: * API documentation - [DefaultServiceProviderFactory](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.defaultserviceproviderfactory) - [ServiceCollectionContainerBuilderExtensions](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.servicecollectioncontainerbuilderextensions) - - [ServiceProvider](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.serviceprovider) + - [ServiceProvider](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.serviceprovider) ## Related Packages - `Microsoft.Extensions.DependencyInjection.Abstractions` diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md index 0887f275672ddc..f1c1084f301cdc 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md @@ -48,7 +48,7 @@ The main types provided by this library are: * `Microsoft.Extensions.Hosting.IHostedLifecycleService` ## Additional Documentation -* [Generic host](https://learn.microsoft.com/en-us/dotnet/core/extensions/generic-host) +* [Generic host](https://learn.microsoft.com/dotnet/core/extensions/generic-host) * API documentation - [Host](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.host) - [HostApplicationBuilder](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.hostapplicationbuilder) From 7dd0d99ae3cfe8d6fe1a9b36f7d2c0f9fa0c03b2 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 7 Sep 2023 15:57:49 -0700 Subject: [PATCH 229/783] Update System.DirectoryServices.AccountManagement PACKAGE.md --- .../src/PACKAGE.md | 55 +++++++++++++++---- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md index 2709a6e84e284f..9ca387e0757c14 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md @@ -1,44 +1,75 @@ ## About - - +Provides uniform access and manipulation of security principals across multiple principal stores. The principal objects in the Account Management API include computer, group and user objects, principal stores include: + * Active Directory Domain Services (AD DS) + * Active Directory Lightweight Directory Services (AD LDS) + * Machine SAM (MSAM). ## Key Features -* -* -* +* Basic directory operations such as creating and updating security principals. The application requires less knowledge of the underlying stores to perform these operations. +* Applications can extend the object model to include new types of directory objects. +* Account management tasks, such as enabling and disabling a user account. +* Cross-store support allows group objects in the Active Directory Domain Services (AD DS), Active Directory Lightweight Directory Services (AD LDS), and Machine SAM (MSAM) databases to contain members from different types of stores. +* Query by example searching, available on the PrincipalSearcher class, enables applications to set properties on a principal object and search the selected store for other objects that contain matching property values. +* Enhanced search on computer, user and group principal objects enables applications to search the selected store for matching principal objects. +* Recursive search, available on the group principal object, enables applications to search a group recursively and return only principal objects that are leaf nodes. +* Credential validation against the Machine SAM, AD DS, and AD LS stores. +* Connections speeds are increased by using the Fast Concurrent Bind (FSB) feature when available. Connection caching decreases the number of ports used. ## How to Use +```cs +// Create the principal context for the usr object. +PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "fabrikam.com", "CN=Users,DC=fabrikam,DC=com", "administrator", "securelyStoredPassword"); + +// Create the principal user object from the context +UserPrincipal usr = new UserPrincipal(ctx); +usr.AdvancedSearchFilter.LastLogonTime(DateTime.Now, MatchType.LessThan); +usr.AdvancedSearchFilter.LastLogonTime(DateTime.Yesterday, MatchType.GreaterThan); + +// Create a PrincipalSearcher object. +PrincipalSearcher ps = new PrincipalSearcher(usr); +PrincipalSearchResult fr = ps.FindAll(); +foreach (UserPrincipal u in results) +{ + Console.WriteLine(u.Name); +} +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `System.DirectoryServices.AccountManagement.PrincipalContext` +* `System.DirectoryServices.AccountManagement.PrincipalSearcher` +* `System.DirectoryServices.AccountManagement.Principal` and its subclasses: `System.DirectoryServices.AccountManagement.UserPrincipal`, `System.DirectoryServices.AccountManagement.GroupPrincipal` and `System.DirectoryServices.AccountManagement.ComputerPrincipal` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* Conceptual documentations: + - [System.DirectoryServices.AccountManagement Namespace Overview](https://learn.microsoft.com/en-us/previous-versions/bb384379(v=vs.90)) + - [About System.DirectoryServices.AccountManagement](https://learn.microsoft.com//previous-versions/bb384375(v=vs.90)) + - [Using System.DirectoryServices.AccountManagement](https://learn.microsoft.com/previous-versions/bb384384(v=vs.90)) +* API documentation + - [System.DirectoryServices.AccountManagement namespace](https://learn.microsoft.com/dotnet/api/system.directoryservices.accountmanagement) ## Related Packages - +[System.DirectoryServices](https://learn.microsoft.com/dotnet/api/system.directoryservices) + ## Feedback & Contributing -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +**System.DirectoryServices.AccountManagement** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From bcb766140ee0e8dea6b28e0386547e5461ca2268 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 7 Sep 2023 16:03:00 -0700 Subject: [PATCH 230/783] Remove extra space --- .../System.DirectoryServices.AccountManagement/src/PACKAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md index 9ca387e0757c14..0a999337f099a4 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md @@ -1,7 +1,7 @@ ## About -Provides uniform access and manipulation of security principals across multiple principal stores. The principal objects in the Account Management API include computer, group and user objects, principal stores include: +Provides uniform access and manipulation of security principals across multiple principal stores. The principal objects in the Account Management API include computer, group and user objects, principal stores include: * Active Directory Domain Services (AD DS) * Active Directory Lightweight Directory Services (AD LDS) * Machine SAM (MSAM). From 4d0f59e74f8ebef594f770b9138dc51002d30272 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Thu, 7 Sep 2023 17:06:29 -0600 Subject: [PATCH 231/783] space --- src/libraries/System.Speech/src/PACKAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Speech/src/PACKAGE.md b/src/libraries/System.Speech/src/PACKAGE.md index 0b39583a424016..acfb0cda2ae7cc 100644 --- a/src/libraries/System.Speech/src/PACKAGE.md +++ b/src/libraries/System.Speech/src/PACKAGE.md @@ -33,7 +33,7 @@ synth.Speak("Hello World!"); // Speak a string asynchronously var prompt = synth.SpeakAsync("Goodnight Moon!"); -while(!prompt.IsCompleted) +while (!prompt.IsCompleted) { Console.WriteLine("speaking..."); Thread.Sleep(500); From 57a8f86490f29f5fd3bd96b0f45f9f89a4803d24 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Fri, 8 Sep 2023 09:54:36 -0500 Subject: [PATCH 232/783] Add Microsoft.Extensions.Hosting.Abstractions --- .../src/PACKAGE.md | 55 +++++++++---------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/PACKAGE.md index b94327b9a0078f..e699e51a601704 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/PACKAGE.md @@ -1,44 +1,43 @@ ## About +Contains abstractions to host user code in an application by encapsulating an application's resources and lifetime functionality including: +- Dependency injection (DI). +- Logging. +- Configuration. +- Starting, stopping and obtaining notifications. - - - +This package is also used to wire up specific application models like ASP.NET Core that are built on top of hosting. ## Key Features - - - -* -* -* +* Provides the `BackgroundService` base class and the `IHostedService` interface for implementing worker services. +* Provides interfaces used to configure and start\stop a host. +* Provides types to obtain environment settings such as an application name and paths. ## How to Use - - +See the Conceptual documentation below for using `BackgroundService` and `IHostedService` to host worker services. ## Main Types - - - The main types provided by this library are: -* `` -* `` -* `` +* `Microsoft.Extensions.Hosting.BackgroundService` +* `Microsoft.Extensions.Hosting.IHostBuilder` +* `Microsoft.Extensions.Hosting.IHostedService` ## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation] + - [Worker services in .NET](https://learn.microsoft.com/dotnet/core/extensions/workers) + - [Implement the IHostedService interface](https://learn.microsoft.com/dotnet/core/extensions/timer-service) +* [API documentation] + - [BackgroundService](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.backgroundservice) + - [IHostBuilder](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.ihostbuilder) + - [IHostedService](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.ihostedservice) ## Related Packages - - +- `Microsoft.Extensions.Hosting` +- `Microsoft.Extensions.Configuration.Abstractions` +- `Microsoft.Extensions.DependencyInjection.Abstractions` +- `Microsoft.Extensions.Diagnostics.Abstractions` +- `Microsoft.Extensions.FileProviders.Abstractions` +- `Microsoft.Extensions.Logging.Abstractions` ## Feedback & Contributing - - - -Microsoft.Extensions.Hosting.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.Hosting.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From ebf742e3655f9d72565f270a00da5e8e6be9f697 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Fri, 8 Sep 2023 09:57:35 -0500 Subject: [PATCH 233/783] Update PACKAGE.md --- src/libraries/System.DirectoryServices/src/PACKAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.DirectoryServices/src/PACKAGE.md b/src/libraries/System.DirectoryServices/src/PACKAGE.md index ed4f115006da62..423ed87b7f386c 100644 --- a/src/libraries/System.DirectoryServices/src/PACKAGE.md +++ b/src/libraries/System.DirectoryServices/src/PACKAGE.md @@ -24,7 +24,7 @@ Install the `System.DirectoryServices` library from nuget dotnet add package System.DirectoryServices --version 7.0.1 ``` -The sample need a real path to an Active Directory server to work properly: +The sample needs a real path to an Active Directory server to work properly: ```cs using System.DirectoryServices; From 43344fb9a7c82438eea10be00e2aac2647649308 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Fri, 8 Sep 2023 09:59:46 -0500 Subject: [PATCH 234/783] Update PACKAGE.md --- .../System.DirectoryServices.AccountManagement/src/PACKAGE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md index 0a999337f099a4..1cb6350eb96903 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md @@ -1,7 +1,7 @@ ## About -Provides uniform access and manipulation of security principals across multiple principal stores. The principal objects in the Account Management API include computer, group and user objects, principal stores include: +Provides uniform access and manipulation of security principals across multiple principal stores. The principal objects in the Account Management API include computer, group and user objects. The principal stores includes: * Active Directory Domain Services (AD DS) * Active Directory Lightweight Directory Services (AD LDS) * Machine SAM (MSAM). @@ -28,7 +28,7 @@ Provides uniform access and manipulation of security principals across multiple // Create the principal context for the usr object. PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "fabrikam.com", "CN=Users,DC=fabrikam,DC=com", "administrator", "securelyStoredPassword"); -// Create the principal user object from the context +// Create the principal user object from the context. UserPrincipal usr = new UserPrincipal(ctx); usr.AdvancedSearchFilter.LastLogonTime(DateTime.Now, MatchType.LessThan); usr.AdvancedSearchFilter.LastLogonTime(DateTime.Yesterday, MatchType.GreaterThan); From 56c8b145855282eb585363d3c36da11a411e7528 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Fri, 8 Sep 2023 10:02:00 -0500 Subject: [PATCH 235/783] Update Hosting --- src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md index f1c1084f301cdc..8434c4227716c1 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md @@ -1,12 +1,6 @@ ## About Contains the .NET Generic Host `HostBuilder` which layers on the `Microsoft.Extensions.Hosting.Abstractions` package. -A host encapsulates an app's resources and lifetime functionality, such as: -- Dependency injection (DI). -- Logging. -- Configuration. -- The `IHostedService` implementation which supports starting and stopping. - ## Key Features * Contains the .NET Generic Host `HostBuilder`. From 505ac8073a61170c9f3880d6b80d46bd2c4ccebf Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Fri, 8 Sep 2023 10:03:03 -0500 Subject: [PATCH 236/783] Update Hosting --- src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md index 8434c4227716c1..a9cd4f5727700b 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md @@ -28,7 +28,7 @@ For a console app project: host.Start(); - // Listens for Ctrl-C. + // Listens for Ctrl+C. host.WaitForShutdown(); } ``` From 86b9aa5dcdfa9efc94e3db284ff7c07986d0126c Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 8 Sep 2023 09:27:53 -0700 Subject: [PATCH 237/783] Remove unnecessary brackets --- .../Microsoft.Extensions.Hosting.Abstractions/src/PACKAGE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/PACKAGE.md index e699e51a601704..f017c0b7193271 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/PACKAGE.md @@ -23,10 +23,10 @@ The main types provided by this library are: * `Microsoft.Extensions.Hosting.IHostedService` ## Additional Documentation -* [Conceptual documentation] +* Conceptual documentation - [Worker services in .NET](https://learn.microsoft.com/dotnet/core/extensions/workers) - [Implement the IHostedService interface](https://learn.microsoft.com/dotnet/core/extensions/timer-service) -* [API documentation] +* API documentation - [BackgroundService](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.backgroundservice) - [IHostBuilder](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.ihostbuilder) - [IHostedService](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.ihostedservice) From ae6f006aa404b99d0bdbeca879b74343d1404268 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Fri, 8 Sep 2023 11:11:33 -0600 Subject: [PATCH 238/783] add oledb and odbc --- src/libraries/System.Data.Odbc/src/PACKAGE.md | 49 +++++++++--------- .../System.Data.OleDb/src/PACKAGE.md | 51 ++++++++++--------- 2 files changed, 53 insertions(+), 47 deletions(-) diff --git a/src/libraries/System.Data.Odbc/src/PACKAGE.md b/src/libraries/System.Data.Odbc/src/PACKAGE.md index 2709a6e84e284f..eac97dd7247198 100644 --- a/src/libraries/System.Data.Odbc/src/PACKAGE.md +++ b/src/libraries/System.Data.Odbc/src/PACKAGE.md @@ -1,44 +1,47 @@ ## About - - - +This package implements a data provider for ODBC data sources. ## Key Features - - -* -* -* +Allows access to legacy ODBC data sources. ## How to Use - +This is a basic example of retrieving the results of a query using an `OdbcDataReader`. For examples of using an `OdbcDataAdapter`, and of updating an ODBC data source, please see the documentation. -## Main Types +```cs +string queryString = "SELECT DISTINCT CustomerID FROM Orders"; +using (OdbcConnection connection = new OdbcConnection(connectionString)) +{ + OdbcCommand command = new OdbcCommand(queryString, connection); + connection.Open(); + OdbcDataReader reader = command.ExecuteReader(); - + while (reader.Read()) + { + Console.WriteLine("CustomerID={0}", reader[0]); + } -The main types provided by this library are: + reader.Close(); +} +``` -* `` -* `` -* `` +## Main Types -## Additional Documentation +* `OdbcDataAdapter` represents a set of data commands and a database connection that are used to fill a `DataSet` and update the ODBC data source. +* `OdbcDataReader` provides a way of reading a forward-only stream of data rows from an ODBC data source. +* `OdbcCommand` represents an SQL statement or stored procedure to execute against an ODBC data source.. +* `OdbcConnection` represents an open connection to an ODBC data source. - +## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.data.odbc) ## Related Packages - +System.Data.OleDb is a similar package for accessing OLE DB data sources. ## Feedback & Contributing - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +**System.Data.Odbc** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports are welcome at [the GitHub repository](https://github.com/dotnet/runtime). This package is considered complete and we only consider lower-risk or high-impact fixes that will maintain or improve quality. \ No newline at end of file diff --git a/src/libraries/System.Data.OleDb/src/PACKAGE.md b/src/libraries/System.Data.OleDb/src/PACKAGE.md index 2709a6e84e284f..b74dfad019759f 100644 --- a/src/libraries/System.Data.OleDb/src/PACKAGE.md +++ b/src/libraries/System.Data.OleDb/src/PACKAGE.md @@ -1,44 +1,47 @@ ## About - - - +This package implements a data provider for OLE DB data sources. ## Key Features - - -* -* -* +Allows access to legacy OLE DB data sources. ## How to Use - +This is a basic example of retrieving the results of a query using an `OleDbDataReader`. For examples of using an `OleDbDataAdapter`, and of updating an OLE DB data source, please see the documentation. + +```cs +string queryString = "SELECT OrderID, CustomerID FROM Orders"; +using (OleDbConnection connection = new OleDbConnection(connectionString)) +{ + OleDbCommand command = new OleDbCommand(queryString, connection); + connection.Open(); + OleDbDataReader reader = command.ExecuteReader(); + + while (reader.Read()) + { + Console.WriteLine(reader.GetInt32(0) + ", " + reader.GetString(1)); + } + // always call Close when done reading. + reader.Close(); +} +``` ## Main Types - - -The main types provided by this library are: - -* `` -* `` -* `` +* `OleDbDataAdapter` represents a set of data commands and a database connection that are used to fill a `DataSet` and update the OLE DB data source. +* `OleDbDataReader` provides a way of reading a forward-only stream of data rows from an OLE DB data source. +* `OleDbCommand` represents an SQL statement or stored procedure to execute against an OLE DB data source. +* `OleDbConnection` represents an open connection to an OLE DB data source. ## Additional Documentation - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.data.oledb) ## Related Packages - +System.Data.Odbc is a similar package for accessing ODBC data sources. ## Feedback & Contributing - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +**System.Data.OleDb** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports are welcome at [the GitHub repository](https://github.com/dotnet/runtime). This package is considered complete and we only consider lower-risk or high-impact fixes that will maintain or improve quality. \ No newline at end of file From 0f8464ca3319b0250cc0525c3259ceaceaad4ec4 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Fri, 8 Sep 2023 11:15:26 -0600 Subject: [PATCH 239/783] tweak --- src/libraries/System.Data.Odbc/src/PACKAGE.md | 2 +- src/libraries/System.Data.OleDb/src/PACKAGE.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Data.Odbc/src/PACKAGE.md b/src/libraries/System.Data.Odbc/src/PACKAGE.md index eac97dd7247198..7f5d22258dbc85 100644 --- a/src/libraries/System.Data.Odbc/src/PACKAGE.md +++ b/src/libraries/System.Data.Odbc/src/PACKAGE.md @@ -44,4 +44,4 @@ System.Data.OleDb is a similar package for accessing OLE DB data sources. ## Feedback & Contributing -**System.Data.Odbc** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports are welcome at [the GitHub repository](https://github.com/dotnet/runtime). This package is considered complete and we only consider lower-risk or high-impact fixes that will maintain or improve quality. \ No newline at end of file +**System.Data.Odbc** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports are welcome at [the GitHub repository](https://github.com/dotnet/runtime). This package is considered complete and we only consider low-risk, high-impact fixes that are necessary to maintain or improve quality. \ No newline at end of file diff --git a/src/libraries/System.Data.OleDb/src/PACKAGE.md b/src/libraries/System.Data.OleDb/src/PACKAGE.md index b74dfad019759f..5d5b0649345ce2 100644 --- a/src/libraries/System.Data.OleDb/src/PACKAGE.md +++ b/src/libraries/System.Data.OleDb/src/PACKAGE.md @@ -22,7 +22,7 @@ using (OleDbConnection connection = new OleDbConnection(connectionString)) { Console.WriteLine(reader.GetInt32(0) + ", " + reader.GetString(1)); } - // always call Close when done reading. + reader.Close(); } ``` @@ -44,4 +44,4 @@ System.Data.Odbc is a similar package for accessing ODBC data sources. ## Feedback & Contributing -**System.Data.OleDb** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports are welcome at [the GitHub repository](https://github.com/dotnet/runtime). This package is considered complete and we only consider lower-risk or high-impact fixes that will maintain or improve quality. \ No newline at end of file +**System.Data.OleDb** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports are welcome at [the GitHub repository](https://github.com/dotnet/runtime). This package is considered complete and we only consider low-risk, high-impact fixes that are necessary to maintain or improve quality. \ No newline at end of file From 9bf79ce9d41c2cbeb18c1693607533fa9af78f51 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Fri, 8 Sep 2023 13:26:15 -0600 Subject: [PATCH 240/783] Update src/libraries/System.Speech/src/PACKAGE.md Co-authored-by: MSDN.WhiteKnight <35516665+MSDN-WhiteKnight@users.noreply.github.com> --- src/libraries/System.Speech/src/PACKAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Speech/src/PACKAGE.md b/src/libraries/System.Speech/src/PACKAGE.md index acfb0cda2ae7cc..c58da5834d1b34 100644 --- a/src/libraries/System.Speech/src/PACKAGE.md +++ b/src/libraries/System.Speech/src/PACKAGE.md @@ -3,7 +3,7 @@ Provides APIs for speech recognition and synthesis built on the [Microsoft Speech API](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms723627(v=vs.85)) in Windows. Not supported on other non-Windows platforms. -This package is provided primarily for compatibility with code being ported from .NETFramework and is not accepting new features. +This package is provided primarily for compatibility with code being ported from .NET Framework and is not accepting new features. ## Key Features From 066cadeaa21f7c245bf5e4132dd14f5300136acd Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Fri, 8 Sep 2023 13:26:56 -0600 Subject: [PATCH 241/783] Update src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md Co-authored-by: Anton Firszov --- src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md index bf1cc0ef79e7e2..15fc9683b87abd 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md @@ -10,7 +10,7 @@ * The package allows to fluently set up multiple `HttpClient` configurations for applications that use DI via `AddHttpClient` extension method. * `HttpClientFactory` caches `HttpMessageHandler` instances per configuration name, which allows to reuse resources between `HttpClient` instances to avoid port exhaustion. -* `HttpClientFactory` manages lifetime of `HttpMessageHandler` instances and recycles connections to avoid losing DNS changes. +* `HttpClientFactory` manages lifetime of `HttpMessageHandler` instances and recycles connections to track DNS changes. ## How to Use From f5e2b2541741599fa807fde12f38d36122cbc27a Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Fri, 8 Sep 2023 13:29:14 -0600 Subject: [PATCH 242/783] Update src/libraries/System.Speech/src/PACKAGE.md --- src/libraries/System.Speech/src/PACKAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Speech/src/PACKAGE.md b/src/libraries/System.Speech/src/PACKAGE.md index c58da5834d1b34..4d2a8df1f1f8e4 100644 --- a/src/libraries/System.Speech/src/PACKAGE.md +++ b/src/libraries/System.Speech/src/PACKAGE.md @@ -1,7 +1,7 @@ ## About -Provides APIs for speech recognition and synthesis built on the [Microsoft Speech API](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms723627(v=vs.85)) in Windows. Not supported on other non-Windows platforms. +Provides APIs for speech recognition and synthesis built on the [Microsoft Speech API](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms723627(v=vs.85)) in Windows. Not supported on other platforms. This package is provided primarily for compatibility with code being ported from .NET Framework and is not accepting new features. From 646b0f0250262cba5462f923839296b9d3819aec Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Fri, 8 Sep 2023 14:49:07 -0600 Subject: [PATCH 243/783] Apply suggestions from code review Co-authored-by: Shay Rojansky --- src/libraries/System.Data.Odbc/src/PACKAGE.md | 30 +++++++++---------- .../System.Data.OleDb/src/PACKAGE.md | 28 ++++++++--------- 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/src/libraries/System.Data.Odbc/src/PACKAGE.md b/src/libraries/System.Data.Odbc/src/PACKAGE.md index 7f5d22258dbc85..4211f7f44ee1e5 100644 --- a/src/libraries/System.Data.Odbc/src/PACKAGE.md +++ b/src/libraries/System.Data.Odbc/src/PACKAGE.md @@ -4,35 +4,33 @@ This package implements a data provider for ODBC data sources. ## Key Features -Allows access to legacy ODBC data sources. +Allows access to ODBC data sources. ## How to Use -This is a basic example of retrieving the results of a query using an `OdbcDataReader`. For examples of using an `OdbcDataAdapter`, and of updating an ODBC data source, please see the documentation. +This is a basic example of retrieving the results of a query using an [OdbcDataReader](https://learn.microsoft.com/dotnet/api/system.data.odbc.odbcdatareader). For examples of using an [OdbcDataAdapter](https://learn.microsoft.com/dotnet/api/system.data.odbc.odbcdataadapter), and of updating an ODBC data source, please see the documentation. ```cs string queryString = "SELECT DISTINCT CustomerID FROM Orders"; -using (OdbcConnection connection = new OdbcConnection(connectionString)) -{ - OdbcCommand command = new OdbcCommand(queryString, connection); - connection.Open(); - OdbcDataReader reader = command.ExecuteReader(); - while (reader.Read()) - { - Console.WriteLine("CustomerID={0}", reader[0]); - } +using OdbcConnection connection = new OdbcConnection(connectionString); +using OdbcCommand command = new OdbcCommand(queryString, connection); + +connection.Open(); +using OdbcDataReader reader = command.ExecuteReader(); - reader.Close(); +while (reader.Read()) +{ + Console.WriteLine("CustomerID={0}", reader[0]); } ``` ## Main Types -* `OdbcDataAdapter` represents a set of data commands and a database connection that are used to fill a `DataSet` and update the ODBC data source. -* `OdbcDataReader` provides a way of reading a forward-only stream of data rows from an ODBC data source. -* `OdbcCommand` represents an SQL statement or stored procedure to execute against an ODBC data source.. -* `OdbcConnection` represents an open connection to an ODBC data source. +* [OdbcConnection](https://learn.microsoft.com/dotnet/api/system.data.odbc.odbcconnection) represents a connection to an ODBC data source. +* [OdbcCommand](https://learn.microsoft.com/dotnet/api/system.data.odbc.odbccommand) represents an SQL statement or stored procedure to execute against an ODBC data source.. +* [OdbcDataReader](https://learn.microsoft.com/dotnet/api/system.data.odbc.odbcdatareader) provides a way of reading a forward-only stream of data rows from an ODBC data source. +* [OdbcDataAdapter](https://learn.microsoft.com/dotnet/api/system.data.odbc.odbcdataadapter) represents a set of data commands and a database connection that are used to fill a [DataSet](https://learn.microsoft.com/dotnet/api/system.data.dataset) and update the ODBC data source. ## Additional Documentation diff --git a/src/libraries/System.Data.OleDb/src/PACKAGE.md b/src/libraries/System.Data.OleDb/src/PACKAGE.md index 5d5b0649345ce2..85b73459db6794 100644 --- a/src/libraries/System.Data.OleDb/src/PACKAGE.md +++ b/src/libraries/System.Data.OleDb/src/PACKAGE.md @@ -8,31 +8,29 @@ Allows access to legacy OLE DB data sources. ## How to Use -This is a basic example of retrieving the results of a query using an `OleDbDataReader`. For examples of using an `OleDbDataAdapter`, and of updating an OLE DB data source, please see the documentation. +This is a basic example of retrieving the results of a query using an [OleDbDataReader](https://learn.microsoft.com/dotnet/api/system.data.oledb.oledbdatareader). For examples of using an [OleDbDataAdapter](https://learn.microsoft.com/dotnet/api/system.data.oledb.oledbdataadapter), and of updating an OLE DB data source, please see the documentation. ```cs string queryString = "SELECT OrderID, CustomerID FROM Orders"; -using (OleDbConnection connection = new OleDbConnection(connectionString)) -{ - OleDbCommand command = new OleDbCommand(queryString, connection); - connection.Open(); - OleDbDataReader reader = command.ExecuteReader(); - while (reader.Read()) - { - Console.WriteLine(reader.GetInt32(0) + ", " + reader.GetString(1)); - } +using OleDbConnection connection = new OleDbConnection(connectionString); +using OleDbCommand command = new OleDbCommand(queryString, connection); + +connection.Open(); +using OleDbDataReader reader = command.ExecuteReader(); - reader.Close(); +while (reader.Read()) +{ + Console.WriteLine(reader.GetInt32(0) + ", " + reader.GetString(1)); } ``` ## Main Types -* `OleDbDataAdapter` represents a set of data commands and a database connection that are used to fill a `DataSet` and update the OLE DB data source. -* `OleDbDataReader` provides a way of reading a forward-only stream of data rows from an OLE DB data source. -* `OleDbCommand` represents an SQL statement or stored procedure to execute against an OLE DB data source. -* `OleDbConnection` represents an open connection to an OLE DB data source. +* [OleDbConnection](https://learn.microsoft.com/dotnet/api/system.data.oledb.oledbconnection) represents an open connection to an OLE DB data source. +* [OleDbCommand](https://learn.microsoft.com/dotnet/api/system.data.oledb.oledbcommand) represents an SQL statement or stored procedure to execute against an OLE DB data source. +* [OleDbDataReader](https://learn.microsoft.com/dotnet/api/system.data.oledb.oledbdatareader) provides a way of reading a forward-only stream of data rows from an OLE DB data source. +* [OleDbDataAdapter](https://learn.microsoft.com/dotnet/api/system.data.oledb.oledbdataadapter) represents a set of data commands and a database connection that are used to fill a `DataSet` and update the OLE DB data source. ## Additional Documentation From f107d058fb9f597231f50e56a57ac37ad0837a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Mon, 11 Sep 2023 08:44:36 -0600 Subject: [PATCH 244/783] Apply suggestions for System.Diagnostics.EventLog & PerformanceCounter --- .../src/PACKAGE.md | 46 +++---------------- .../src/PACKAGE.md | 22 ++------- 2 files changed, 10 insertions(+), 58 deletions(-) diff --git a/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md b/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md index 1cb7eae3a470b3..2821a14f7c70b0 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md +++ b/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md @@ -2,9 +2,9 @@ -When an error occurs in a Windows machine, the system administrator or support representative must determine what caused the error, attempt to recover any lost data, and prevent the error from recurring. It is helpful if applications, the operating system, and other system services record important events, such as low-memory conditions or excessive attempts to access a disk. The system administrator can then use the Windows Event Log to help determine what conditions caused the error and identify the context in which it occurred. +This package provides types that allow applications to interact with the Windows Event Log service. -This package provides the `System.Diagnostics.EventLog.dll` assembly, which contains types that allow applications to interact with the Windows Event Log service. +When an error occurs in a Windows machine, the system administrator or support representative must determine what caused the error, attempt to recover any lost data, and prevent the error from recurring. It is helpful if applications, the operating system, and other system services record important events, such as low-memory conditions or excessive attempts to access a disk. The system administrator can then use the Windows Event Log to help determine what conditions caused the error and identify the context in which it occurred. ## Key Features @@ -50,55 +50,21 @@ Notes: The main types provided by this library are: -Under the [`System.Diagnostics`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics) namespace: +Under the [`System.Diagnostics`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics) namespace, the main types are: -- [`System.Diagnostics.EntryWrittenEventArgs`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EntryWrittenEventArgs) -- [`System.Diagnostics.EntryWrittenEventHandler`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EntryWrittenEventHandler) -- [`System.Diagnostics.EventInstance`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventInstance) - [`System.Diagnostics.EventLog`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLog) - [`System.Diagnostics.EventLogEntry`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLogEntry) - [`System.Diagnostics.EventLogEntryCollection`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLogEntryCollection) - [`System.Diagnostics.EventLogEntryType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLogEntryType) -- [`System.Diagnostics.EventLogTraceListener`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLogTraceListener) -- [`System.Diagnostics.EventSourceCreationData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventSourceCreationData) -- [`System.Diagnostics.OverflowAction`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.OverflowAction) - -Under the[`System.Diagnostics.Eventing.Reader`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader) namespace: - -- [`System.Diagnostics.Eventing.Reader.EventBookmark`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventBookmark) -- [`System.Diagnostics.Eventing.Reader.EventKeyword`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventKeyword) -- [`System.Diagnostics.Eventing.Reader.EventLevel`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLevel) -- [`System.Diagnostics.Eventing.Reader.EventLogConfiguration`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogConfiguration) -- [`System.Diagnostics.Eventing.Reader.EventLogException`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogException) -- [`System.Diagnostics.Eventing.Reader.EventLogInformation`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogInformation) -- [`System.Diagnostics.Eventing.Reader.EventLogInvalidDataException`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogInvalidDataException) -- [`System.Diagnostics.Eventing.Reader.EventLogIsolation`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogIsolation) -- [`System.Diagnostics.Eventing.Reader.EventLogLink`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogLink) -- [`System.Diagnostics.Eventing.Reader.EventLogMode`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogMode) -- [`System.Diagnostics.Eventing.Reader.EventLogNotFoundException`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogNotFoundException) -- [`System.Diagnostics.Eventing.Reader.EventLogPropertySelector`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogPropertySelector) -- [`System.Diagnostics.Eventing.Reader.EventLogProviderDisabledException`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogProviderDisabledException) + +Under the [`System.Diagnostics.Eventing.Reader`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader) namespace, the main types are: + - [`System.Diagnostics.Eventing.Reader.EventLogQuery`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogQuery) - [`System.Diagnostics.Eventing.Reader.EventLogReader`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogReader) -- [`System.Diagnostics.Eventing.Reader.EventLogReadingException`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogReadingException) - [`System.Diagnostics.Eventing.Reader.EventLogRecord`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogRecord) - [`System.Diagnostics.Eventing.Reader.EventLogSession`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogSession) -- [`System.Diagnostics.Eventing.Reader.EventLogStatus`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogStatus) - [`System.Diagnostics.Eventing.Reader.EventLogType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogType) -- [`System.Diagnostics.Eventing.Reader.EventLogWatcher`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogWatcher) -- [`System.Diagnostics.Eventing.Reader.EventMetadata`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventMetadata) -- [`System.Diagnostics.Eventing.Reader.EventOpcode`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventOpcode) -- [`System.Diagnostics.Eventing.Reader.EventProperty`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventProperty) - [`System.Diagnostics.Eventing.Reader.EventRecord`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventRecord) -- [`System.Diagnostics.Eventing.Reader.EventRecordWrittenEventArgs`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventRecordWrittenEventArgs) -- [`System.Diagnostics.Eventing.Reader.EventTask`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventTask) -- [`System.Diagnostics.Eventing.Reader.PathType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.PathType) -- [`System.Diagnostics.Eventing.Reader.ProviderMetadata`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.ProviderMetadata) -- [`System.Diagnostics.Eventing.Reader.SessionAuthentication`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.SessionAuthentication) -- [`System.Diagnostics.Eventing.Reader.StandardEventKeywords`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.StandardEventKeywords) -- [`System.Diagnostics.Eventing.Reader.StandardEventLevel`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.StandardEventLevel) -- [`System.Diagnostics.Eventing.Reader.StandardEventOpcode`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.StandardEventOpcode) -- [`System.Diagnostics.Eventing.Reader.StandardEventTask`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.StandardEventTask) ## Additional Documentation diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md b/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md index 1fecb16e569611..6f74c9a86379c6 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md @@ -2,14 +2,14 @@ +This package provides types that allow applications to interact with the Windows performance counters. + Windows allows you to examine how programs you run affect your computer's performance, both in real time and by collecting log data for later analysis. You can do this via the Windows Performance Monitor tool, which uses performance counters, among other features. Windows performance counters provide a high-level abstraction layer that provides a consistent interface for collecting various kinds of system data such as CPU, memory, and disk usage. They can be included in the operating system or can be part of individual applications. Windows Performance Monitor requests the current value of performance counters at specifiedtime intervals. System administrators often use performance counters to monitor systems for performance or behavior problems. Software developers often use performance counters to examine the resource usage of their programs. -This package provides the `System.Diagnostics.PerformanceCounter.dll` assembly, which contains types that allow applications to interact with the Windows performance counters. - ## Key Features @@ -188,30 +188,16 @@ Notes: The main types provided by this library are: -Under the [`System.Diagnostics`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics) namespace: +Under the [`System.Diagnostics`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics) namespace, the main types are: * [`System.Diagnostics.CounterCreationData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.CounterCreationData) * [`System.Diagnostics.CounterCreationDataCollection`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.CounterCreationDataCollection) -* [`System.Diagnostics.CounterSample`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.CounterSample) -* [`System.Diagnostics.CounterSampleCalculator`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.CounterSampleCalculator) -* [`System.Diagnostics.ICollectData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.ICollectData) -* [`System.Diagnostics.InstanceData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.InstanceData) -* [`System.Diagnostics.InstanceDataCollection`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.InstanceDataCollection) -* [`System.Diagnostics.InstanceDataCollectionCollection`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.InstanceDataCollectionCollection) * [`System.Diagnostics.PerformanceCounter`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceCounter) -* [`System.Diagnostics.PerformanceCounterCategory`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceCounterCategory) -* [`System.Diagnostics.PerformanceCounterCategoryType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceCounterCategoryType) -* [`System.Diagnostics.PerformanceCounterInstanceLifetime`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceCounterInstanceLifetime) -* [`System.Diagnostics.PerformanceCounterManager`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceCounterManager) -* [`System.Diagnostics.PerformanceCounterType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceCounterType) -Under the [`System.Diagnostics.PerformanceData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData) namespace: +Under the [`System.Diagnostics.PerformanceData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData) namespace, the main types are: * [`System.Diagnostics.PerformanceData.CounterData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterData) * [`System.Diagnostics.PerformanceData.CounterSet`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterSet) -* [`System.Diagnostics.PerformanceData.CounterSetInstance`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterSetInstance) -* [`System.Diagnostics.PerformanceData.CounterSetInstanceCounterDataSet`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterSetInstanceCounterDataSet) -* [`System.Diagnostics.PerformanceData.CounterSetInstanceType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterSetInstanceType) * [`System.Diagnostics.PerformanceData.CounterType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterType) ## Additional Documentation From eca1ff8ec64ff6e053008a2afb14ad49519fb0fc Mon Sep 17 00:00:00 2001 From: Michael Sharp Date: Tue, 12 Sep 2023 23:13:22 -0600 Subject: [PATCH 245/783] added Bcl.Numerics --- .../Microsoft.Bcl.Numerics/src/PACKAGE.md | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md index df05c1c906d9b8..faa3594f73e151 100644 --- a/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md +++ b/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md @@ -1,20 +1,32 @@ ## About - - - +As of .NET Core 2.0 and .NET Standard 2.1, the C# language has support for math (System.MathF) functions with floats. This library provides the necessary definitions of those types to support these language features on .NET Framework and on .NET Standard 2.0. This library is not necessary nor recommended when targeting versions of .NET that include the relevant support. ## Key Features -* -* -* +* Enables the use of MathF on older .NET platforms + ## How to Use - +```C# +using System; +using System.MathF. + +internal static class Program +{ + private static async Task Main() + { + Console.WriteLine("Starting..."); + + Console.WriteLine(MathF.Max(1f, 5f)); // returns 5f + + Console.WriteLine("Finished!"); + } +} +``` ## Main Types @@ -22,20 +34,13 @@ The main types provided by this library are: -* `` -* `` -* `` +* `System.MathF` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.mathf) ## Feedback & Contributing From 5827567812b4a3b4d9a60edd068d0518459872ae Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Sat, 16 Sep 2023 12:20:41 -0700 Subject: [PATCH 246/783] Fill template for Microsoft.Extensions.Configuration & Abstractions --- .../src/PACKAGE.md | 30 +++++++---- .../src/PACKAGE.md | 52 ++++++++++++++++--- 2 files changed, 66 insertions(+), 16 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md index fb051d69f251b2..bf951fcc17968e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md @@ -4,13 +4,15 @@ Provides abstractions of key-value pair based configuration. Interfaces defined in this package are implemented by classes in [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/) and other configuration packages. + ## Key Features -* -* -* +* Abstractions for string key-value pair configuration sources and sections +* Path conventions of keys establishing a heirachy of values +* Support for multiple configuration sources, aggregating and defining precdence for values +* Support for reload on change ## How to Use @@ -42,17 +44,18 @@ var options = config.Get(); Console.WriteLine(options.NamedProperty); // returns "value for named property" ``` + ## Main Types The main types provided by this library are: -* [`Microsoft.Extensions.Configuration.IConfiguration`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfiguration) -* [`Microsoft.Extensions.Configuration.IConfigurationBuilder`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfigurationbuilder) -* [`Microsoft.Extensions.Configuration.IConfigurationProvider`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfigurationprovider) -* [`Microsoft.Extensions.Configuration.IConfigurationRoot`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfigurationroot) -* [`Microsoft.Extensions.Configuration.IConfigurationSection`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iconfigurationsection) +* `Microsoft.Extensions.Configuration.IConfiguration` +* `Microsoft.Extensions.Configuration.IConfigurationBuilder` +* `Microsoft.Extensions.Configuration.IConfigurationProvider` +* `Microsoft.Extensions.Configuration.IConfigurationRoot` +* `Microsoft.Extensions.Configuration.IConfigurationSection` ## Additional Documentation @@ -64,9 +67,18 @@ The main types provided by this library are: ## Related Packages +* [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration) +* [Microsoft.Extensions.Configuration.Binder](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder) +* [Microsoft.Extensions.Configuration.CommandLine](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.CommandLine) +* [Microsoft.Extensions.Configuration.EnvironmentVariables](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.EnvironmentVariables) +* [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions) +* [Microsoft.Extensions.Configuration.Ini](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Ini) +* [Microsoft.Extensions.Configuration.Json](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Json) +* [Microsoft.Extensions.Configuration.UserSecrets](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.UserSecrets) +* [Microsoft.Extensions.Configuration.Xml](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Xml) ## Feedback & Contributing -Microsoft.Extensions.Configuration.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.Caching.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). diff --git a/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md index 13f09693b243a3..b9f3878b7e9b78 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md @@ -8,13 +8,41 @@ -* -* -* +* In-memory configuration provider +* Chained configuration provider for chaining multiple confiugration providers together. +* Base types that implement configuration abstraction interfaces that can be used when implementing other configuration providers. ## How to Use +```C# +using Microsoft.Extensions.Configuration; + +var configurationBuilder = new ConfigurationBuilder(); + +configurationBuilder.AddInMemoryCollection( + new Dictionary + { + ["Setting1"] = "value", + ["MyOptions:Enabled"] = bool.TrueString, + }); + +configurationBuilder.AddInMemoryCollection( + new Dictionary + { + ["Setting2"] = "value2", + ["MyOptions:Enabled"] = bool.FalseString, + }); + +var config = configurationBuilder.Build(); + +// note case-insensitive +Console.WriteLine(config["setting1"]); +Console.WriteLine(config["setting2"]); + +// note last in wins +Console.WriteLine(config["MyOptions:Enabled"]); +``` ## Main Types @@ -22,9 +50,10 @@ The main types provided by this library are: -* `` -* `` -* `` +* `Microsoft.Extensions.Configuration.ConfigurationBuilder` +* `Microsoft.Extensions.Configuration.ConfigurationManager` +* `Microsoft.Extensions.Configuration.ConfigurationRoot` +* `Microsoft.Extensions.Configuration.ConfigurationSection` ## Additional Documentation @@ -36,9 +65,18 @@ The main types provided by this library are: ## Related Packages +* [Microsoft.Extensions.Configuration.Binder](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder) +* [Microsoft.Extensions.Configuration.CommandLine](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.CommandLine) +* [Microsoft.Extensions.Configuration.EnvironmentVariables](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.EnvironmentVariables) +* [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions) +* [Microsoft.Extensions.Configuration.Ini](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Ini) +* [Microsoft.Extensions.Configuration.Json](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Json) +* [Microsoft.Extensions.Configuration.UserSecrets](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.UserSecrets) +* [Microsoft.Extensions.Configuration.Xml](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Xml) + ## Feedback & Contributing -Microsoft.Extensions.Configuration is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.Configuration is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From cf124a103629a29295fe16c40fc72d0ad72f3f54 Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Sat, 16 Sep 2023 12:46:24 -0700 Subject: [PATCH 247/783] Add Microsoft.Extensions.Configuration.Binder readme. --- .../src/PACKAGE.md | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/PACKAGE.md index f39973daaad6f2..c7caaacac6c1c4 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/PACKAGE.md @@ -4,13 +4,15 @@ Provides the functionality to bind an object to data in configuration providers for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to represent the configuration data as strongly-typed classes defined in the application code. To bind a configuration, use the [Microsoft.Extensions.Configuration.ConfigurationBinder.Get](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.configurationbinder.get) extension method on the `IConfiguration` object. To use this package, you also need to install a package for the [configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration#configuration-providers), for example, [Microsoft.Extensions.Configuration.Json](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Json/) for the JSON provider. +The types contained in this assembly use Reflection at runtime which is not friendly with linking or AOT. To better support linking and AOT as well as provide more efficient strongly-typed binding methods - this package also provides a source generator. This generator is enabled by default when a project sets `PublishAot` but can also be enabled using `true`. + ## Key Features -* -* -* +* Configuring existing type instances from a configuration section (Bind) +* Constructing new configured type instances from a configuration section (Get & GetValue) +* Generating source to bind objects from a configuration section without a runtime reflection dependency. ## How to Use @@ -53,7 +55,7 @@ class Program // Read nested objects Console.WriteLine("Endpoints: "); - + foreach (Endpoint endpoint in settings.Endpoints) { Console.WriteLine($"{endpoint.IPAddress}:{endpoint.Port}"); @@ -93,15 +95,21 @@ You can include a configuration file using a code like this in your `.csproj` fi ``` +You can add the following property to enable the source generator. This requires a .NET 8.0 SDK or later. +```xml + + true + +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `Microsoft.Extensions.Configuration.ConfigurationBinder` +* `Microsoft.Extensions.Configuration.BinderOptions` ## Additional Documentation @@ -113,9 +121,18 @@ The main types provided by this library are: ## Related Packages +* [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration) +* [Microsoft.Extensions.Configuration.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Abstractions) +* [Microsoft.Extensions.Configuration.CommandLine](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.CommandLine) +* [Microsoft.Extensions.Configuration.EnvironmentVariables](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.EnvironmentVariables) +* [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions) +* [Microsoft.Extensions.Configuration.Ini](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Ini) +* [Microsoft.Extensions.Configuration.Json](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Json) +* [Microsoft.Extensions.Configuration.UserSecrets](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.UserSecrets) +* [Microsoft.Extensions.Configuration.Xml](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Xml) ## Feedback & Contributing -Microsoft.Extensions.Configuration.Binder is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.Configuration.Binder is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 3eba320f1ea303ce574fdda14742d67196522814 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 18 Sep 2023 14:14:49 +0200 Subject: [PATCH 248/783] Remove undocumented P2 package readmes --- .../Microsoft.Bcl.Cryptography/src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- src/libraries/System.CodeDom/src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../System.Composition.Hosting/src/PACKAGE.md | 44 ------------------- .../System.Composition.Runtime/src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../System.Composition/src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../System.Drawing.Common/src/PACKAGE.md | 44 ------------------- .../System.Formats.Cbor/src/PACKAGE.md | 44 ------------------- .../System.IO.Hashing/src/PACKAGE.md | 44 ------------------- .../System.IO.Packaging/src/PACKAGE.md | 44 ------------------- .../System.IO.Pipelines/src/PACKAGE.md | 44 ------------------- .../System.Management/src/PACKAGE.md | 44 ------------------- .../System.Memory.Data/src/PACKAGE.md | 44 ------------------- .../System.Numerics.Tensors/src/PACKAGE.md | 44 ------------------- .../System.Reflection.Context/src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../System.Text.Encodings.Web/src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- .../src/PACKAGE.md | 44 ------------------- src/libraries/System.Threading/src/PACKAGE.md | 44 ------------------- .../System.Windows.Extensions/src/PACKAGE.md | 44 ------------------- 52 files changed, 2288 deletions(-) delete mode 100644 src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Extensions.FileProviders.Composite/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Extensions.Hosting.Systemd/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Extensions.Logging.Configuration/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Extensions.Logging.EventLog/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Extensions.Logging.EventSource/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.NET.WebAssembly.Threading/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Win32.Registry.AccessControl/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.Win32.SystemEvents/src/PACKAGE.md delete mode 100644 src/libraries/Microsoft.XmlSerializer.Generator/src/PACKAGE.md delete mode 100644 src/libraries/System.CodeDom/src/PACKAGE.md delete mode 100644 src/libraries/System.ComponentModel.Composition.Registration/src/PACKAGE.md delete mode 100644 src/libraries/System.ComponentModel.Composition/src/PACKAGE.md delete mode 100644 src/libraries/System.Composition.AttributedModel/src/PACKAGE.md delete mode 100644 src/libraries/System.Composition.Convention/src/PACKAGE.md delete mode 100644 src/libraries/System.Composition.Hosting/src/PACKAGE.md delete mode 100644 src/libraries/System.Composition.Runtime/src/PACKAGE.md delete mode 100644 src/libraries/System.Composition.TypedParts/src/PACKAGE.md delete mode 100644 src/libraries/System.Composition/src/PACKAGE.md delete mode 100644 src/libraries/System.Diagnostics.DiagnosticSource/src/PACKAGE.md delete mode 100644 src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md delete mode 100644 src/libraries/System.Drawing.Common/src/PACKAGE.md delete mode 100644 src/libraries/System.Formats.Cbor/src/PACKAGE.md delete mode 100644 src/libraries/System.IO.Hashing/src/PACKAGE.md delete mode 100644 src/libraries/System.IO.Packaging/src/PACKAGE.md delete mode 100644 src/libraries/System.IO.Pipelines/src/PACKAGE.md delete mode 100644 src/libraries/System.Management/src/PACKAGE.md delete mode 100644 src/libraries/System.Memory.Data/src/PACKAGE.md delete mode 100644 src/libraries/System.Numerics.Tensors/src/PACKAGE.md delete mode 100644 src/libraries/System.Reflection.Context/src/PACKAGE.md delete mode 100644 src/libraries/System.Resources.Extensions/src/PACKAGE.md delete mode 100644 src/libraries/System.Runtime.Serialization.Schema/src/PACKAGE.md delete mode 100644 src/libraries/System.Security.Cryptography.Cose/src/PACKAGE.md delete mode 100644 src/libraries/System.Security.Cryptography.Pkcs/src/PACKAGE.md delete mode 100644 src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md delete mode 100644 src/libraries/System.Security.Cryptography.Xml/src/PACKAGE.md delete mode 100644 src/libraries/System.Security.Permissions/src/PACKAGE.md delete mode 100644 src/libraries/System.ServiceModel.Syndication/src/PACKAGE.md delete mode 100644 src/libraries/System.ServiceProcess.ServiceController/src/PACKAGE.md delete mode 100644 src/libraries/System.Text.Encodings.Web/src/PACKAGE.md delete mode 100644 src/libraries/System.Threading.AccessControl/src/PACKAGE.md delete mode 100644 src/libraries/System.Threading.RateLimiting/src/PACKAGE.md delete mode 100644 src/libraries/System.Threading.Tasks.Dataflow/src/PACKAGE.md delete mode 100644 src/libraries/System.Threading/src/PACKAGE.md delete mode 100644 src/libraries/System.Windows.Extensions/src/PACKAGE.md diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md deleted file mode 100644 index 5a3a8c037bca45..00000000000000 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -Microsoft.Bcl.Cryptography is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md deleted file mode 100644 index 651e3c04c98405..00000000000000 --- a/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -Microsoft.Extensions.Caching.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/PACKAGE.md deleted file mode 100644 index 79b5aea01302e5..00000000000000 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -Microsoft.Extensions.DependencyInjection.Specification.Tests is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md deleted file mode 100644 index efb7ca7c9133cc..00000000000000 --- a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -Microsoft.Extensions.FileProviders.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Composite/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileProviders.Composite/src/PACKAGE.md deleted file mode 100644 index 122fbecfa2ba91..00000000000000 --- a/src/libraries/Microsoft.Extensions.FileProviders.Composite/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -Microsoft.Extensions.FileProviders.Composite is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md deleted file mode 100644 index bf3378a56e63dd..00000000000000 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -Microsoft.Extensions.FileProviders.Physical is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md deleted file mode 100644 index a5d26b28318fda..00000000000000 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -Microsoft.Extensions.FileSystemGlobbing is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Hosting.Systemd/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Hosting.Systemd/src/PACKAGE.md deleted file mode 100644 index ffb5501c8568fe..00000000000000 --- a/src/libraries/Microsoft.Extensions.Hosting.Systemd/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -Microsoft.Extensions.Hosting.Systemd is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/PACKAGE.md deleted file mode 100644 index 7c38fc44d350f7..00000000000000 --- a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -Microsoft.Extensions.Logging.Configuration is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.EventLog/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.EventLog/src/PACKAGE.md deleted file mode 100644 index 9f1330aad75f6a..00000000000000 --- a/src/libraries/Microsoft.Extensions.Logging.EventLog/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -Microsoft.Extensions.Logging.EventLog is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.EventSource/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.EventSource/src/PACKAGE.md deleted file mode 100644 index 8a67a2888f46db..00000000000000 --- a/src/libraries/Microsoft.Extensions.Logging.EventSource/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -Microsoft.Extensions.Logging.EventSource is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md deleted file mode 100644 index 7bab863fa95cc9..00000000000000 --- a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -Microsoft.Extensions.Logging.TraceSource is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md deleted file mode 100644 index 3bf3280ad4cf1b..00000000000000 --- a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -Microsoft.Extensions.Options.DataAnnotations is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/PACKAGE.md b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Win32.Registry.AccessControl/src/PACKAGE.md b/src/libraries/Microsoft.Win32.Registry.AccessControl/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/Microsoft.Win32.Registry.AccessControl/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Win32.SystemEvents/src/PACKAGE.md b/src/libraries/Microsoft.Win32.SystemEvents/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/Microsoft.Win32.SystemEvents/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.XmlSerializer.Generator/src/PACKAGE.md b/src/libraries/Microsoft.XmlSerializer.Generator/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/Microsoft.XmlSerializer.Generator/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.CodeDom/src/PACKAGE.md b/src/libraries/System.CodeDom/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.CodeDom/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.Composition.Registration/src/PACKAGE.md b/src/libraries/System.ComponentModel.Composition.Registration/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.ComponentModel.Composition.Registration/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.Composition/src/PACKAGE.md b/src/libraries/System.ComponentModel.Composition/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.ComponentModel.Composition/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Composition.AttributedModel/src/PACKAGE.md b/src/libraries/System.Composition.AttributedModel/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Composition.AttributedModel/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Composition.Convention/src/PACKAGE.md b/src/libraries/System.Composition.Convention/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Composition.Convention/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Composition.Hosting/src/PACKAGE.md b/src/libraries/System.Composition.Hosting/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Composition.Hosting/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Composition.Runtime/src/PACKAGE.md b/src/libraries/System.Composition.Runtime/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Composition.Runtime/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Composition.TypedParts/src/PACKAGE.md b/src/libraries/System.Composition.TypedParts/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Composition.TypedParts/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Composition/src/PACKAGE.md b/src/libraries/System.Composition/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Composition/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/PACKAGE.md b/src/libraries/System.Diagnostics.DiagnosticSource/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md b/src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Drawing.Common/src/PACKAGE.md b/src/libraries/System.Drawing.Common/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Drawing.Common/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Formats.Cbor/src/PACKAGE.md b/src/libraries/System.Formats.Cbor/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Formats.Cbor/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.IO.Hashing/src/PACKAGE.md b/src/libraries/System.IO.Hashing/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.IO.Hashing/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.IO.Packaging/src/PACKAGE.md b/src/libraries/System.IO.Packaging/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.IO.Packaging/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.IO.Pipelines/src/PACKAGE.md b/src/libraries/System.IO.Pipelines/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.IO.Pipelines/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Management/src/PACKAGE.md b/src/libraries/System.Management/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Management/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Memory.Data/src/PACKAGE.md b/src/libraries/System.Memory.Data/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Memory.Data/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Numerics.Tensors/src/PACKAGE.md b/src/libraries/System.Numerics.Tensors/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Numerics.Tensors/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Reflection.Context/src/PACKAGE.md b/src/libraries/System.Reflection.Context/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Reflection.Context/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Resources.Extensions/src/PACKAGE.md b/src/libraries/System.Resources.Extensions/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Resources.Extensions/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Runtime.Serialization.Schema/src/PACKAGE.md b/src/libraries/System.Runtime.Serialization.Schema/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Runtime.Serialization.Schema/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Cose/src/PACKAGE.md b/src/libraries/System.Security.Cryptography.Cose/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cose/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/PACKAGE.md b/src/libraries/System.Security.Cryptography.Pkcs/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md b/src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Xml/src/PACKAGE.md b/src/libraries/System.Security.Cryptography.Xml/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Security.Cryptography.Xml/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Security.Permissions/src/PACKAGE.md b/src/libraries/System.Security.Permissions/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Security.Permissions/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.ServiceModel.Syndication/src/PACKAGE.md b/src/libraries/System.ServiceModel.Syndication/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.ServiceModel.Syndication/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/PACKAGE.md b/src/libraries/System.ServiceProcess.ServiceController/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.ServiceProcess.ServiceController/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Text.Encodings.Web/src/PACKAGE.md b/src/libraries/System.Text.Encodings.Web/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Text.Encodings.Web/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Threading.AccessControl/src/PACKAGE.md b/src/libraries/System.Threading.AccessControl/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Threading.AccessControl/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Threading.RateLimiting/src/PACKAGE.md b/src/libraries/System.Threading.RateLimiting/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Threading.RateLimiting/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/PACKAGE.md b/src/libraries/System.Threading.Tasks.Dataflow/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Threading/src/PACKAGE.md b/src/libraries/System.Threading/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Threading/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Windows.Extensions/src/PACKAGE.md b/src/libraries/System.Windows.Extensions/src/PACKAGE.md deleted file mode 100644 index 2709a6e84e284f..00000000000000 --- a/src/libraries/System.Windows.Extensions/src/PACKAGE.md +++ /dev/null @@ -1,44 +0,0 @@ -## About - - - - - -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - -## Additional Documentation - - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - - -## Feedback & Contributing - - - -**LIBRARY NAME** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file From 600a331c8e6e0e3ecd52290a6cc323245faa1353 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 18 Sep 2023 14:15:20 +0200 Subject: [PATCH 249/783] Update Feedback library name markdown style --- src/libraries/System.Data.Odbc/src/PACKAGE.md | 2 +- src/libraries/System.Data.OleDb/src/PACKAGE.md | 2 +- src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md | 2 +- .../System.Diagnostics.PerformanceCounter/src/PACKAGE.md | 2 +- .../System.DirectoryServices.AccountManagement/src/PACKAGE.md | 2 +- src/libraries/System.DirectoryServices/src/PACKAGE.md | 2 +- src/libraries/System.IO.Ports/src/PACKAGE.md | 2 +- src/libraries/System.Net.Http.Json/src/PACKAGE.md | 2 +- src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md | 2 +- src/libraries/System.Speech/src/PACKAGE.md | 2 +- src/libraries/System.Threading.Channels/src/PACKAGE.md | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.Data.Odbc/src/PACKAGE.md b/src/libraries/System.Data.Odbc/src/PACKAGE.md index 4211f7f44ee1e5..295da33bd964c3 100644 --- a/src/libraries/System.Data.Odbc/src/PACKAGE.md +++ b/src/libraries/System.Data.Odbc/src/PACKAGE.md @@ -42,4 +42,4 @@ System.Data.OleDb is a similar package for accessing OLE DB data sources. ## Feedback & Contributing -**System.Data.Odbc** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports are welcome at [the GitHub repository](https://github.com/dotnet/runtime). This package is considered complete and we only consider low-risk, high-impact fixes that are necessary to maintain or improve quality. \ No newline at end of file +System.Data.Odbc is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports are welcome at [the GitHub repository](https://github.com/dotnet/runtime). This package is considered complete and we only consider low-risk, high-impact fixes that are necessary to maintain or improve quality. \ No newline at end of file diff --git a/src/libraries/System.Data.OleDb/src/PACKAGE.md b/src/libraries/System.Data.OleDb/src/PACKAGE.md index 85b73459db6794..ffc6aa46332ffd 100644 --- a/src/libraries/System.Data.OleDb/src/PACKAGE.md +++ b/src/libraries/System.Data.OleDb/src/PACKAGE.md @@ -42,4 +42,4 @@ System.Data.Odbc is a similar package for accessing ODBC data sources. ## Feedback & Contributing -**System.Data.OleDb** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports are welcome at [the GitHub repository](https://github.com/dotnet/runtime). This package is considered complete and we only consider low-risk, high-impact fixes that are necessary to maintain or improve quality. \ No newline at end of file +System.Data.OleDb is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports are welcome at [the GitHub repository](https://github.com/dotnet/runtime). This package is considered complete and we only consider low-risk, high-impact fixes that are necessary to maintain or improve quality. \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md b/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md index 2821a14f7c70b0..78ae5d190b780f 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md +++ b/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md @@ -84,4 +84,4 @@ Under the [`System.Diagnostics.Eventing.Reader`](https://learn.microsoft.com/en- -**System.Diagnostics.EventLog** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). +System.Diagnostics.EventLog is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md b/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md index 6f74c9a86379c6..22ce6c10beb7ab 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md @@ -220,4 +220,4 @@ Under the [`System.Diagnostics.PerformanceData`](https://learn.microsoft.com/en- -**System.Diagnostics.PerformanceCounter** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). +System.Diagnostics.PerformanceCounter is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md index 1cb6350eb96903..4cb5ff5494796e 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md @@ -72,4 +72,4 @@ The main types provided by this library are: -**System.DirectoryServices.AccountManagement** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). +System.DirectoryServices.AccountManagement is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). diff --git a/src/libraries/System.DirectoryServices/src/PACKAGE.md b/src/libraries/System.DirectoryServices/src/PACKAGE.md index 423ed87b7f386c..4c879dd574aa3e 100644 --- a/src/libraries/System.DirectoryServices/src/PACKAGE.md +++ b/src/libraries/System.DirectoryServices/src/PACKAGE.md @@ -79,4 +79,4 @@ The main types provided by this library are: -**System.DirectoryServices** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). +System.DirectoryServices is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). diff --git a/src/libraries/System.IO.Ports/src/PACKAGE.md b/src/libraries/System.IO.Ports/src/PACKAGE.md index b450bd4318cb3e..e8494878cd28f0 100644 --- a/src/libraries/System.IO.Ports/src/PACKAGE.md +++ b/src/libraries/System.IO.Ports/src/PACKAGE.md @@ -55,4 +55,4 @@ The main type provided by this library is: -**System.IO.Ports** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). +System.IO.Ports is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). diff --git a/src/libraries/System.Net.Http.Json/src/PACKAGE.md b/src/libraries/System.Net.Http.Json/src/PACKAGE.md index 5c084900142c12..23fa95df54eccf 100644 --- a/src/libraries/System.Net.Http.Json/src/PACKAGE.md +++ b/src/libraries/System.Net.Http.Json/src/PACKAGE.md @@ -47,4 +47,4 @@ The main types provided by this library are: ## Feedback & Contributing -**System.Net.Http.Json** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). +System.Net.Http.Json is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md b/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md index ab0ba9b13aab92..44f5a5eb2ff3ee 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md @@ -45,4 +45,4 @@ The main types provided by this library are: ## Feedback & Contributing -**System.Net.Http.WinHttpHandler** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). +System.Net.Http.WinHttpHandler is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). diff --git a/src/libraries/System.Speech/src/PACKAGE.md b/src/libraries/System.Speech/src/PACKAGE.md index 4d2a8df1f1f8e4..32b4997443e164 100644 --- a/src/libraries/System.Speech/src/PACKAGE.md +++ b/src/libraries/System.Speech/src/PACKAGE.md @@ -98,4 +98,4 @@ The main types provided by this library are: -**System.Speech** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). +System.Speech is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). diff --git a/src/libraries/System.Threading.Channels/src/PACKAGE.md b/src/libraries/System.Threading.Channels/src/PACKAGE.md index cd9c6b829e10bb..f022aaf5ba32f2 100644 --- a/src/libraries/System.Threading.Channels/src/PACKAGE.md +++ b/src/libraries/System.Threading.Channels/src/PACKAGE.md @@ -70,4 +70,4 @@ https://www.nuget.org/packages/System.Threading.Tasks.Dataflow/ -**System.Threading.Channels** is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +System.Threading.Channels is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file From e819ea8b534a2e94ceb4647849e1c228b04284e3 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 18 Sep 2023 14:15:47 +0200 Subject: [PATCH 250/783] Remove en-US culture from links --- .../src/PACKAGE.md | 2 +- .../Microsoft.Bcl.Numerics/src/PACKAGE.md | 2 +- .../src/PACKAGE.md | 2 +- .../src/PACKAGE.md | 2 +- .../src/PACKAGE.md | 2 +- .../src/PACKAGE.md | 2 +- .../src/PACKAGE.md | 2 +- .../src/PACKAGE.md | 2 +- .../src/PACKAGE.md | 4 +-- .../src/PACKAGE.md | 2 +- .../src/PACKAGE.md | 2 +- .../Microsoft.Extensions.Http/src/PACKAGE.md | 10 +++---- src/libraries/System.Data.Odbc/src/PACKAGE.md | 2 +- .../System.Data.OleDb/src/PACKAGE.md | 2 +- .../src/PACKAGE.md | 28 +++++++++---------- .../src/PACKAGE.md | 24 ++++++++-------- .../src/PACKAGE.md | 2 +- src/libraries/System.IO.Ports/src/PACKAGE.md | 4 +-- .../src/PACKAGE.md | 4 +-- .../System.Runtime.Caching/src/PACKAGE.md | 8 +++--- src/libraries/System.Speech/src/PACKAGE.md | 8 +++--- src/libraries/System.Text.Json/src/PACKAGE.md | 4 +-- 22 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/PACKAGE.md index a4a5af4a370f6f..e0c6e8ae9adaae 100644 --- a/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/PACKAGE.md +++ b/src/libraries/Microsoft.Bcl.AsyncInterfaces/src/PACKAGE.md @@ -54,7 +54,7 @@ The main types provided by this library are: -* [C# Feature Specification](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/async-streams) +* [C# Feature Specification](https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-8.0/async-streams) * [Walkthrough article](https://learn.microsoft.com/archive/msdn-magazine/2019/november/csharp-iterating-with-async-enumerables-in-csharp-8) ## Feedback & Contributing diff --git a/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md index faa3594f73e151..87db6a1678284e 100644 --- a/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md +++ b/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md @@ -40,7 +40,7 @@ The main types provided by this library are: -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.mathf) +* [API documentation](https://learn.microsoft.com/dotnet/api/system.mathf) ## Feedback & Contributing diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Caching.Memory/src/PACKAGE.md index 8798aa1ff8f38f..a9e1c0e00615d6 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/src/PACKAGE.md @@ -73,7 +73,7 @@ The main types provided by this library are: * [Conceptual documentation](https://learn.microsoft.com/dotnet/core/extensions/caching) -* [Cache in-memory in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory) +* [Cache in-memory in ASP.NET Core](https://learn.microsoft.com/aspnet/core/performance/caching/memory) * [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.caching.memory) ## Related Packages diff --git a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md index bf951fcc17968e..428cc0faf6b8e6 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md @@ -62,7 +62,7 @@ The main types provided by this library are: * [Configuration in .NET](https://learn.microsoft.com/dotnet/core/extensions/configuration) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration) ## Related Packages diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/PACKAGE.md index c7caaacac6c1c4..861b0687843ea0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/PACKAGE.md @@ -116,7 +116,7 @@ The main types provided by this library are: * [Configuration in .NET](https://learn.microsoft.com/dotnet/core/extensions/configuration) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration) ## Related Packages diff --git a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md index 7d4c1543012d4c..91bcc9a646a501 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md @@ -31,7 +31,7 @@ The main types provided by this library are: * [Command-line configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#command-line-configuration-provider) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.commandline) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.commandline) ## Related Packages diff --git a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/PACKAGE.md index d9612166e7ecd4..3363278a0108c0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/PACKAGE.md @@ -53,7 +53,7 @@ The main types provided by this library are: * [Environment variable configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#environment-variable-configuration-provider) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.environmentvariables) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.environmentvariables) ## Related Packages diff --git a/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md index a86dbd4757ea19..1a32dfbb88ab79 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md @@ -31,7 +31,7 @@ The main types provided by this library are: * [INI configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#ini-configuration-provider) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.ini) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.ini) ## Related Packages diff --git a/src/libraries/Microsoft.Extensions.Configuration.Json/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Json/src/PACKAGE.md index b1b0a8fff8421c..777a3420ad3319 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Json/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Json/src/PACKAGE.md @@ -86,8 +86,8 @@ The main types provided by this library are: -* [JSON configuration provider](https://learn.microsoft.com/en-us/dotnet/core/extensions/configuration-providers#json-configuration-provider) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.json) +* [JSON configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#json-configuration-provider) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.json) ## Related Packages diff --git a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/PACKAGE.md index 976bf5598f60f4..12ec8f399a9120 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/PACKAGE.md @@ -32,7 +32,7 @@ The main types provided by this library are: * [Configuration in .NET](https://learn.microsoft.com/dotnet/core/extensions/configuration) * [Safe storage of app secrets in development in ASP.NET Core](https://learn.microsoft.com/aspnet/core/security/app-secrets) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.usersecrets) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.usersecrets) ## Related Packages diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Xml/src/PACKAGE.md index 602c919514ddce..38560635038cb8 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Xml/src/PACKAGE.md @@ -86,7 +86,7 @@ The main types provided by this library are: * [XML configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#xml-configuration-provider) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.xml) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.xml) ## Related Packages diff --git a/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md index 15fc9683b87abd..294cb308cc7a9b 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Http/src/PACKAGE.md @@ -16,7 +16,7 @@ -Note that lifetime management of `HttpClient` instances created by `HttpClientFactory` is completely different from instances created manually. The strategies are to use either short-lived clients created by `HttpClientFactory` or long-lived clients with `PooledConnectionLifetime` set up. For more information, see the [HttpClient lifetime management section](https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory#httpclient-lifetime-management) in the conceptual docs and [Guidelines for using HTTP clients](https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient-guidelines). +Note that lifetime management of `HttpClient` instances created by `HttpClientFactory` is completely different from instances created manually. The strategies are to use either short-lived clients created by `HttpClientFactory` or long-lived clients with `PooledConnectionLifetime` set up. For more information, see the [HttpClient lifetime management section](https://learn.microsoft.com/dotnet/core/extensions/httpclient-factory#httpclient-lifetime-management) in the conceptual docs and [Guidelines for using HTTP clients](https://learn.microsoft.com/dotnet/fundamentals/networking/http/httpclient-guidelines). ### Configuring HttpClient @@ -61,10 +61,10 @@ The main types provided by this library are: -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory) - * Also see [HttpClient guidelines](https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient-guidelines) conceptual doc -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.net.http?view=dotnet-plat-ext-7.0) - * Also see [`AddHttpClient` extension method](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.httpclientfactoryservicecollectionextensions?view=dotnet-plat-ext-7.0) API doc +* [Conceptual documentation](https://learn.microsoft.com/dotnet/core/extensions/httpclient-factory) + * Also see [HttpClient guidelines](https://learn.microsoft.com/dotnet/fundamentals/networking/http/httpclient-guidelines) conceptual doc +* [API documentation](https://learn.microsoft.com/dotnet/api/system.net.http?view=dotnet-plat-ext-7.0) + * Also see [`AddHttpClient` extension method](https://learn.microsoft.com/dotnet/api/microsoft.extensions.dependencyinjection.httpclientfactoryservicecollectionextensions?view=dotnet-plat-ext-7.0) API doc ## Related Packages diff --git a/src/libraries/System.Data.Odbc/src/PACKAGE.md b/src/libraries/System.Data.Odbc/src/PACKAGE.md index 295da33bd964c3..7195ca77a50064 100644 --- a/src/libraries/System.Data.Odbc/src/PACKAGE.md +++ b/src/libraries/System.Data.Odbc/src/PACKAGE.md @@ -34,7 +34,7 @@ while (reader.Read()) ## Additional Documentation -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.data.odbc) +* [API documentation](https://learn.microsoft.com/dotnet/api/system.data.odbc) ## Related Packages diff --git a/src/libraries/System.Data.OleDb/src/PACKAGE.md b/src/libraries/System.Data.OleDb/src/PACKAGE.md index ffc6aa46332ffd..be973625ebef7d 100644 --- a/src/libraries/System.Data.OleDb/src/PACKAGE.md +++ b/src/libraries/System.Data.OleDb/src/PACKAGE.md @@ -34,7 +34,7 @@ while (reader.Read()) ## Additional Documentation -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.data.oledb) +* [API documentation](https://learn.microsoft.com/dotnet/api/system.data.oledb) ## Related Packages diff --git a/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md b/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md index 78ae5d190b780f..56e111a68ac802 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md +++ b/src/libraries/System.Diagnostics.EventLog/src/PACKAGE.md @@ -50,28 +50,28 @@ Notes: The main types provided by this library are: -Under the [`System.Diagnostics`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics) namespace, the main types are: +Under the [`System.Diagnostics`](https://learn.microsoft.com/dotnet/api/System.Diagnostics) namespace, the main types are: -- [`System.Diagnostics.EventLog`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLog) -- [`System.Diagnostics.EventLogEntry`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLogEntry) -- [`System.Diagnostics.EventLogEntryCollection`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLogEntryCollection) -- [`System.Diagnostics.EventLogEntryType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLogEntryType) +- [`System.Diagnostics.EventLog`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.EventLog) +- [`System.Diagnostics.EventLogEntry`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.EventLogEntry) +- [`System.Diagnostics.EventLogEntryCollection`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.EventLogEntryCollection) +- [`System.Diagnostics.EventLogEntryType`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.EventLogEntryType) -Under the [`System.Diagnostics.Eventing.Reader`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader) namespace, the main types are: +Under the [`System.Diagnostics.Eventing.Reader`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.Eventing.Reader) namespace, the main types are: -- [`System.Diagnostics.Eventing.Reader.EventLogQuery`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogQuery) -- [`System.Diagnostics.Eventing.Reader.EventLogReader`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogReader) -- [`System.Diagnostics.Eventing.Reader.EventLogRecord`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogRecord) -- [`System.Diagnostics.Eventing.Reader.EventLogSession`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogSession) -- [`System.Diagnostics.Eventing.Reader.EventLogType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogType) -- [`System.Diagnostics.Eventing.Reader.EventRecord`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.Eventing.Reader.EventRecord) +- [`System.Diagnostics.Eventing.Reader.EventLogQuery`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogQuery) +- [`System.Diagnostics.Eventing.Reader.EventLogReader`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogReader) +- [`System.Diagnostics.Eventing.Reader.EventLogRecord`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogRecord) +- [`System.Diagnostics.Eventing.Reader.EventLogSession`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogSession) +- [`System.Diagnostics.Eventing.Reader.EventLogType`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.Eventing.Reader.EventLogType) +- [`System.Diagnostics.Eventing.Reader.EventRecord`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.Eventing.Reader.EventRecord) ## Additional Documentation -- [Microsoft Learn - System.Diagnostics.EventLog API reference](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.EventLog) -- [Windows App Development - Event logging](https://learn.microsoft.com/en-us/windows/win32/eventlog/event-logging) +- [Microsoft Learn - System.Diagnostics.EventLog API reference](https://learn.microsoft.com/dotnet/api/System.Diagnostics.EventLog) +- [Windows App Development - Event logging](https://learn.microsoft.com/windows/win32/eventlog/event-logging) - [GitHub - Source code](https://github.com/dotnet/runtime/tree/main/src/libraries/System.Diagnostics.EventLog) ## Related Packages diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md b/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md index 22ce6c10beb7ab..475291274ff289 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/PACKAGE.md @@ -188,26 +188,26 @@ Notes: The main types provided by this library are: -Under the [`System.Diagnostics`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics) namespace, the main types are: +Under the [`System.Diagnostics`](https://learn.microsoft.com/dotnet/api/System.Diagnostics) namespace, the main types are: -* [`System.Diagnostics.CounterCreationData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.CounterCreationData) -* [`System.Diagnostics.CounterCreationDataCollection`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.CounterCreationDataCollection) -* [`System.Diagnostics.PerformanceCounter`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceCounter) +* [`System.Diagnostics.CounterCreationData`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.CounterCreationData) +* [`System.Diagnostics.CounterCreationDataCollection`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.CounterCreationDataCollection) +* [`System.Diagnostics.PerformanceCounter`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.PerformanceCounter) -Under the [`System.Diagnostics.PerformanceData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData) namespace, the main types are: +Under the [`System.Diagnostics.PerformanceData`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.PerformanceData) namespace, the main types are: -* [`System.Diagnostics.PerformanceData.CounterData`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterData) -* [`System.Diagnostics.PerformanceData.CounterSet`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterSet) -* [`System.Diagnostics.PerformanceData.CounterType`](https://learn.microsoft.com/en-us/dotnet/api/System.Diagnostics.PerformanceData.CounterType) +* [`System.Diagnostics.PerformanceData.CounterData`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.PerformanceData.CounterData) +* [`System.Diagnostics.PerformanceData.CounterSet`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.PerformanceData.CounterSet) +* [`System.Diagnostics.PerformanceData.CounterType`](https://learn.microsoft.com/dotnet/api/System.Diagnostics.PerformanceData.CounterType) ## Additional Documentation -* [Microsoft Learn - System.Diagnostics.PerformanceCounter API reference](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.performancecounter?view=dotnet-plat-ext-7.0) -* [Windows App Development - Performance Counters](https://learn.microsoft.com/en-us/windows/win32/perfctrs/performance-counters-portal) -* [Windows Performance and Reliability - Windows Performance Monitor](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc749249(v=ws.11)) -* [Windows Server - perfmon](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/perfmon) +* [Microsoft Learn - System.Diagnostics.PerformanceCounter API reference](https://learn.microsoft.com/dotnet/api/system.diagnostics.performancecounter?view=dotnet-plat-ext-7.0) +* [Windows App Development - Performance Counters](https://learn.microsoft.com/windows/win32/perfctrs/performance-counters-portal) +* [Windows Performance and Reliability - Windows Performance Monitor](https://learn.microsoft.com/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc749249(v=ws.11)) +* [Windows Server - perfmon](https://learn.microsoft.com/windows-server/administration/windows-commands/perfmon) * [GitHub - Source code](https://github.com/dotnet/runtime/tree/main/src/libraries/System.Diagnostics.PerformanceCounter) ## Related Packages diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md index 4cb5ff5494796e..7d761e089fbb8c 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md @@ -57,7 +57,7 @@ The main types provided by this library are: * Conceptual documentations: - - [System.DirectoryServices.AccountManagement Namespace Overview](https://learn.microsoft.com/en-us/previous-versions/bb384379(v=vs.90)) + - [System.DirectoryServices.AccountManagement Namespace Overview](https://learn.microsoft.com/previous-versions/bb384379(v=vs.90)) - [About System.DirectoryServices.AccountManagement](https://learn.microsoft.com//previous-versions/bb384375(v=vs.90)) - [Using System.DirectoryServices.AccountManagement](https://learn.microsoft.com/previous-versions/bb384384(v=vs.90)) * API documentation diff --git a/src/libraries/System.IO.Ports/src/PACKAGE.md b/src/libraries/System.IO.Ports/src/PACKAGE.md index e8494878cd28f0..90da18ddefd2f0 100644 --- a/src/libraries/System.IO.Ports/src/PACKAGE.md +++ b/src/libraries/System.IO.Ports/src/PACKAGE.md @@ -43,8 +43,8 @@ The main type provided by this library is: -* [SerialPort class documentation](https://learn.microsoft.com/en-us/dotnet/api/system.io.ports.serialport?view=dotnet-plat-ext-7.0) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/System.IO.Ports) +* [SerialPort class documentation](https://learn.microsoft.com/dotnet/api/system.io.ports.serialport?view=dotnet-plat-ext-7.0) +* [API documentation](https://learn.microsoft.com/dotnet/api/System.IO.Ports) ## Related Packages diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md b/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md index 44f5a5eb2ff3ee..dcc800e598728a 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/PACKAGE.md @@ -1,6 +1,6 @@ ## About -This package provides an [`HttpMessageHandler`](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpmessagehandler) implementation backed by [Windows HTTP Services (WinHTTP)](https://learn.microsoft.com/en-us/windows/win32/winhttp/winhttp-start-page). +This package provides an [`HttpMessageHandler`](https://learn.microsoft.com/dotnet/api/system.net.http.httpmessagehandler) implementation backed by [Windows HTTP Services (WinHTTP)](https://learn.microsoft.com/windows/win32/winhttp/winhttp-start-page). While the use of the default `HttpClientHandler` is highly recommended for applications targeting modern .NET, `WinHttpHandler` might help migration scenarios by providing an alternative HTTP backend for Windows that works consistently accross .NET Framework and modern .NET. ## Key Features @@ -41,7 +41,7 @@ The main types provided by this library are: ## Additional Documentation -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.winhttphandler) +* [API documentation](https://learn.microsoft.com/dotnet/api/system.net.http.winhttphandler) ## Feedback & Contributing diff --git a/src/libraries/System.Runtime.Caching/src/PACKAGE.md b/src/libraries/System.Runtime.Caching/src/PACKAGE.md index 56b8069b131681..9f9b02700d5ba2 100644 --- a/src/libraries/System.Runtime.Caching/src/PACKAGE.md +++ b/src/libraries/System.Runtime.Caching/src/PACKAGE.md @@ -4,7 +4,7 @@ Packaged set of simple caching API's derived from those of the same namespace available in .NET Framework since 4.0. This package is intended for use as a bridge when porting .NET Framework applications to .NET. -[Microsoft.Extensions.Caching.Memory](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Memory/)/[IMemoryCache](https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-7.0) is recommended over `System.Runtime.Caching`/`MemoryCache` because it's better integrated into ASP.NET Core. For example, `IMemoryCache` works natively with ASP.NET Core [dependency injection](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-7.0). +[Microsoft.Extensions.Caching.Memory](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Memory/)/[IMemoryCache](https://learn.microsoft.com/aspnet/core/performance/caching/memory?view=aspnetcore-7.0) is recommended over `System.Runtime.Caching`/`MemoryCache` because it's better integrated into ASP.NET Core. For example, `IMemoryCache` works natively with ASP.NET Core [dependency injection](https://learn.microsoft.com/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-7.0). > > [!IMPORTANT] > Use `System.Runtime.Caching`/`MemoryCache` as a compatibility bridge when porting code from .NET 4.x to .NET Core. @@ -34,10 +34,10 @@ The main types provided by this library are: -[MemoryCache.PhysicalMemoryLimit](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.caching.memorycache.physicalmemorylimit?view=dotnet-plat-ext-7.0) property is only supported on windows. +[MemoryCache.PhysicalMemoryLimit](https://learn.microsoft.com/dotnet/api/system.runtime.caching.memorycache.physicalmemorylimit?view=dotnet-plat-ext-7.0) property is only supported on windows. -* [Caching in .NET](https://learn.microsoft.com/en-us/dotnet/core/extensions/caching) -* [Cache in-memory in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-7.0 ) +* [Caching in .NET](https://learn.microsoft.com/dotnet/core/extensions/caching) +* [Cache in-memory in ASP.NET Core](https://learn.microsoft.com/aspnet/core/performance/caching/memory?view=aspnetcore-7.0 ) ## Related Packages diff --git a/src/libraries/System.Speech/src/PACKAGE.md b/src/libraries/System.Speech/src/PACKAGE.md index 32b4997443e164..e7d46cc047307e 100644 --- a/src/libraries/System.Speech/src/PACKAGE.md +++ b/src/libraries/System.Speech/src/PACKAGE.md @@ -1,7 +1,7 @@ ## About -Provides APIs for speech recognition and synthesis built on the [Microsoft Speech API](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms723627(v=vs.85)) in Windows. Not supported on other platforms. +Provides APIs for speech recognition and synthesis built on the [Microsoft Speech API](https://learn.microsoft.com/previous-versions/windows/desktop/ms723627(v=vs.85)) in Windows. Not supported on other platforms. This package is provided primarily for compatibility with code being ported from .NET Framework and is not accepting new features. @@ -90,9 +90,9 @@ The main types provided by this library are: -* [Conceptual documentation](https://learn.microsoft.com/en-us/previous-versions/office/developer/speech-technologies/hh361625(v%3doffice.14)) -* [Speech.Recognition API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.speech.recognition) -* [Speech.Synthesis API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.speech.synthesis) +* [Conceptual documentation](https://learn.microsoft.com/previous-versions/office/developer/speech-technologies/hh361625(v%3doffice.14)) +* [Speech.Recognition API documentation](https://learn.microsoft.com/dotnet/api/system.speech.recognition) +* [Speech.Synthesis API documentation](https://learn.microsoft.com/dotnet/api/system.speech.synthesis) ## Feedback & Contributing diff --git a/src/libraries/System.Text.Json/src/PACKAGE.md b/src/libraries/System.Text.Json/src/PACKAGE.md index 7cbbec76e65b32..1ddd210a0acb28 100644 --- a/src/libraries/System.Text.Json/src/PACKAGE.md +++ b/src/libraries/System.Text.Json/src/PACKAGE.md @@ -239,8 +239,8 @@ The main types provided by this library are: ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.text.json) +* [Conceptual documentation](https://learn.microsoft.com/dotnet/standard/serialization/system-text-json/overview) +* [API documentation](https://learn.microsoft.com/dotnet/api/system.text.json) ## Related Packages From 8890301670c4e933b98b17a18ddf254303d580e0 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 18 Sep 2023 14:17:31 +0200 Subject: [PATCH 251/783] Replace important markdown tag with bold --- src/libraries/System.Runtime.Caching/src/PACKAGE.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libraries/System.Runtime.Caching/src/PACKAGE.md b/src/libraries/System.Runtime.Caching/src/PACKAGE.md index 9f9b02700d5ba2..60abdb27032f1d 100644 --- a/src/libraries/System.Runtime.Caching/src/PACKAGE.md +++ b/src/libraries/System.Runtime.Caching/src/PACKAGE.md @@ -6,9 +6,7 @@ Packaged set of simple caching API's derived from those of the same namespace av [Microsoft.Extensions.Caching.Memory](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Memory/)/[IMemoryCache](https://learn.microsoft.com/aspnet/core/performance/caching/memory?view=aspnetcore-7.0) is recommended over `System.Runtime.Caching`/`MemoryCache` because it's better integrated into ASP.NET Core. For example, `IMemoryCache` works natively with ASP.NET Core [dependency injection](https://learn.microsoft.com/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-7.0). -> > [!IMPORTANT] -> Use `System.Runtime.Caching`/`MemoryCache` as a compatibility bridge when porting code from .NET 4.x to .NET Core. - +**Use `System.Runtime.Caching`/`MemoryCache` as a compatibility bridge when porting code from .NET 4.x to .NET Core.** ## Key Features From 0b106c54af8d9d8a7dbf55d3d790f17d2045f327 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 18 Sep 2023 14:19:24 +0200 Subject: [PATCH 252/783] MathF PR feedback --- src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md index 87db6a1678284e..620514e8bb0b82 100644 --- a/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md +++ b/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md @@ -13,17 +13,12 @@ As of .NET Core 2.0 and .NET Standard 2.1, the C# language has support for math ```C# using System; -using System.MathF. internal static class Program { private static async Task Main() - { - Console.WriteLine("Starting..."); - + { Console.WriteLine(MathF.Max(1f, 5f)); // returns 5f - - Console.WriteLine("Finished!"); } } ``` From 2cf3fafb650f789a3d9432803b6d1a5916c3decc Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 18 Sep 2023 14:52:31 +0200 Subject: [PATCH 253/783] Add System.Management packag readme --- .../System.Management/src/PACKAGE.md | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/libraries/System.Management/src/PACKAGE.md diff --git a/src/libraries/System.Management/src/PACKAGE.md b/src/libraries/System.Management/src/PACKAGE.md new file mode 100644 index 00000000000000..733cc750bcac1f --- /dev/null +++ b/src/libraries/System.Management/src/PACKAGE.md @@ -0,0 +1,69 @@ +## About + + +Provides access to a rich set of management information and management events about the system, devices, and applications instrumented to the Windows Management Instrumentation (WMI) infrastructure. Not supported on other platforms. + +## Key Features + + + +* Consume Windows Management Instrumentation (WMI) data and events +* High performance extensible event mechanism + +## How to Use + + + +### Retrieve management information +```C# +using System.Management; + +// Get the WMI class +ManagementClass managementClass = new("Win32_Processor"); + +// Loop through the WMI class instances and print the processor information found +foreach (ManagementObject managementObject in managementClass.GetInstances()) +{ + Console.WriteLine("--- Processor information ---"); + Console.WriteLine($"Name: {managementObject["Name"]}"); + Console.WriteLine($"Architecture: {managementObject["Architecture"]}"); +} +``` + +### Query management information via the SelectQuery type +```C# +using System.Management; + +// Search for win32 services with a stopped state +SelectQuery selectQuery = new("Win32_Service", "State = 'Stopped'"); +ManagementObjectSearcher managementObjectSearcher = new(selectQuery); + +foreach (ManagementObject service in managementObjectSearcher.Get()) +{ + Console.WriteLine(service.ToString()); +} +``` + +## Main Types + + + +The main types provided by this library are: + +* `System.Management.ManagementClass` +* `System.Management.ManagementObject` +* `System.Management.SelectQuery` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/windows/win32/wmisdk/wmi-start-page) +* [System.Management API documentation](https://learn.microsoft.com/dotnet/api/system.management?view=dotnet-plat-ext-7.0) +* [System.Management.ManagementClass documentation](https://learn.microsoft.com/dotnet/api/system.management.managementclass.-ctor?view=dotnet-plat-ext-7.0) + +## Feedback & Contributing + + + +System.Management is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From dc9c01278e2bd990c97588fabe8e4beffd757d10 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 18 Sep 2023 14:57:53 +0200 Subject: [PATCH 254/783] Fix trailing whitespace --- src/libraries/System.Management/src/PACKAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Management/src/PACKAGE.md b/src/libraries/System.Management/src/PACKAGE.md index 733cc750bcac1f..280347191d1013 100644 --- a/src/libraries/System.Management/src/PACKAGE.md +++ b/src/libraries/System.Management/src/PACKAGE.md @@ -30,7 +30,7 @@ foreach (ManagementObject managementObject in managementClass.GetInstances()) } ``` -### Query management information via the SelectQuery type +### Query management information via the SelectQuery type ```C# using System.Management; From c59bf659eec0447129f70416c0a9659acc7aead5 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 18 Sep 2023 15:30:08 +0200 Subject: [PATCH 255/783] Add ServiceController package readme --- .../src/PACKAGE.md | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/libraries/System.ServiceProcess.ServiceController/src/PACKAGE.md diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/PACKAGE.md b/src/libraries/System.ServiceProcess.ServiceController/src/PACKAGE.md new file mode 100644 index 00000000000000..902a69d0ae2858 --- /dev/null +++ b/src/libraries/System.ServiceProcess.ServiceController/src/PACKAGE.md @@ -0,0 +1,69 @@ +## About + + +Provides the System.ServiceProcess.ServiceController API, which allows to connect to a Windows service, manipulate it, or get information about it. Not supported on other platforms. + +## Key Features + + + +* Retrieve information from Windows services +* Connect to and manipulate Windows services (start, pause, stop or other operations) + +## How to Use + + + +### Retrieve Windows service information +```C# +using System.ServiceProcess; + +// Loop through all installed Windows services and print the name, status and display name. +foreach (ServiceController serviceController in ServiceController.GetServices()) +{ + Console.WriteLine("Name: " + serviceController.ServiceName); + Console.WriteLine("Status: " + serviceController.Status.ToString()); + Console.WriteLine("Display name: " + serviceController.DisplayName); +} + +// Loop through all installed device driver services +foreach (ServiceController serviceController in ServiceController.GetDevices()) +{ + Console.WriteLine("Name: " + serviceController.ServiceName); + Console.WriteLine("Status: " + serviceController.Status.ToString()); + Console.WriteLine("Display name: " + serviceController.DisplayName); +} +``` + +### Manipulate a Windows service +```C# +using System.ServiceProcess; + +ServiceController service = new("TestServiceName"); +if (service.CanStop && service.Status != ServiceControllerStatus.Stopped && service.Status != ServiceControllerStatus.StopPending) +{ + service.Stop(); +} +``` + +## Main Types + + + +The main types provided by this library are: + +* `System.ServiceProcess.ServiceController` +* `System.ServiceProcess.ServiceControllerStatus` +* `System.ServiceProcess.ServiceType` + +## Additional Documentation + + + +* [System.ServiceController API documentation](https://learn.microsoft.com/dotnet/api/system.serviceprocess.servicecontroller?view=dotnet-plat-ext-7.0) + +## Feedback & Contributing + + + +System.ServiceProcess.ServiceController is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 21727cee290d157c93e4ebd2b292b0021b452f8b Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 18 Sep 2023 15:51:32 +0200 Subject: [PATCH 256/783] Clean-up --- .../Microsoft.Bcl.TimeProvider/src/PACKAGE.md | 1 - .../src/PACKAGE.md | 2 - .../src/PACKAGE.md | 26 ----------- .../src/PACKAGE.md | 22 ---------- .../src/PACKAGE.md | 26 ----------- .../src/PACKAGE.md | 26 ----------- .../src/PACKAGE.md | 22 ---------- .../src/PACKAGE.md | 26 ----------- .../src/PACKAGE.md | 22 ---------- .../src/PACKAGE.md | 22 ---------- .../src/PACKAGE.md | 21 ++++++++- .../src/PACKAGE.md | 1 - .../src/PACKAGE.md | 44 ++++++++++++++++--- .../src/PACKAGE.md | 13 +----- .../System.Reflection.Metadata/src/PACKAGE.md | 8 ---- .../src/PACKAGE.md | 17 +------ .../System.Runtime.Caching/src/PACKAGE.md | 10 ++--- 17 files changed, 64 insertions(+), 245 deletions(-) diff --git a/src/libraries/Microsoft.Bcl.TimeProvider/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.TimeProvider/src/PACKAGE.md index bf767f3354d39a..f3c9c372cf2caf 100644 --- a/src/libraries/Microsoft.Bcl.TimeProvider/src/PACKAGE.md +++ b/src/libraries/Microsoft.Bcl.TimeProvider/src/PACKAGE.md @@ -52,7 +52,6 @@ The main types provided by this library are: * [API documentation](https://learn.microsoft.com/dotnet/api/system.timeprovider) - ## Feedback & Contributing Microsoft.Bcl.TimeProvider is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md index 428cc0faf6b8e6..e744e1b9e73df1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/PACKAGE.md @@ -4,7 +4,6 @@ Provides abstractions of key-value pair based configuration. Interfaces defined in this package are implemented by classes in [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/) and other configuration packages. - ## Key Features @@ -44,7 +43,6 @@ var options = config.Get(); Console.WriteLine(options.NamedProperty); // returns "value for named property" ``` - ## Main Types diff --git a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md index 91bcc9a646a501..8b1734c0421fb3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md @@ -4,28 +4,6 @@ Command line configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to read configuration parameters from the command line arguments of your application. You can use [CommandLineConfigurationExtensions.AddCommandLine](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.commandlineconfigurationextensions.addcommandline) extension method on `IConfigurationBuilder` to add the command line configuration provider to the configuration builder. -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - ## Additional Documentation @@ -33,10 +11,6 @@ The main types provided by this library are: * [Command-line configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#command-line-configuration-provider) * [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.commandline) -## Related Packages - - - ## Feedback & Contributing diff --git a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/PACKAGE.md index 3363278a0108c0..eb9a67bfbfda25 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.EnvironmentVariables/src/PACKAGE.md @@ -4,14 +4,6 @@ Environment variables configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to read configuration parameters from environment variables. You can use [EnvironmentVariablesExtensions.AddEnvironmentVariables](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.environmentvariablesextensions.addenvironmentvariables) extension method on `IConfigurationBuilder` to add the environment variables configuration provider to the configuration builder. -## Key Features - - - -* -* -* - ## How to Use @@ -38,16 +30,6 @@ class Program } ``` -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - ## Additional Documentation @@ -55,10 +37,6 @@ The main types provided by this library are: * [Environment variable configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#environment-variable-configuration-provider) * [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.environmentvariables) -## Related Packages - - - ## Feedback & Contributing diff --git a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/PACKAGE.md index 60b2096828e8ec..4a4f404102c89a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/PACKAGE.md @@ -4,28 +4,6 @@ Provides a base class for file-based configuration providers used with [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/) and extension methods for configuring them. -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - ## Additional Documentation @@ -34,10 +12,6 @@ The main types provided by this library are: * [Microsoft.Extensions.Configuration.FileConfigurationProvider](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.fileconfigurationprovider) * [Microsoft.Extensions.Configuration.FileConfigurationExtensions](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.fileconfigurationextensions) -## Related Packages - - - ## Feedback & Contributing diff --git a/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md index 1a32dfbb88ab79..0fc660489a4fc6 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md @@ -4,28 +4,6 @@ INI configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to read configuration parameters from [INI files](https://en.wikipedia.org/wiki/INI_file). You can use [IniConfigurationExtensions.AddIniFile](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iniconfigurationextensions.addinifile) extension method on `IConfigurationBuilder` to add INI configuration provider to the configuration builder. -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - ## Additional Documentation @@ -33,10 +11,6 @@ The main types provided by this library are: * [INI configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#ini-configuration-provider) * [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.ini) -## Related Packages - - - ## Feedback & Contributing diff --git a/src/libraries/Microsoft.Extensions.Configuration.Json/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Json/src/PACKAGE.md index 777a3420ad3319..825b3dbe412d4d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Json/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Json/src/PACKAGE.md @@ -4,14 +4,6 @@ JSON configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to read your application's settings from a JSON file. You can use [JsonConfigurationExtensions.AddJsonFile](https://docs.microsoft.com/dotnet/api/microsoft.extensions.configuration.jsonconfigurationextensions.addjsonfile) extension method on `IConfigurationBuilder` to add the JSON configuration provider to the configuration builder. -## Key Features - - - -* -* -* - ## How to Use @@ -72,16 +64,6 @@ You can include a configuration file using a code like this in your `.csproj` fi ``` -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - ## Additional Documentation @@ -89,10 +71,6 @@ The main types provided by this library are: * [JSON configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#json-configuration-provider) * [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.json) -## Related Packages - - - ## Feedback & Contributing diff --git a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/PACKAGE.md index 12ec8f399a9120..1fe9ee6c98939e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/PACKAGE.md @@ -4,28 +4,6 @@ User secrets configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). User secrets mechanism enables you to override application configuration settings with values stored in the local secrets file. You can use [UserSecretsConfigurationExtensions.AddUserSecrets](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.usersecretsconfigurationextensions.addusersecrets) extension method on `IConfigurationBuilder` to add user secrets provider to the configuration builder. -## Key Features - - - -* -* -* - -## How to Use - - - -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - ## Additional Documentation @@ -34,10 +12,6 @@ The main types provided by this library are: * [Safe storage of app secrets in development in ASP.NET Core](https://learn.microsoft.com/aspnet/core/security/app-secrets) * [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.usersecrets) -## Related Packages - - - ## Feedback & Contributing diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Xml/src/PACKAGE.md index 38560635038cb8..209645bc5a4732 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Xml/src/PACKAGE.md @@ -4,14 +4,6 @@ XML configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to read configuration parameters from XML files. You can use [XmlConfigurationExtensions.AddXmlFile](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.xmlconfigurationextensions.addxmlfile) extension method on `IConfigurationBuilder` to add XML configuration provider to the configuration builder. -## Key Features - - - -* -* -* - ## How to Use @@ -71,16 +63,6 @@ You can include a configuration file using a code like this in your `.csproj` fi ``` -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - ## Additional Documentation @@ -88,10 +70,6 @@ The main types provided by this library are: * [XML configuration provider](https://learn.microsoft.com/dotnet/core/extensions/configuration-providers#xml-configuration-provider) * [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.xml) -## Related Packages - - - ## Feedback & Contributing diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.DependencyModel/src/PACKAGE.md index d8bcd473f60d0a..19b13040a8aea9 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/PACKAGE.md @@ -6,14 +6,6 @@ Provides abstractions for reading `.deps` files. When a .NET application is comp By default, the dependency manifest contains information about the application's target framework and runtime dependencies. Set the [PreserveCompilationContext](https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#preservecompilationcontext) project property to `true` to additionally include information about reference assemblies used during compilation. -## Key Features - - - -* -* -* - ## How to Use @@ -42,16 +34,6 @@ class Program } ``` -## Main Types - - - -The main types provided by this library are: - -* `` -* `` -* `` - ## Additional Documentation @@ -60,10 +42,6 @@ The main types provided by this library are: * [Microsoft.Extensions.DependencyModel namespace](https://docs.microsoft.com/dotnet/api/microsoft.extensions.dependencymodel) * [Microsoft.Extensions.DependencyModel.DependencyContext](https://docs.microsoft.com/dotnet/api/microsoft.extensions.dependencymodel.dependencycontext) -## Related Packages - - - ## Feedback & Contributing diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md index a9cd4f5727700b..836433b1a4bba5 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Hosting/src/PACKAGE.md @@ -1,12 +1,21 @@ ## About + + + Contains the .NET Generic Host `HostBuilder` which layers on the `Microsoft.Extensions.Hosting.Abstractions` package. ## Key Features + + + * Contains the .NET Generic Host `HostBuilder`. ## How to Use + + + For a console app project: -```cs +```C# using (IHost host = new HostBuilder().Build()) { var lifetime = host.Services.GetRequiredService(); @@ -34,7 +43,11 @@ For a console app project: ``` ## Main Types + + + The main types provided by this library are: + * `Microsoft.Extensions.Host`. * `Microsoft.Extensions.Hosting.HostApplicationBuilder` * `Microsoft.Extensions.Hosting.HostBuilder` @@ -42,6 +55,9 @@ The main types provided by this library are: * `Microsoft.Extensions.Hosting.IHostedLifecycleService` ## Additional Documentation + + + * [Generic host](https://learn.microsoft.com/dotnet/core/extensions/generic-host) * API documentation - [Host](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.host) @@ -49,6 +65,9 @@ The main types provided by this library are: - [HostBuilder](https://learn.microsoft.com/dotnet/api/microsoft.extensions.hosting.hostbuilder) ## Related Packages + + + - `Microsoft.Extensions.Configuration` - `Microsoft.Extensions.DependencyInjection` - `Microsoft.Extensions.Hosting.Abstractions` diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.Console/src/PACKAGE.md index b35f529af9c06c..69823b6d4d3faa 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/PACKAGE.md @@ -10,7 +10,6 @@ * Allow logging to the console using the [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging/) package. * Provide extension methods for the [ILoggingBuilder](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.iloggingbuilder) and [ILoggerProviderConfiguration](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.configuration.iloggerproviderconfiguration-1) classes. - ## How to Use diff --git a/src/libraries/System.Collections.Immutable/src/PACKAGE.md b/src/libraries/System.Collections.Immutable/src/PACKAGE.md index 1b39d42bb175f0..563660c9be59ea 100644 --- a/src/libraries/System.Collections.Immutable/src/PACKAGE.md +++ b/src/libraries/System.Collections.Immutable/src/PACKAGE.md @@ -18,15 +18,49 @@ The `System.Collections.Immutable` library is built-in as part of the shared fra +```C# +using System.Collections.Immutable; + +// Create immutable set of strings +ImmutableHashSet colors = ImmutableHashSet.Create("Red", "Green", "Blue"); + +// Create a new set by adding and removing items from the original set +ImmutableHashSet colorsModified = colors.Remove("Red").Add("Orange"); + +foreach (string s in colorsModified) +{ + Console.WriteLine(s); +} + +/* Example output: + Blue + Green + Orange + */ + ``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `System.Collections.Immutable.ImmutableArray` +* `System.Collections.Immutable.ImmutableArray` +* `System.Collections.Immutable.ImmutableDictionary` +* `System.Collections.Immutable.ImmutableDictionary` +* `System.Collections.Immutable.ImmutableHashSet` +* `System.Collections.Immutable.ImmutableHashSet` +* `System.Collections.Immutable.ImmutableList` +* `System.Collections.Immutable.ImmutableList` +* `System.Collections.Immutable.ImmutableQueue` +* `System.Collections.Immutable.ImmutableQueue` +* `System.Collections.Immutable.ImmutableSortedDictionary` +* `System.Collections.Immutable.ImmutableSortedDictionary` +* `System.Collections.Immutable.ImmutableSortedSet` +* `System.Collections.Immutable.ImmutableSortedSet` +* `System.Collections.Immutable.ImmutableStack` +* `System.Collections.Immutable.ImmutableStack` ## Additional Documentation @@ -35,10 +69,6 @@ The main types provided by this library are: - [Collections and Data Structures](https://docs.microsoft.com/dotnet/standard/collections/) - [API documentation](https://docs.microsoft.com/dotnet/api/system.collections.immutable) -## Related Packages - - - ## Feedback & Contributing diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/PACKAGE.md b/src/libraries/System.Configuration.ConfigurationManager/src/PACKAGE.md index fdaea06fddb7e3..3a315884484cae 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/PACKAGE.md +++ b/src/libraries/System.Configuration.ConfigurationManager/src/PACKAGE.md @@ -4,14 +4,6 @@ Provides types that support using XML configuration files (`app.config`). This package exists only to support migrating existing .NET Framework code that already uses System.Configuration. When writing new code, use another configuration system instead, such as [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). -## Key Features - - - -* -* -* - ## How to Use @@ -75,9 +67,8 @@ To run this example, include an `app.config` file with the following content in The main types provided by this library are: -* `` -* `` -* `` +* `System.Configuration.Configuration` +* `System.Configuration.ConfigurationManager` ## Additional Documentation diff --git a/src/libraries/System.Reflection.Metadata/src/PACKAGE.md b/src/libraries/System.Reflection.Metadata/src/PACKAGE.md index 42ee1764292807..df290dd1ab0f50 100644 --- a/src/libraries/System.Reflection.Metadata/src/PACKAGE.md +++ b/src/libraries/System.Reflection.Metadata/src/PACKAGE.md @@ -6,14 +6,6 @@ This package provides a low-level .NET (ECMA-335) metadata reader and writer. It The `System.Reflection.Metadata` library is included in the .NET Runtime shared framework. The package can be installed when you need to use it in other target frameworks. -## Key Features - - - -* -* -* - ## How to Use diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/PACKAGE.md b/src/libraries/System.Reflection.MetadataLoadContext/src/PACKAGE.md index 1f0e974b2bab60..f16805d7d3f14a 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/PACKAGE.md +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/PACKAGE.md @@ -4,14 +4,6 @@ Provides read-only reflection on assemblies in an isolated context with support for assemblies that target different processor architectures and runtimes. Using MetadataLoadContext enables you to inspect assemblies without loading them into the main execution context. Assemblies in MetadataLoadContext are treated only as metadata, that is, you can read information about their members, but cannot execute any code contained in them. -## Key Features - - - -* -* -* - ## How to Use @@ -51,9 +43,8 @@ class Program The main types provided by this library are: -* `` -* `` -* `` +* `System.Reflection.MetadataLoadContext` +* `System.Reflection.MetadataAssemblyResolver` ## Additional Documentation @@ -63,10 +54,6 @@ The main types provided by this library are: * [System.Reflection.MetadataLoadContext](https://docs.microsoft.com/dotnet/api/system.reflection.metadataloadcontext) * [System.Reflection.MetadataAssemblyResolver](https://docs.microsoft.com/dotnet/api/system.reflection.metadataassemblyresolver) -## Related Packages - - - ## Feedback & Contributing diff --git a/src/libraries/System.Runtime.Caching/src/PACKAGE.md b/src/libraries/System.Runtime.Caching/src/PACKAGE.md index 60abdb27032f1d..5b79f3f7cfb01c 100644 --- a/src/libraries/System.Runtime.Caching/src/PACKAGE.md +++ b/src/libraries/System.Runtime.Caching/src/PACKAGE.md @@ -12,13 +12,9 @@ Packaged set of simple caching API's derived from those of the same namespace av -* -* -* - -## How to Use - - +* Use caching facilities like in ASP.NET, but without a dependency on the System.Web assembly. +* Extensible caching mechanism +* Possible to create custom caching providers ## Main Types From ed430fc763f79735a859d292bd9af64b0650257b Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 18 Sep 2023 15:57:55 +0200 Subject: [PATCH 257/783] More clean-up --- .../Microsoft.Bcl.Numerics/src/PACKAGE.md | 3 +- .../src/PACKAGE.md | 26 +++++++++++ .../src/PACKAGE.md | 45 +++++++++++++++++++ .../src/PACKAGE.md | 1 + .../src/PACKAGE.md | 8 ---- .../System.Reflection.Metadata/src/PACKAGE.md | 12 +++-- 6 files changed, 79 insertions(+), 16 deletions(-) diff --git a/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md index 620514e8bb0b82..5ce176a315dedb 100644 --- a/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md +++ b/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md @@ -8,9 +8,10 @@ As of .NET Core 2.0 and .NET Standard 2.1, the C# language has support for math * Enables the use of MathF on older .NET platforms - ## How to Use + + ```C# using System; diff --git a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md index 8b1734c0421fb3..3714573d5d449b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.CommandLine/src/PACKAGE.md @@ -4,6 +4,32 @@ Command line configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to read configuration parameters from the command line arguments of your application. You can use [CommandLineConfigurationExtensions.AddCommandLine](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.commandlineconfigurationextensions.addcommandline) extension method on `IConfigurationBuilder` to add the command line configuration provider to the configuration builder. +## How to Use + + + +The following example shows how to read application configuration from the command line. You can use a command like `dotnet run --InputPath "c:\fizz" --OutputPath "c:\buzz"` to run it. + +```C# +using System; +using Microsoft.Extensions.Configuration; + +class Program +{ + static void Main(string[] args) + { + // Build a configuration object from command line + IConfiguration config = new ConfigurationBuilder() + .AddCommandLine(args) + .Build(); + + // Read configuration values + Console.WriteLine($"InputPath: {config["InputPath"]}"); + Console.WriteLine($"OutputPath: {config["OutputPath"]}"); + } +} +``` + ## Additional Documentation diff --git a/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md index 0fc660489a4fc6..a987b88924d64d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration.Ini/src/PACKAGE.md @@ -4,6 +4,51 @@ INI configuration provider implementation for [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/). This package enables you to read configuration parameters from [INI files](https://en.wikipedia.org/wiki/INI_file). You can use [IniConfigurationExtensions.AddIniFile](https://learn.microsoft.com/dotnet/api/microsoft.extensions.configuration.iniconfigurationextensions.addinifile) extension method on `IConfigurationBuilder` to add INI configuration provider to the configuration builder. +## How to Use + + + +```C# +using System; +using Microsoft.Extensions.Configuration; + +class Program +{ + static void Main() + { + // Build a configuration object from INI file + IConfiguration config = new ConfigurationBuilder() + .AddIniFile("appsettings.ini") + .Build(); + + // Get a configuration section + IConfigurationSection section = config.GetSection("Settings"); + + // Read configuration values + Console.WriteLine($"Server: {section["Server"]}"); + Console.WriteLine($"Database: {section["Database"]}"); + } +} +``` + +To run this example, include an `appsettings.ini` file with the following content in your project: + +``` +[Settings] +Server=example.com +Database=Northwind +``` + +You can include a configuration file using a code like this in your `.csproj` file: + +```xml + + + Always + + +``` + ## Additional Documentation diff --git a/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md index b9f3878b7e9b78..b507e18c328a5e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md @@ -15,6 +15,7 @@ ## How to Use + ```C# using Microsoft.Extensions.Configuration; diff --git a/src/libraries/System.Collections.Immutable/src/PACKAGE.md b/src/libraries/System.Collections.Immutable/src/PACKAGE.md index 563660c9be59ea..202fb6d0137833 100644 --- a/src/libraries/System.Collections.Immutable/src/PACKAGE.md +++ b/src/libraries/System.Collections.Immutable/src/PACKAGE.md @@ -6,14 +6,6 @@ This package provides collections that are thread safe and guaranteed to never c The `System.Collections.Immutable` library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks. -## Key Features - - - -* -* -* - ## How to Use diff --git a/src/libraries/System.Reflection.Metadata/src/PACKAGE.md b/src/libraries/System.Reflection.Metadata/src/PACKAGE.md index df290dd1ab0f50..921506138ee1b4 100644 --- a/src/libraries/System.Reflection.Metadata/src/PACKAGE.md +++ b/src/libraries/System.Reflection.Metadata/src/PACKAGE.md @@ -83,9 +83,11 @@ class Program The main types provided by this library are: -* `` -* `` -* `` +* `System.Reflection.Metadata.MetadataReader` +* `System.Reflection.PortableExecutable.PEReader` +* `System.Reflection.Metadata.Ecma335.MetadataBuilder` +* `System.Reflection.PortableExecutable.PEBuilder` +* `System.Reflection.PortableExecutable.ManagedPEBuilder` ## Additional Documentation @@ -97,10 +99,6 @@ The main types provided by this library are: * [System.Reflection.PortableExecutable.PEBuilder](https://docs.microsoft.com/dotnet/api/system.reflection.portableexecutable.pebuilder) * [System.Reflection.PortableExecutable.ManagedPEBuilder](https://docs.microsoft.com/dotnet/api/system.reflection.portableexecutable.managedpebuilder) -## Related Packages - - - ## Feedback & Contributing From 934eeea33d3accc9f6811bf63315b456889242c7 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 18 Sep 2023 16:00:28 +0200 Subject: [PATCH 258/783] ConfigurationManager clean-up --- .../System.Configuration.ConfigurationManager/src/PACKAGE.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/PACKAGE.md b/src/libraries/System.Configuration.ConfigurationManager/src/PACKAGE.md index 3a315884484cae..992b7669426993 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/PACKAGE.md +++ b/src/libraries/System.Configuration.ConfigurationManager/src/PACKAGE.md @@ -79,10 +79,6 @@ The main types provided by this library are: * [System.Configuration.Configuration](https://docs.microsoft.com/dotnet/api/system.configuration.configuration) * [System.Configuration.ConfigurationManager](https://docs.microsoft.com/dotnet/api/system.configuration.configurationmanager) -## Related Packages - - - ## Feedback & Contributing From f4d90741507cdef6304834ceffee0ab023c1b729 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 18 Sep 2023 16:33:59 +0200 Subject: [PATCH 259/783] Last clean-up --- .../Microsoft.Extensions.Configuration/src/PACKAGE.md | 1 - .../Microsoft.Extensions.Logging.Debug/src/PACKAGE.md | 1 - src/libraries/Microsoft.Extensions.Logging/src/PACKAGE.md | 1 + src/libraries/System.Data.Odbc/src/PACKAGE.md | 3 +++ src/libraries/System.Data.OleDb/src/PACKAGE.md | 3 +++ .../System.DirectoryServices.AccountManagement/src/PACKAGE.md | 1 - src/libraries/System.DirectoryServices/src/PACKAGE.md | 1 - src/libraries/System.IO.Ports/src/PACKAGE.md | 1 + src/libraries/System.Management/src/PACKAGE.md | 1 + src/libraries/System.Speech/src/PACKAGE.md | 1 + src/libraries/System.Text.Encoding.CodePages/src/PACKAGE.md | 2 +- 11 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md index b507e18c328a5e..1d193afbda8667 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Configuration/src/PACKAGE.md @@ -75,7 +75,6 @@ The main types provided by this library are: * [Microsoft.Extensions.Configuration.UserSecrets](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.UserSecrets) * [Microsoft.Extensions.Configuration.Xml](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Xml) - ## Feedback & Contributing diff --git a/src/libraries/Microsoft.Extensions.Logging.Debug/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.Debug/src/PACKAGE.md index 8a5c652290643e..97b378f4350c57 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Debug/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Logging.Debug/src/PACKAGE.md @@ -3,7 +3,6 @@ `Microsoft.Extensions.Logging.Debug` provides a Debug output logger provider implementation for Microsoft.Extensions.Logging. This logger logs messages to a debugger monitor by writing messages with `System.Diagnostics.Debug.WriteLine()`. - ## Key Features diff --git a/src/libraries/Microsoft.Extensions.Logging/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging/src/PACKAGE.md index 607283d3eb7486..87c2d2b79ee29d 100644 --- a/src/libraries/Microsoft.Extensions.Logging/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Logging/src/PACKAGE.md @@ -1,6 +1,7 @@ ## About + `Microsoft.Extensions.Logging` is combined with a core logging abstraction under `Microsoft.Extensions.Logging.Abstractions`. This abstraction is available in our basic built-in implementations like console, event log, and debug (Debug.WriteLine) logging. ## Key Features diff --git a/src/libraries/System.Data.Odbc/src/PACKAGE.md b/src/libraries/System.Data.Odbc/src/PACKAGE.md index 7195ca77a50064..a45dd52364c18e 100644 --- a/src/libraries/System.Data.Odbc/src/PACKAGE.md +++ b/src/libraries/System.Data.Odbc/src/PACKAGE.md @@ -11,6 +11,9 @@ Allows access to ODBC data sources. This is a basic example of retrieving the results of a query using an [OdbcDataReader](https://learn.microsoft.com/dotnet/api/system.data.odbc.odbcdatareader). For examples of using an [OdbcDataAdapter](https://learn.microsoft.com/dotnet/api/system.data.odbc.odbcdataadapter), and of updating an ODBC data source, please see the documentation. ```cs +using System.Data.Odbc; + +string connectionString = ""; string queryString = "SELECT DISTINCT CustomerID FROM Orders"; using OdbcConnection connection = new OdbcConnection(connectionString); diff --git a/src/libraries/System.Data.OleDb/src/PACKAGE.md b/src/libraries/System.Data.OleDb/src/PACKAGE.md index be973625ebef7d..6e81daa638b2eb 100644 --- a/src/libraries/System.Data.OleDb/src/PACKAGE.md +++ b/src/libraries/System.Data.OleDb/src/PACKAGE.md @@ -11,6 +11,9 @@ Allows access to legacy OLE DB data sources. This is a basic example of retrieving the results of a query using an [OleDbDataReader](https://learn.microsoft.com/dotnet/api/system.data.oledb.oledbdatareader). For examples of using an [OleDbDataAdapter](https://learn.microsoft.com/dotnet/api/system.data.oledb.oledbdataadapter), and of updating an OLE DB data source, please see the documentation. ```cs +using System.Data.OleDb; + +string connectionString = ""; string queryString = "SELECT OrderID, CustomerID FROM Orders"; using OleDbConnection connection = new OleDbConnection(connectionString); diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md index 7d761e089fbb8c..bee50af73d3c45 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/PACKAGE.md @@ -67,7 +67,6 @@ The main types provided by this library are: [System.DirectoryServices](https://learn.microsoft.com/dotnet/api/system.directoryservices) - ## Feedback & Contributing diff --git a/src/libraries/System.DirectoryServices/src/PACKAGE.md b/src/libraries/System.DirectoryServices/src/PACKAGE.md index 4c879dd574aa3e..981c865baf9210 100644 --- a/src/libraries/System.DirectoryServices/src/PACKAGE.md +++ b/src/libraries/System.DirectoryServices/src/PACKAGE.md @@ -69,7 +69,6 @@ The main types provided by this library are: * [Active Directory Service Interfaces](https://learn.microsoft.com/windows/win32/adsi/active-directory-service-interfaces-adsi) * [Lightweight Directory Access Protocol (LDAP)](https://learn.microsoft.com/previous-versions/windows/desktop/ldap/lightweight-directory-access-protocol-ldap-api) - ## Related Packages * [System.DirectoryServices.AccountManagement](https://learn.microsoft.com/dotnet/api/system.directoryservices.accountmanagement) diff --git a/src/libraries/System.IO.Ports/src/PACKAGE.md b/src/libraries/System.IO.Ports/src/PACKAGE.md index 90da18ddefd2f0..218bf288eb0454 100644 --- a/src/libraries/System.IO.Ports/src/PACKAGE.md +++ b/src/libraries/System.IO.Ports/src/PACKAGE.md @@ -1,6 +1,7 @@ ## About + [System.IO.Ports](https://www.nuget.org/packages/System.IO.Ports) package provides synchronous serial port file resource. Additionally, the functionality of this class can be wrapped in an internal `Stream` object, accessible through the `BaseStream` property, and passed to classes that wrap or use streams. ## Key Features diff --git a/src/libraries/System.Management/src/PACKAGE.md b/src/libraries/System.Management/src/PACKAGE.md index 280347191d1013..7138378ac87480 100644 --- a/src/libraries/System.Management/src/PACKAGE.md +++ b/src/libraries/System.Management/src/PACKAGE.md @@ -1,6 +1,7 @@ ## About + Provides access to a rich set of management information and management events about the system, devices, and applications instrumented to the Windows Management Instrumentation (WMI) infrastructure. Not supported on other platforms. ## Key Features diff --git a/src/libraries/System.Speech/src/PACKAGE.md b/src/libraries/System.Speech/src/PACKAGE.md index e7d46cc047307e..ac57df4ca354d8 100644 --- a/src/libraries/System.Speech/src/PACKAGE.md +++ b/src/libraries/System.Speech/src/PACKAGE.md @@ -1,6 +1,7 @@ ## About + Provides APIs for speech recognition and synthesis built on the [Microsoft Speech API](https://learn.microsoft.com/previous-versions/windows/desktop/ms723627(v=vs.85)) in Windows. Not supported on other platforms. This package is provided primarily for compatibility with code being ported from .NET Framework and is not accepting new features. diff --git a/src/libraries/System.Text.Encoding.CodePages/src/PACKAGE.md b/src/libraries/System.Text.Encoding.CodePages/src/PACKAGE.md index 87e4c8054b2fd6..7da4fd98cd740b 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/PACKAGE.md +++ b/src/libraries/System.Text.Encoding.CodePages/src/PACKAGE.md @@ -8,7 +8,7 @@ ## How to Use -```csharp +```C# using System.Text; // Register the CodePages encoding provider at application startup to enable using single and double byte encodings. From bcdff134478ad8df8014018cc4a2e67cc34fc452 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 10:09:53 -0700 Subject: [PATCH 260/783] [release/8.0] Remove public provider from rundown session (#92048) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add rundown check * Update ep-session.c * Check for rundown provider * Fix * Update src/mono/mono/eventpipe/ep-rt-types-mono.h Co-authored-by: Aleksey Kliger (λgeek) * Fix cross plat build * Revert previous changes * Remove public provider from rundown session * Finish reverting * Update ep-session.c --------- Co-authored-by: David Mason Co-authored-by: Aleksey Kliger (λgeek) --- src/native/eventpipe/ep-session.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/native/eventpipe/ep-session.c b/src/native/eventpipe/ep-session.c index 959214d1375963..ee134be65059d7 100644 --- a/src/native/eventpipe/ep-session.c +++ b/src/native/eventpipe/ep-session.c @@ -329,24 +329,16 @@ ep_session_enable_rundown (EventPipeSession *session) const uint64_t keywords = 0x80020139; const EventPipeEventLevel verbose_logging_level = EP_EVENT_LEVEL_VERBOSE; - EventPipeProviderConfiguration rundown_providers [2]; - uint32_t rundown_providers_len = (uint32_t)ARRAY_SIZE (rundown_providers); + EventPipeProviderConfiguration rundown_provider; + ep_provider_config_init (&rundown_provider, ep_config_get_rundown_provider_name_utf8 (), keywords, verbose_logging_level, NULL); // Rundown provider. - ep_provider_config_init (&rundown_providers [0], ep_config_get_public_provider_name_utf8 (), keywords, verbose_logging_level, NULL); // Public provider. - ep_provider_config_init (&rundown_providers [1], ep_config_get_rundown_provider_name_utf8 (), keywords, verbose_logging_level, NULL); // Rundown provider. + EventPipeSessionProvider *session_provider = ep_session_provider_alloc ( + ep_provider_config_get_provider_name (&rundown_provider), + ep_provider_config_get_keywords (&rundown_provider), + ep_provider_config_get_logging_level (&rundown_provider), + ep_provider_config_get_filter_data (&rundown_provider)); - // Update provider list with rundown configuration. - for (uint32_t i = 0; i < rundown_providers_len; ++i) { - const EventPipeProviderConfiguration *config = &rundown_providers [i]; - - EventPipeSessionProvider *session_provider = ep_session_provider_alloc ( - ep_provider_config_get_provider_name (config), - ep_provider_config_get_keywords (config), - ep_provider_config_get_logging_level (config), - ep_provider_config_get_filter_data (config)); - - ep_raise_error_if_nok (ep_session_add_session_provider (session, session_provider)); - } + ep_raise_error_if_nok (ep_session_add_session_provider (session, session_provider)); ep_session_set_rundown_enabled (session, true); result = true; From 607bbcae163feefe855004bd404cf5564b755cd8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 10:11:57 -0700 Subject: [PATCH 261/783] [release/8.0] Avoid marking property/event attributes multiple times (#92153) * Avoid marking property attributes multiple times * Fix test for nativeaot * Add issue link * Simplify test, fix bug for events, add more coverage * Fix event tests * Fix test for nativeaot NativeAot requires a call to GetCustomAttribute for the attributes to be kept. --------- Co-authored-by: Sven Boemer --- .../src/linker/Linker.Steps/MarkStep.cs | 7 +- .../illink/src/linker/Linker/Annotations.cs | 1 - .../DataFlow/AttributePropertyDataflow.cs | 118 +++++++++++++++++- .../TypeHierarchyReflectionWarnings.cs | 5 - .../RequiresCapability/BasicRequires.cs | 2 - .../RequiresCapability/RequiresOnAttribute.cs | 5 - .../RequiresCapability/RequiresOnClass.cs | 6 - 7 files changed, 118 insertions(+), 26 deletions(-) diff --git a/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs b/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs index 52fe64b3632559..d5923d135aa5b8 100644 --- a/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs +++ b/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs @@ -3548,7 +3548,8 @@ protected virtual bool ShouldParseMethodBody (MethodDefinition method) protected internal void MarkProperty (PropertyDefinition prop, in DependencyInfo reason) { - Tracer.AddDirectDependency (prop, reason, marked: false); + if (!Annotations.MarkProcessed (prop, reason)) + return; using var propertyScope = ScopeStack.PushScope (new MessageOrigin (prop)); @@ -3559,8 +3560,8 @@ protected internal void MarkProperty (PropertyDefinition prop, in DependencyInfo protected internal virtual void MarkEvent (EventDefinition evt, in DependencyInfo reason) { - // Record the event without marking it in Annotations. - Tracer.AddDirectDependency (evt, reason, marked: false); + if (!Annotations.MarkProcessed (evt, reason)) + return; using var eventScope = ScopeStack.PushScope (new MessageOrigin (evt)); diff --git a/src/tools/illink/src/linker/Linker/Annotations.cs b/src/tools/illink/src/linker/Linker/Annotations.cs index 6576436b963cec..456af9fdf6ab1e 100644 --- a/src/tools/illink/src/linker/Linker/Annotations.cs +++ b/src/tools/illink/src/linker/Linker/Annotations.cs @@ -272,7 +272,6 @@ public bool IsProcessed (IMetadataTokenProvider provider) public bool MarkProcessed (IMetadataTokenProvider provider, in DependencyInfo reason) { - Debug.Assert (!(reason.Kind == DependencyKind.AlreadyMarked)); Tracer.AddDirectDependency (provider, reason, marked: true); // The item may or may not be pending. marked_pending.Remove (provider); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs index 91fdad3652d8fd..2167c1886fa235 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs @@ -17,15 +17,19 @@ class AttributePropertyDataflow [KeptAttributeAttribute (typeof (KeepsPublicFieldsAttribute))] [KeptAttributeAttribute (typeof (TypeArrayAttribute))] [KeepsPublicConstructors (Type = typeof (ClassWithKeptPublicConstructor))] - [KeepsPublicMethods (Type = "Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+ClassWithKeptPublicMethods")] + [KeepsPublicMethods (TypeName = "Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+ClassWithKeptPublicMethods")] [KeepsPublicFields (Type = null, TypeName = null)] [TypeArray (Types = new Type[] { typeof (AttributePropertyDataflow) })] // Trimmer only for now - https://github.com/dotnet/linker/issues/2273 [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] public static void Main () { - typeof (AttributePropertyDataflow).GetMethod ("Main").GetCustomAttribute (typeof (KeepsPublicConstructorsAttribute)); - typeof (AttributePropertyDataflow).GetMethod ("Main").GetCustomAttribute (typeof (KeepsPublicMethodsAttribute)); + typeof (AttributePropertyDataflow).GetMethod (nameof (Main)).GetCustomAttribute (typeof (KeepsPublicConstructorsAttribute)); + typeof (AttributePropertyDataflow).GetMethod (nameof (Main)).GetCustomAttribute (typeof (KeepsPublicMethodsAttribute)); + RecursivePropertyDataFlow.Test (); + RecursiveEventDataFlow.Test (); + RecursiveFieldDataFlow.Test (); + RecursiveMethodDataFlow.Test (); } [Kept] @@ -57,7 +61,13 @@ public KeepsPublicMethodsAttribute () [Kept] [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - public string Type { get; [Kept] set; } + public Type Type { get; [Kept] set; } + + [field: Kept] + [Kept] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + public string TypeName { get; [Kept] set; } } // Used to test null values @@ -83,6 +93,38 @@ public KeepsPublicFieldsAttribute () public string TypeName { get; [Kept] set; } } + [Kept] + [KeptBaseType (typeof (Attribute))] + class KeepsPublicPropertiesAttribute : Attribute + { + [Kept] + public KeepsPublicPropertiesAttribute () + { + } + + [field: Kept] + [Kept] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] + public Type Type { get; [Kept] set; } + } + + [Kept] + [KeptBaseType (typeof (Attribute))] + class KeepsPublicEventsAttribute : Attribute + { + [Kept] + public KeepsPublicEventsAttribute () + { + } + + [field: Kept] + [Kept] + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] + public Type Type { get; [Kept] set; } + } + [Kept] class ClassWithKeptPublicConstructor { @@ -117,5 +159,73 @@ public TypeArrayAttribute () [Kept] public Type[] Types { get; [Kept] set; } } + + [Kept] + class RecursivePropertyDataFlow + { + [field: Kept] + [Kept] + [KeptAttributeAttribute (typeof (KeepsPublicPropertiesAttribute))] + [KeepsPublicProperties (Type = typeof (RecursivePropertyDataFlow))] + public static int Property { [Kept] get; [Kept] set; } + + [Kept] + public static void Test () + { + typeof (RecursivePropertyDataFlow).GetProperty (nameof (Property)).GetCustomAttribute (typeof (KeepsPublicPropertiesAttribute)); + Property = 0; + } + } + + [Kept] + class RecursiveEventDataFlow + { + [field: Kept] + [Kept] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + [KeptAttributeAttribute (typeof (KeepsPublicEventsAttribute))] + [KeepsPublicEvents (Type = typeof (RecursiveEventDataFlow))] + public static event EventHandler Event; + + [Kept] + public static void Test () + { + typeof (RecursiveEventDataFlow).GetEvent (nameof (Event)).GetCustomAttribute (typeof (KeepsPublicEventsAttribute)); + Event += (sender, e) => { }; + } + } + + [Kept] + class RecursiveFieldDataFlow + { + [Kept] + [KeptAttributeAttribute (typeof (KeepsPublicFieldsAttribute))] + [KeepsPublicFields (Type = typeof (RecursiveFieldDataFlow))] + public static int field; + + [Kept] + public static void Test () + { + typeof (RecursiveMethodDataFlow).GetField (nameof (field)).GetCustomAttribute (typeof (KeepsPublicFieldsAttribute)); + field = 0; + } + } + + [Kept] + class RecursiveMethodDataFlow + { + [Kept] + [KeptAttributeAttribute (typeof (KeepsPublicMethodsAttribute))] + [KeepsPublicMethods (Type = typeof (RecursiveMethodDataFlow))] + public static void Method () { } + + [Kept] + public static void Test () + { + typeof (RecursiveMethodDataFlow).GetMethod (nameof (Method)).GetCustomAttribute (typeof (KeepsPublicMethodsAttribute)); + Method (); + } + } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs index a0d84562dd8917..d7225a40eacdb1 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs @@ -246,11 +246,6 @@ class AnnotatedPublicEvents public delegate void MyEventHandler (object sender, int i); [Kept] - // ILLink always keeps event methods when an event is kept, so this generates warnings - // on the event itself (since an event access is considered to reference the annotated add method), - // and on the add method (if it is accessed through reflection). - [ExpectedWarning ("IL2026", "--RUC on add_RUCEvent--", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2026", "--RUC on add_RUCEvent--", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2026", "--RUC on add_RUCEvent--", ProducedBy = Tool.Trimmer)] public event MyEventHandler RUCEvent { [Kept] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/BasicRequires.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/BasicRequires.cs index ba11e7fa07fdef..0d6b360ac71478 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/BasicRequires.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/BasicRequires.cs @@ -137,7 +137,6 @@ static void TestRequiresFromNameOf () class OnEventMethod { - [ExpectedWarning ("IL2026", "--EventToTestRemove.remove--", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2026", "--EventToTestRemove.remove--", ProducedBy = Tool.Trimmer)] static event EventHandler EventToTestRemove { add { } @@ -147,7 +146,6 @@ static event EventHandler EventToTestRemove { remove { } } - [ExpectedWarning ("IL2026", "--EventToTestAdd.add--", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2026", "--EventToTestAdd.add--", ProducedBy = Tool.Trimmer)] static event EventHandler EventToTestAdd { [RequiresUnreferencedCode ("Message for --EventToTestAdd.add--")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttribute.cs index d44fb0f4466fae..8710ed0e45cf82 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttribute.cs @@ -112,14 +112,9 @@ static void MethodWithAttributeWhichRequires () { } static int _fieldWithAttributeWhichRequires; [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] - // https://github.com/dotnet/runtime/issues/83581 - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Trimmer)] // Trimmer can produce duplicate warnings for property access - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Trimmer)] // Trimmer can produce duplicate warnings for property access [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")] - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Trimmer)] // Trimmer can produce duplicate warnings for property access - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Trimmer)] // Trimmer can produce duplicate warnings for property access [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] [AttributeWhichRequires] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs index c95e7abe6fa65b..abc594d1777390 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs @@ -494,8 +494,6 @@ class MemberTypesWithRequires // These should not be reported https://github.com/mono/linker/issues/2218 [ExpectedWarning ("IL2026", "MemberTypesWithRequires.Event.add", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2026", "MemberTypesWithRequires.Event.add", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2026", "MemberTypesWithRequires.Event.remove", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2026", "MemberTypesWithRequires.Event.remove", ProducedBy = Tool.Trimmer)] public static event EventHandler Event; } @@ -851,10 +849,6 @@ class WithRequires // These should be reported only in TestDirectReflectionAccess // https://github.com/mono/linker/issues/2218 [ExpectedWarning ("IL2026", "StaticEvent.add", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2026", "StaticEvent.add", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2026", "StaticEvent.add", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2026", "StaticEvent.remove", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2026", "StaticEvent.remove", ProducedBy = Tool.Trimmer)] [ExpectedWarning ("IL2026", "StaticEvent.remove", ProducedBy = Tool.Trimmer)] public static event EventHandler StaticEvent; } From 8ca963c0f88f328c420c0eb600f0d0169899d704 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 10:13:31 -0700 Subject: [PATCH 262/783] [workloads] Opt into using package groups (#92168) This is to make sure the MSI's we generate for VS are recognized as the same. Enabling sxs workloads by itself caused the package id's that wrap the manifest MSI's to be different. This prevents that from happening. Co-authored-by: Steve Pfister --- src/workloads/workloads.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/workloads/workloads.csproj b/src/workloads/workloads.csproj index ae0a4f6af7f246..82c5c31badd71b 100644 --- a/src/workloads/workloads.csproj +++ b/src/workloads/workloads.csproj @@ -165,7 +165,7 @@ - Date: Mon, 18 Sep 2023 10:20:30 -0700 Subject: [PATCH 263/783] [release/8.0] Update dependencies from dnceng/internal/dotnet-optimization (#92177) * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230915.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23464.6 -> To Version 1.0.0-prerelease.23465.3 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230915.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23464.6 -> To Version 1.0.0-prerelease.23465.3 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230915.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23464.6 -> To Version 1.0.0-prerelease.23465.3 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index da204b55f24849..161eab1c82c64c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -334,21 +334,21 @@ https://github.com/dotnet/arcade 1d451c32dda2314c721adbf8829e1c0cd4e681ff - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 5b0a8abbba75c63e20e42f778650dd1448aef62c + f67c4e806a744f7274aed9493e4c8d39a3c73445 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 5b0a8abbba75c63e20e42f778650dd1448aef62c + f67c4e806a744f7274aed9493e4c8d39a3c73445 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 5b0a8abbba75c63e20e42f778650dd1448aef62c + f67c4e806a744f7274aed9493e4c8d39a3c73445 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 5b0a8abbba75c63e20e42f778650dd1448aef62c + f67c4e806a744f7274aed9493e4c8d39a3c73445 https://github.com/dotnet/hotreload-utils @@ -384,13 +384,13 @@ d10b02ae5cc670609d920a672985ed4456bdd6b6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 5b0a8abbba75c63e20e42f778650dd1448aef62c + f67c4e806a744f7274aed9493e4c8d39a3c73445 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 5b0a8abbba75c63e20e42f778650dd1448aef62c + f67c4e806a744f7274aed9493e4c8d39a3c73445 diff --git a/eng/Versions.props b/eng/Versions.props index 9223996861d8fd..f71e6cc183dd73 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -156,12 +156,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23464.6 - 1.0.0-prerelease.23464.6 - 1.0.0-prerelease.23464.6 - 1.0.0-prerelease.23464.6 - 1.0.0-prerelease.23464.6 - 1.0.0-prerelease.23464.6 + 1.0.0-prerelease.23465.3 + 1.0.0-prerelease.23465.3 + 1.0.0-prerelease.23465.3 + 1.0.0-prerelease.23465.3 + 1.0.0-prerelease.23465.3 + 1.0.0-prerelease.23465.3 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From ae998ebf0071b0f441c7faca24165fe33530af8a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 10:21:39 -0700 Subject: [PATCH 264/783] [mono][aot] Avoid compiling the same method multiple times during dedup. (#92178) Co-authored-by: Zoltan Varga --- src/mono/mono/mini/aot-compiler.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 023cd6ce42b0b5..e067d2714d8a37 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -4326,6 +4326,7 @@ get_method_index (MonoAotCompile *acfg, MonoMethod *method) return index - 1; } +/* Return TRUE if the method can be skipped */ static gboolean collect_dedup_method (MonoAotCompile *acfg, MonoMethod *method) { @@ -4334,14 +4335,16 @@ collect_dedup_method (MonoAotCompile *acfg, MonoMethod *method) if (acfg->dedup_phase == DEDUP_SKIP) return TRUE; // Remember for later - if (acfg->dedup_phase == DEDUP_COLLECT && !g_hash_table_lookup (dedup_methods, method)) + g_assert (acfg->dedup_phase == DEDUP_COLLECT); + if (!g_hash_table_lookup (dedup_methods, method)) g_hash_table_insert (dedup_methods, method, method); + else + // Already processed when compiling another assembly + return TRUE; } return FALSE; } - - static int add_method_full (MonoAotCompile *acfg, MonoMethod *method, gboolean extra, int depth) { From 6c9a74307070bd63e2d88ae2e5d6aa03d46debf2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 10:22:10 -0700 Subject: [PATCH 265/783] [release/8.0] [browser] Add link to docs to interop error messages (#92182) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * JS part * C# part --------- Co-authored-by: Marek Fišera --- .../JSImportGenerator/Resources/Strings.resx | 26 +++++------ .../tests/JSImportGenerator.UnitTest/Fails.cs | 44 +++++++++---------- src/mono/wasm/runtime/marshal-to-cs.ts | 7 +-- src/mono/wasm/runtime/marshal-to-js.ts | 18 ++++---- 4 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/Resources/Strings.resx b/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/Resources/Strings.resx index b06ebce2260316..1c6e47ef214f15 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/Resources/Strings.resx +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/Resources/Strings.resx @@ -136,7 +136,7 @@ Specified type is not supported by source-generated JavaScript interop. - {0} The generated source will not handle marshalling of the return value of method '{1}'. + {0} The generated source will not handle marshalling of the return value of method '{1}'. For more information see https://aka.ms/dotnet-wasm-jsinterop {0} is a message containing additional details about what is not supported {1} is the name of the method @@ -144,21 +144,21 @@ Type is not supported by source-generated JavaScript interop. - The type '{0}' is not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter '{1}'. + The type '{0}' is not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter '{1}'. For more information see https://aka.ms/dotnet-wasm-jsinterop - The type '{0}' is not supported by source-generated JavaScript interop. The generated source will not handle marshalling of the return value of method '{1}'. + The type '{0}' is not supported by source-generated JavaScript interop. The generated source will not handle marshalling of the return value of method '{1}'. For more information see https://aka.ms/dotnet-wasm-jsinterop - {0} The generated source will not handle marshalling of parameter '{1}'. + {0} The generated source will not handle marshalling of parameter '{1}'. For more information see https://aka.ms/dotnet-wasm-jsinterop {0} is a message containing additional details about what is not supported {1} is the name of the parameter - The specified '{0}' configuration for the return value of method '{1}' is not supported by source-generated JavaScript interop. + The specified '{0}' configuration for the return value of method '{1}' is not supported by source-generated JavaScript interop. For more information see https://aka.ms/dotnet-wasm-jsinterop - The specified '{0}' configuration for parameter '{1}' is not supported by source-generated JavaScript interop. + The specified '{0}' configuration for parameter '{1}' is not supported by source-generated JavaScript interop. For more information see https://aka.ms/dotnet-wasm-jsinterop Invalid 'JSImportAttribute' usage @@ -167,10 +167,10 @@ Invalid 'JSExportAttribute' usage - Method '{0}' should be 'static', 'partial', and non-generic when marked with 'JSImportAttribute'. JavaScript interop source generation will ignore method '{0}'. + Method '{0}' should be 'static', 'partial', and non-generic when marked with 'JSImportAttribute'. JavaScript interop source generation will ignore method '{0}'. For more information see https://aka.ms/dotnet-wasm-jsinterop - Method '{0}' should be 'static', non-partial and non-generic when marked with 'JSExportAttribute'. JavaScript interop source generation will ignore method '{0}'. + Method '{0}' should be 'static', non-partial and non-generic when marked with 'JSExportAttribute'. JavaScript interop source generation will ignore method '{0}'. For more information see https://aka.ms/dotnet-wasm-jsinterop Methods marked with 'JSImportAttribute' should be 'static', 'partial', and non-generic. JavaScript interop source generation will ignore methods that are non-'static', non-'partial', or generic. @@ -179,7 +179,7 @@ Methods marked with 'JSImportAttribute' should be 'static', non-partial, and non-generic. JavaScript interop source generation will ignore methods that are non-'static', 'partial', or generic. - Method '{0}' is contained in a type '{1}' that is not marked 'partial'. JavaScript interop source generation will ignore method '{0}'. + Method '{0}' is contained in a type '{1}' that is not marked 'partial'. JavaScript interop source generation will ignore method '{0}'. For more information see https://aka.ms/dotnet-wasm-jsinterop 'JSType.Discard' could be only used with void return argument. @@ -212,18 +212,18 @@ JSImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. - JSImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. + JSImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. For more information see https://aka.ms/dotnet-wasm-jsinterop - JSImportAttribute requires unsafe code. + JSImportAttribute requires unsafe code. For more information see https://aka.ms/dotnet-wasm-jsinterop JSExportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. - JSExportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. + JSExportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. For more information see https://aka.ms/dotnet-wasm-jsinterop - JSExportAttribute requires unsafe code. + JSExportAttribute requires unsafe code. For more information see https://aka.ms/dotnet-wasm-jsinterop \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JSImportGenerator.UnitTest/Fails.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JSImportGenerator.UnitTest/Fails.cs index 513af4747a4e92..f5ffe77afb7949 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JSImportGenerator.UnitTest/Fails.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JSImportGenerator.UnitTest/Fails.cs @@ -15,39 +15,39 @@ public class Fails public static IEnumerable CodeSnippetsToFail() { yield return new object?[] { CodeSnippets.DefaultReturnMarshaler(), new string[] { - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of the return value of method 'Import1'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of the return value of method 'Export1'.", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of the return value of method 'Import1'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of the return value of method 'Export1'. For more information see https://aka.ms/dotnet-wasm-jsinterop", },null }; yield return new object?[] { CodeSnippets.DefaultReturnMarshaler(), null, null }; yield return new object?[] { CodeSnippets.DefaultReturnMarshaler("System.Func"), null, null }; yield return new object?[] { CodeSnippets.DefaultReturnMarshaler("System.Action"), new string[] { - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Action. The generated source will not handle marshalling of the return value of method 'Import1'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Action. The generated source will not handle marshalling of the return value of method 'Export1'.", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Action. The generated source will not handle marshalling of the return value of method 'Import1'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Action. The generated source will not handle marshalling of the return value of method 'Export1'. For more information see https://aka.ms/dotnet-wasm-jsinterop", },null }; yield return new object?[] { CodeSnippets.DefaultReturnMarshaler("System.Span"), null, null }; yield return new object?[] { CodeSnippets.DefaultReturnMarshaler("System.Span"), null, null }; yield return new object?[] { CodeSnippets.DefaultReturnMarshaler("System.ArraySegment"), null, null }; yield return new object?[] { CodeSnippets.AllMissing, new string[] { - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of object. The generated source will not handle marshalling of parameter 'a1'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of parameter 'a2'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of parameter 'a3'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Action. The generated source will not handle marshalling of parameter 'a4'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Func. The generated source will not handle marshalling of parameter 'a5'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Span. The generated source will not handle marshalling of parameter 'a6'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.ArraySegment. The generated source will not handle marshalling of parameter 'a7'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a8'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of object[]. The generated source will not handle marshalling of parameter 'a9'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.DateTime. The generated source will not handle marshalling of parameter 'a10'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.DateTimeOffset. The generated source will not handle marshalling of parameter 'a11'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a12'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a13'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a14'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a15'.", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of object. The generated source will not handle marshalling of parameter 'a1'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of parameter 'a2'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of parameter 'a3'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Action. The generated source will not handle marshalling of parameter 'a4'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Func. The generated source will not handle marshalling of parameter 'a5'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Span. The generated source will not handle marshalling of parameter 'a6'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.ArraySegment. The generated source will not handle marshalling of parameter 'a7'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a8'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of object[]. The generated source will not handle marshalling of parameter 'a9'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.DateTime. The generated source will not handle marshalling of parameter 'a10'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.DateTimeOffset. The generated source will not handle marshalling of parameter 'a11'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a12'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a13'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a14'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a15'. For more information see https://aka.ms/dotnet-wasm-jsinterop", },null }; yield return new object?[] { CodeSnippets.InOutRef, new string[] { - "Parameters with 'in', 'out' and 'ref' modifiers are not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter 'a1'.", - "Parameters with 'in', 'out' and 'ref' modifiers are not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter 'a2'.", - "Parameters with 'in', 'out' and 'ref' modifiers are not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter 'a3'.", + "Parameters with 'in', 'out' and 'ref' modifiers are not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter 'a1'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Parameters with 'in', 'out' and 'ref' modifiers are not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter 'a2'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Parameters with 'in', 'out' and 'ref' modifiers are not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter 'a3'. For more information see https://aka.ms/dotnet-wasm-jsinterop", }, null }; } diff --git a/src/mono/wasm/runtime/marshal-to-cs.ts b/src/mono/wasm/runtime/marshal-to-cs.ts index a0f5b58a5cd332..14d6c7e3dd7479 100644 --- a/src/mono/wasm/runtime/marshal-to-cs.ts +++ b/src/mono/wasm/runtime/marshal-to-cs.ts @@ -24,6 +24,7 @@ import { TypedArray } from "./types/emscripten"; import { addUnsettledPromise, settleUnsettledPromise } from "./pthreads/shared/eventloop"; import { mono_log_warn } from "./logging"; +export const jsinteropDoc = "For more information see https://aka.ms/dotnet-wasm-jsinterop"; export function initialize_marshalers_to_cs(): void { if (js_to_cs_marshalers.size == 0) { @@ -389,7 +390,7 @@ export function marshal_js_object_to_cs(arg: JSMarshalerArgument, value: any): v } else { // if value was ManagedObject, it would be double proxied, but the C# signature requires that - mono_check(value[js_owned_gc_handle_symbol] === undefined, "JSObject proxy of ManagedObject proxy is not supported"); + mono_check(value[js_owned_gc_handle_symbol] === undefined, () => `JSObject proxy of ManagedObject proxy is not supported. ${jsinteropDoc}`); mono_check(typeof value === "function" || typeof value === "object", () => `JSObject proxy of ${typeof value} is not supported`); set_arg_type(arg, MarshalerType.JSObject); @@ -474,7 +475,7 @@ function _marshal_cs_object_to_cs(arg: JSMarshalerArgument, value: any): void { else { assert_not_disposed(value); if (value instanceof ArraySegment) { - throw new Error("NotImplementedException: ArraySegment"); + throw new Error("NotImplementedException: ArraySegment. " + jsinteropDoc); } else if (value instanceof ManagedError) { set_arg_type(arg, MarshalerType.Exception); @@ -484,7 +485,7 @@ function _marshal_cs_object_to_cs(arg: JSMarshalerArgument, value: any): void { set_arg_type(arg, MarshalerType.Object); set_gc_handle(arg, gc_handle); } else { - throw new Error("NotImplementedException " + js_type); + throw new Error("NotImplementedException " + js_type + ". " + jsinteropDoc); } } } diff --git a/src/mono/wasm/runtime/marshal-to-js.ts b/src/mono/wasm/runtime/marshal-to-js.ts index 9b5a931067fda6..1ad71dbc4ae784 100644 --- a/src/mono/wasm/runtime/marshal-to-js.ts +++ b/src/mono/wasm/runtime/marshal-to-js.ts @@ -18,7 +18,7 @@ import { import { monoStringToString } from "./strings"; import { JSHandleNull, GCHandleNull, JSMarshalerArgument, JSMarshalerArguments, JSMarshalerType, MarshalerToCs, MarshalerToJs, BoundMarshalerToJs, MarshalerType } from "./types/internal"; import { TypedArray } from "./types/emscripten"; -import { get_marshaler_to_cs_by_type } from "./marshal-to-cs"; +import { get_marshaler_to_cs_by_type, jsinteropDoc } from "./marshal-to-cs"; import { localHeapViewF64, localHeapViewI32, localHeapViewU8 } from "./memory"; export function initialize_marshalers_to_js(): void { @@ -85,7 +85,7 @@ export function get_marshaler_to_js_by_type(marshaler_type: MarshalerType): Mars return undefined; } const converter = cs_to_js_marshalers.get(marshaler_type); - mono_assert(converter && typeof converter === "function", () => `ERR41: Unknown converter for type ${marshaler_type}`); + mono_assert(converter && typeof converter === "function", () => `ERR41: Unknown converter for type ${marshaler_type}. ${jsinteropDoc}`); return converter; } @@ -224,7 +224,7 @@ export function marshal_task_to_js(arg: JSMarshalerArgument, _?: MarshalerType, // when we arrived here from _marshal_cs_object_to_js res_converter = cs_to_js_marshalers.get(type); } - mono_assert(res_converter, () => `Unknown sub_converter for type ${MarshalerType[type]} `); + mono_assert(res_converter, () => `Unknown sub_converter for type ${MarshalerType[type]}. ${jsinteropDoc}`); // this is already resolved const val = res_converter(arg); @@ -256,7 +256,7 @@ export function marshal_task_to_js(arg: JSMarshalerArgument, _?: MarshalerType, // when we arrived here from _marshal_cs_object_to_js res_converter = cs_to_js_marshalers.get(type); } - mono_assert(res_converter, () => `Unknown sub_converter for type ${MarshalerType[type]}`); + mono_assert(res_converter, () => `Unknown sub_converter for type ${MarshalerType[type]}. ${jsinteropDoc}`); const js_value = res_converter!(argInner); orig_resolve(js_value); @@ -291,7 +291,7 @@ export function mono_wasm_marshal_promise(args: JSMarshalerArguments): void { else if (value_type !== MarshalerType.Task) { // this is already resolved task const sub_converter = cs_to_js_marshalers.get(value_type); - mono_assert(sub_converter, () => `Unknown sub_converter for type ${MarshalerType[value_type]} `); + mono_assert(sub_converter, () => `Unknown sub_converter for type ${MarshalerType[value_type]}. ${jsinteropDoc}`); const data = sub_converter(arg_value); promise_control.resolve(data); } @@ -406,7 +406,7 @@ function _marshal_cs_object_to_js(arg: JSMarshalerArgument): any { // other types const converter = cs_to_js_marshalers.get(marshaler_type); - mono_assert(converter, () => `Unknown converter for type ${MarshalerType[marshaler_type]}`); + mono_assert(converter, () => `Unknown converter for type ${MarshalerType[marshaler_type]}. ${jsinteropDoc}`); return converter(arg); } @@ -461,7 +461,7 @@ function _marshal_array_to_js_impl(arg: JSMarshalerArgument, element_type: Marsh result = sourceView.slice();//copy } else { - throw new Error(`NotImplementedException ${MarshalerType[element_type]} `); + throw new Error(`NotImplementedException ${MarshalerType[element_type]}. ${jsinteropDoc}`); } Module._free(buffer_ptr); return result; @@ -483,7 +483,7 @@ function _marshal_span_to_js(arg: JSMarshalerArgument, element_type?: MarshalerT result = new Span(buffer_ptr, length, MemoryViewType.Double); } else { - throw new Error(`NotImplementedException ${MarshalerType[element_type]} `); + throw new Error(`NotImplementedException ${MarshalerType[element_type]}. ${jsinteropDoc}`); } return result; } @@ -504,7 +504,7 @@ function _marshal_array_segment_to_js(arg: JSMarshalerArgument, element_type?: M result = new ArraySegment(buffer_ptr, length, MemoryViewType.Double); } else { - throw new Error(`NotImplementedException ${MarshalerType[element_type]} `); + throw new Error(`NotImplementedException ${MarshalerType[element_type]}. ${jsinteropDoc}`); } const gc_handle = get_arg_gc_handle(arg); if (BuildConfiguration === "Debug") { From db172b4c55e362dac8c2f253c6260caa372a745d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 10:23:48 -0700 Subject: [PATCH 266/783] JIT: Extract all side effects of the index in optRemoveRangeCheck (#92210) optRemoveRangeCheck extracts only GTF_ASG from the bounds check. If the BOUNDS_CHECK is complex, that results in silently dropping side effects on the floor (see the example case). The ideal fix is that we should always extract all side effects from the index and length operands, however this has large regressions because the length typically has an ARR_LENGTH that we then extract. This PR instead has a surgical fix for the problem case that can be backported to .NET 8. It extracts all side effects from the index, but keeps extracting only GTF_ASG from the length to get around the issue mentioned above. Fix #91862 Co-authored-by: Jakob Botsch Nielsen --- src/coreclr/jit/optimizer.cpp | 10 +++- .../JitBlue/Runtime_91576/Runtime_91576.cs | 2 +- .../JitBlue/Runtime_91862/Runtime_91862.cs | 46 +++++++++++++++++++ .../Runtime_91862/Runtime_91862.csproj | 8 ++++ 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91862/Runtime_91862.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91862/Runtime_91862.csproj diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index 7c99a6a423dd01..2ca5526476b82d 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -8875,9 +8875,15 @@ GenTree* Compiler::optRemoveRangeCheck(GenTreeBoundsChk* check, GenTree* comma, } #endif - // Extract side effects + // TODO-Bug: We really should be extracting all side effects from the + // length and index here, but the length typically involves a GT_ARR_LENGTH + // that we would preserve. Usually, as part of proving that the range check + // passes, we have also proven that the ARR_LENGTH is non-faulting. We need + // a good way to communicate to this function that it is ok to ignore side + // effects of the ARR_LENGTH. GenTree* sideEffList = nullptr; - gtExtractSideEffList(check, &sideEffList, GTF_ASG); + gtExtractSideEffList(check->GetArrayLength(), &sideEffList, GTF_ASG); + gtExtractSideEffList(check->GetIndex(), &sideEffList); if (sideEffList != nullptr) { diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91576/Runtime_91576.cs b/src/tests/JIT/Regression/JitBlue/Runtime_91576/Runtime_91576.cs index 4df185d99ab241..23ae4b41c76a28 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_91576/Runtime_91576.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91576/Runtime_91576.cs @@ -1,5 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license.aa +// The .NET Foundation licenses this file to you under the MIT license. // Generated by Fuzzlyn v1.6 on 2023-09-03 15:59:01 // Run on X64 Windows diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91862/Runtime_91862.cs b/src/tests/JIT/Regression/JitBlue/Runtime_91862/Runtime_91862.cs new file mode 100644 index 00000000000000..541e2658f2d6a3 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91862/Runtime_91862.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using Xunit; + +public class Runtime_91862 +{ + [Fact] + public static int TestEntryPoint() + { + return Foo(default); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static int Foo(Vector128 v) + { + int result = 101; + // This tree results in a BOUNDS_CHECK for Bar(...) & 3 + float x = Vector128.GetElement(v, Bar(ref result) & 3); + + if (result != 100) + { + Console.WriteLine("FAIL"); + } + + // After inlining x is DCE'd, which will extract side effects of its assignment above. + // That results IR amenable to forward sub, and we end up with a BOUNDS_CHECK + // with a complex index expression that we can still prove is within bounds. + Baz(x); + return result; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static int Bar(ref int result) + { + result = 100; + return 0; + } + + private static void Baz(float x) + { + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91862/Runtime_91862.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_91862/Runtime_91862.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91862/Runtime_91862.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From 7226388ddf7657da0b29d3ed72bf4855f544e065 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Mon, 18 Sep 2023 19:24:19 +0200 Subject: [PATCH 267/783] [release/8.0] JIT: Initialize jitstdout lazily (#92212) * JIT: Initialize jitstdout lazily Avoid duplicating a handle and doing several I/O operations on the startup path. Fixes #91856 as a side effect. * Fix jitShutdown * Add volatile * CSE * Ensure jitstdout() is not used eagerly * Move comment, fix printf -> jitprintf * Clean up --- src/coreclr/jit/codegencommon.cpp | 6 +- src/coreclr/jit/compiler.cpp | 342 +++++++++++++++--------------- src/coreclr/jit/compiler.h | 2 +- src/coreclr/jit/disasm.cpp | 6 +- src/coreclr/jit/ee_il_dll.cpp | 73 +++++-- src/coreclr/jit/emit.cpp | 4 +- src/coreclr/jit/error.cpp | 4 +- src/coreclr/jit/fgdiagnostic.cpp | 2 +- src/coreclr/jit/gentree.cpp | 4 +- src/coreclr/jit/gentree.h | 2 +- src/coreclr/jit/host.h | 5 +- src/coreclr/jit/inline.cpp | 2 +- src/coreclr/jit/lsra.cpp | 2 +- 13 files changed, 242 insertions(+), 212 deletions(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 07e03d3e0c2334..72e31c388154ab 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -2011,7 +2011,7 @@ void CodeGen::genEmitMachineCode() #if TRACK_LSRA_STATS if (JitConfig.DisplayLsraStats() == 3) { - compiler->m_pLinearScan->dumpLsraStatsSummary(jitstdout); + compiler->m_pLinearScan->dumpLsraStatsSummary(jitstdout()); } #endif // TRACK_LSRA_STATS @@ -2104,7 +2104,7 @@ void CodeGen::genEmitUnwindDebugGCandEH() genCreateAndStoreGCInfo(codeSize, prologSize, epilogSize DEBUGARG(codePtr)); #ifdef DEBUG - FILE* dmpf = jitstdout; + FILE* dmpf = jitstdout(); compiler->opts.dmpHex = false; if (!strcmp(compiler->info.compMethodName, "= 0.5) { - fprintf(fout, " GT_%-17s %7u (%4.1lf%%) %3u bytes each\n", GenTree::OpName(oper.Oper), count, - percentage, size); + jitprintf(" GT_%-17s %7u (%4.1lf%%) %3u bytes each\n", GenTree::OpName(oper.Oper), count, + percentage, size); remainingCount -= count; } else @@ -1484,14 +1482,14 @@ void Compiler::compShutdown() if (remainingCount > 0) { - fprintf(fout, " All other GT_xxx ... %7u (%4.1lf%%) ... %4.1lf%% small + %4.1lf%% large\n", - remainingCount, 100.0 * remainingCount / totalCount, 100.0 * remainingCountSmall / totalCount, - 100.0 * remainingCountLarge / totalCount); + jitprintf(" All other GT_xxx ... %7u (%4.1lf%%) ... %4.1lf%% small + %4.1lf%% large\n", remainingCount, + 100.0 * remainingCount / totalCount, 100.0 * remainingCountSmall / totalCount, + 100.0 * remainingCountLarge / totalCount); } - fprintf(fout, " -----------------------------------------------------\n"); - fprintf(fout, " Total ....... %11u --ALL-- ... %4.1lf%% small + %4.1lf%% large\n", totalCount, - 100.0 * countSmall / totalCount, 100.0 * countLarge / totalCount); - fprintf(fout, "\n"); + jitprintf(" -----------------------------------------------------\n"); + jitprintf(" Total ....... %11u --ALL-- ... %4.1lf%% small + %4.1lf%% large\n", totalCount, + 100.0 * countSmall / totalCount, 100.0 * countLarge / totalCount); + jitprintf("\n"); } #endif // COUNT_AST_OPERS @@ -1500,49 +1498,49 @@ void Compiler::compShutdown() if (grossVMsize && grossNCsize) { - fprintf(fout, "\n"); - fprintf(fout, "--------------------------------------\n"); - fprintf(fout, "Function and GC info size stats\n"); - fprintf(fout, "--------------------------------------\n"); + jitprintf("\n"); + jitprintf("--------------------------------------\n"); + jitprintf("Function and GC info size stats\n"); + jitprintf("--------------------------------------\n"); - fprintf(fout, "[%7u VM, %8u %6s %4u%%] %s\n", grossVMsize, grossNCsize, Target::g_tgtCPUName, - 100 * grossNCsize / grossVMsize, "Total (excluding GC info)"); + jitprintf("[%7u VM, %8u %6s %4u%%] %s\n", grossVMsize, grossNCsize, Target::g_tgtCPUName, + 100 * grossNCsize / grossVMsize, "Total (excluding GC info)"); - fprintf(fout, "[%7u VM, %8u %6s %4u%%] %s\n", grossVMsize, totalNCsize, Target::g_tgtCPUName, - 100 * totalNCsize / grossVMsize, "Total (including GC info)"); + jitprintf("[%7u VM, %8u %6s %4u%%] %s\n", grossVMsize, totalNCsize, Target::g_tgtCPUName, + 100 * totalNCsize / grossVMsize, "Total (including GC info)"); if (gcHeaderISize || gcHeaderNSize) { - fprintf(fout, "\n"); + jitprintf("\n"); - fprintf(fout, "GC tables : [%7uI,%7uN] %7u byt (%u%% of IL, %u%% of %s).\n", - gcHeaderISize + gcPtrMapISize, gcHeaderNSize + gcPtrMapNSize, totalNCsize - grossNCsize, - 100 * (totalNCsize - grossNCsize) / grossVMsize, 100 * (totalNCsize - grossNCsize) / grossNCsize, - Target::g_tgtCPUName); + jitprintf("GC tables : [%7uI,%7uN] %7u byt (%u%% of IL, %u%% of %s).\n", gcHeaderISize + gcPtrMapISize, + gcHeaderNSize + gcPtrMapNSize, totalNCsize - grossNCsize, + 100 * (totalNCsize - grossNCsize) / grossVMsize, 100 * (totalNCsize - grossNCsize) / grossNCsize, + Target::g_tgtCPUName); - fprintf(fout, "GC headers : [%7uI,%7uN] %7u byt, [%4.1fI,%4.1fN] %4.1f byt/meth\n", gcHeaderISize, - gcHeaderNSize, gcHeaderISize + gcHeaderNSize, (float)gcHeaderISize / (genMethodICnt + 0.001), - (float)gcHeaderNSize / (genMethodNCnt + 0.001), - (float)(gcHeaderISize + gcHeaderNSize) / genMethodCnt); + jitprintf("GC headers : [%7uI,%7uN] %7u byt, [%4.1fI,%4.1fN] %4.1f byt/meth\n", gcHeaderISize, + gcHeaderNSize, gcHeaderISize + gcHeaderNSize, (float)gcHeaderISize / (genMethodICnt + 0.001), + (float)gcHeaderNSize / (genMethodNCnt + 0.001), + (float)(gcHeaderISize + gcHeaderNSize) / genMethodCnt); - fprintf(fout, "GC ptr maps : [%7uI,%7uN] %7u byt, [%4.1fI,%4.1fN] %4.1f byt/meth\n", gcPtrMapISize, - gcPtrMapNSize, gcPtrMapISize + gcPtrMapNSize, (float)gcPtrMapISize / (genMethodICnt + 0.001), - (float)gcPtrMapNSize / (genMethodNCnt + 0.001), - (float)(gcPtrMapISize + gcPtrMapNSize) / genMethodCnt); + jitprintf("GC ptr maps : [%7uI,%7uN] %7u byt, [%4.1fI,%4.1fN] %4.1f byt/meth\n", gcPtrMapISize, + gcPtrMapNSize, gcPtrMapISize + gcPtrMapNSize, (float)gcPtrMapISize / (genMethodICnt + 0.001), + (float)gcPtrMapNSize / (genMethodNCnt + 0.001), + (float)(gcPtrMapISize + gcPtrMapNSize) / genMethodCnt); } else { - fprintf(fout, "\n"); + jitprintf("\n"); - fprintf(fout, "GC tables take up %u bytes (%u%% of instr, %u%% of %6s code).\n", - totalNCsize - grossNCsize, 100 * (totalNCsize - grossNCsize) / grossVMsize, - 100 * (totalNCsize - grossNCsize) / grossNCsize, Target::g_tgtCPUName); + jitprintf("GC tables take up %u bytes (%u%% of instr, %u%% of %6s code).\n", totalNCsize - grossNCsize, + 100 * (totalNCsize - grossNCsize) / grossVMsize, 100 * (totalNCsize - grossNCsize) / grossNCsize, + Target::g_tgtCPUName); } #ifdef DEBUG #if DOUBLE_ALIGN - fprintf(fout, "%u out of %u methods generated with double-aligned stack\n", - Compiler::s_lvaDoubleAlignedProcsCount, genMethodCnt); + jitprintf("%u out of %u methods generated with double-aligned stack\n", Compiler::s_lvaDoubleAlignedProcsCount, + genMethodCnt); #endif #endif } @@ -1550,110 +1548,110 @@ void Compiler::compShutdown() #endif // DISPLAY_SIZES #if CALL_ARG_STATS - compDispCallArgStats(fout); + compDispCallArgStats(jitstdout()); #endif #if COUNT_BASIC_BLOCKS - fprintf(fout, "--------------------------------------------------\n"); - fprintf(fout, "Basic block count frequency table:\n"); - fprintf(fout, "--------------------------------------------------\n"); - bbCntTable.dump(fout); - fprintf(fout, "--------------------------------------------------\n"); - - fprintf(fout, "\n"); - - fprintf(fout, "--------------------------------------------------\n"); - fprintf(fout, "IL method size frequency table for methods with a single basic block:\n"); - fprintf(fout, "--------------------------------------------------\n"); - bbOneBBSizeTable.dump(fout); - fprintf(fout, "--------------------------------------------------\n"); - - fprintf(fout, "--------------------------------------------------\n"); - fprintf(fout, "fgComputeDoms `while (change)` iterations:\n"); - fprintf(fout, "--------------------------------------------------\n"); - domsChangedIterationTable.dump(fout); - fprintf(fout, "--------------------------------------------------\n"); - - fprintf(fout, "--------------------------------------------------\n"); - fprintf(fout, "fgComputeReachabilitySets `while (change)` iterations:\n"); - fprintf(fout, "--------------------------------------------------\n"); - computeReachabilitySetsIterationTable.dump(fout); - fprintf(fout, "--------------------------------------------------\n"); - - fprintf(fout, "--------------------------------------------------\n"); - fprintf(fout, "fgComputeReachability `while (change)` iterations:\n"); - fprintf(fout, "--------------------------------------------------\n"); - computeReachabilityIterationTable.dump(fout); - fprintf(fout, "--------------------------------------------------\n"); + jitprintf("--------------------------------------------------\n"); + jitprintf("Basic block count frequency table:\n"); + jitprintf("--------------------------------------------------\n"); + bbCntTable.dump(jitstdout()); + jitprintf("--------------------------------------------------\n"); + + jitprintf("\n"); + + jitprintf("--------------------------------------------------\n"); + jitprintf("IL method size frequency table for methods with a single basic block:\n"); + jitprintf("--------------------------------------------------\n"); + bbOneBBSizeTable.dump(jitstdout()); + jitprintf("--------------------------------------------------\n"); + + jitprintf("--------------------------------------------------\n"); + jitprintf("fgComputeDoms `while (change)` iterations:\n"); + jitprintf("--------------------------------------------------\n"); + domsChangedIterationTable.dump(jitstdout()); + jitprintf("--------------------------------------------------\n"); + + jitprintf("--------------------------------------------------\n"); + jitprintf("fgComputeReachabilitySets `while (change)` iterations:\n"); + jitprintf("--------------------------------------------------\n"); + computeReachabilitySetsIterationTable.dump(jitstdout()); + jitprintf("--------------------------------------------------\n"); + + jitprintf("--------------------------------------------------\n"); + jitprintf("fgComputeReachability `while (change)` iterations:\n"); + jitprintf("--------------------------------------------------\n"); + computeReachabilityIterationTable.dump(jitstdout()); + jitprintf("--------------------------------------------------\n"); #endif // COUNT_BASIC_BLOCKS #if COUNT_LOOPS - fprintf(fout, "\n"); - fprintf(fout, "---------------------------------------------------\n"); - fprintf(fout, "Loop stats\n"); - fprintf(fout, "---------------------------------------------------\n"); - fprintf(fout, "Total number of methods with loops is %5u\n", totalLoopMethods); - fprintf(fout, "Total number of loops is %5u\n", totalLoopCount); - fprintf(fout, "Maximum number of loops per method is %5u\n", maxLoopsPerMethod); - fprintf(fout, "# of methods overflowing nat loop table is %5u\n", totalLoopOverflows); - fprintf(fout, "Total number of 'unnatural' loops is %5u\n", totalUnnatLoopCount); - fprintf(fout, "# of methods overflowing unnat loop limit is %5u\n", totalUnnatLoopOverflows); - fprintf(fout, "Total number of loops with an iterator is %5u\n", iterLoopCount); - fprintf(fout, "Total number of loops with a constant iterator is %5u\n", constIterLoopCount); - - fprintf(fout, "--------------------------------------------------\n"); - fprintf(fout, "Loop count frequency table:\n"); - fprintf(fout, "--------------------------------------------------\n"); - loopCountTable.dump(fout); - fprintf(fout, "--------------------------------------------------\n"); - fprintf(fout, "Loop exit count frequency table:\n"); - fprintf(fout, "--------------------------------------------------\n"); - loopExitCountTable.dump(fout); - fprintf(fout, "--------------------------------------------------\n"); + jitprintf("\n"); + jitprintf("---------------------------------------------------\n"); + jitprintf("Loop stats\n"); + jitprintf("---------------------------------------------------\n"); + jitprintf("Total number of methods with loops is %5u\n", totalLoopMethods); + jitprintf("Total number of loops is %5u\n", totalLoopCount); + jitprintf("Maximum number of loops per method is %5u\n", maxLoopsPerMethod); + jitprintf("# of methods overflowing nat loop table is %5u\n", totalLoopOverflows); + jitprintf("Total number of 'unnatural' loops is %5u\n", totalUnnatLoopCount); + jitprintf("# of methods overflowing unnat loop limit is %5u\n", totalUnnatLoopOverflows); + jitprintf("Total number of loops with an iterator is %5u\n", iterLoopCount); + jitprintf("Total number of loops with a constant iterator is %5u\n", constIterLoopCount); + + jitprintf("--------------------------------------------------\n"); + jitprintf("Loop count frequency table:\n"); + jitprintf("--------------------------------------------------\n"); + loopCountTable.dump(jitstdout()); + jitprintf("--------------------------------------------------\n"); + jitprintf("Loop exit count frequency table:\n"); + jitprintf("--------------------------------------------------\n"); + loopExitCountTable.dump(jitstdout()); + jitprintf("--------------------------------------------------\n"); #endif // COUNT_LOOPS #if MEASURE_NODE_SIZE - fprintf(fout, "\n"); - fprintf(fout, "---------------------------------------------------\n"); - fprintf(fout, "GenTree node allocation stats\n"); - fprintf(fout, "---------------------------------------------------\n"); + jitprintf("\n"); + jitprintf("---------------------------------------------------\n"); + jitprintf("GenTree node allocation stats\n"); + jitprintf("---------------------------------------------------\n"); - fprintf(fout, "Allocated %6I64u tree nodes (%7I64u bytes total, avg %4I64u bytes per method)\n", - genNodeSizeStats.genTreeNodeCnt, genNodeSizeStats.genTreeNodeSize, - genNodeSizeStats.genTreeNodeSize / genMethodCnt); + jitprintf("Allocated %6I64u tree nodes (%7I64u bytes total, avg %4I64u bytes per method)\n", + genNodeSizeStats.genTreeNodeCnt, genNodeSizeStats.genTreeNodeSize, + genNodeSizeStats.genTreeNodeSize / genMethodCnt); - fprintf(fout, "Allocated %7I64u bytes of unused tree node space (%3.2f%%)\n", - genNodeSizeStats.genTreeNodeSize - genNodeSizeStats.genTreeNodeActualSize, - (float)(100 * (genNodeSizeStats.genTreeNodeSize - genNodeSizeStats.genTreeNodeActualSize)) / - genNodeSizeStats.genTreeNodeSize); + jitprintf("Allocated %7I64u bytes of unused tree node space (%3.2f%%)\n", + genNodeSizeStats.genTreeNodeSize - genNodeSizeStats.genTreeNodeActualSize, + (float)(100 * (genNodeSizeStats.genTreeNodeSize - genNodeSizeStats.genTreeNodeActualSize)) / + genNodeSizeStats.genTreeNodeSize); - fprintf(fout, "\n"); - fprintf(fout, "---------------------------------------------------\n"); - fprintf(fout, "Distribution of per-method GenTree node counts:\n"); - genTreeNcntHist.dump(fout); + jitprintf("\n"); + jitprintf("---------------------------------------------------\n"); + jitprintf("Distribution of per-method GenTree node counts:\n"); + genTreeNcntHist.dump(jitstdout()); - fprintf(fout, "\n"); - fprintf(fout, "---------------------------------------------------\n"); - fprintf(fout, "Distribution of per-method GenTree node allocations (in bytes):\n"); - genTreeNsizHist.dump(fout); + jitprintf("\n"); + jitprintf("---------------------------------------------------\n"); + jitprintf("Distribution of per-method GenTree node allocations (in bytes):\n"); + genTreeNsizHist.dump(jitstdout()); #endif // MEASURE_NODE_SIZE #if MEASURE_BLOCK_SIZE - fprintf(fout, "\n"); - fprintf(fout, "---------------------------------------------------\n"); - fprintf(fout, "BasicBlock and FlowEdge/BasicBlockList allocation stats\n"); - fprintf(fout, "---------------------------------------------------\n"); + jitprintf("\n"); + jitprintf("---------------------------------------------------\n"); + jitprintf("BasicBlock and FlowEdge/BasicBlockList allocation stats\n"); + jitprintf("---------------------------------------------------\n"); - fprintf(fout, "Allocated %6u basic blocks (%7u bytes total, avg %4u bytes per method)\n", BasicBlock::s_Count, - BasicBlock::s_Size, BasicBlock::s_Size / genMethodCnt); - fprintf(fout, "Allocated %6u flow nodes (%7u bytes total, avg %4u bytes per method)\n", genFlowNodeCnt, - genFlowNodeSize, genFlowNodeSize / genMethodCnt); + jitprintf("Allocated %6u basic blocks (%7u bytes total, avg %4u bytes per method)\n", BasicBlock::s_Count, + BasicBlock::s_Size, BasicBlock::s_Size / genMethodCnt); + jitprintf("Allocated %6u flow nodes (%7u bytes total, avg %4u bytes per method)\n", genFlowNodeCnt, genFlowNodeSize, + genFlowNodeSize / genMethodCnt); #endif // MEASURE_BLOCK_SIZE @@ -1661,21 +1659,21 @@ void Compiler::compShutdown() if (s_dspMemStats) { - fprintf(fout, "\nAll allocations:\n"); - ArenaAllocator::dumpAggregateMemStats(jitstdout); + jitprintf("\nAll allocations:\n"); + ArenaAllocator::dumpAggregateMemStats(jitstdout()); - fprintf(fout, "\nLargest method:\n"); - ArenaAllocator::dumpMaxMemStats(jitstdout); + jitprintf("\nLargest method:\n"); + ArenaAllocator::dumpMaxMemStats(jitstdout()); - fprintf(fout, "\n"); - fprintf(fout, "---------------------------------------------------\n"); - fprintf(fout, "Distribution of total memory allocated per method (in KB):\n"); - memAllocHist.dump(fout); + jitprintf("\n"); + jitprintf("---------------------------------------------------\n"); + jitprintf("Distribution of total memory allocated per method (in KB):\n"); + memAllocHist.dump(jitstdout()); - fprintf(fout, "\n"); - fprintf(fout, "---------------------------------------------------\n"); - fprintf(fout, "Distribution of total memory used per method (in KB):\n"); - memUsedHist.dump(fout); + jitprintf("\n"); + jitprintf("---------------------------------------------------\n"); + jitprintf("Distribution of total memory used per method (in KB):\n"); + memUsedHist.dump(jitstdout()); } #endif // MEASURE_MEM_ALLOC @@ -1685,29 +1683,29 @@ void Compiler::compShutdown() if (JitConfig.DisplayLoopHoistStats() != 0) #endif // DEBUG { - PrintAggregateLoopHoistStats(jitstdout); + PrintAggregateLoopHoistStats(jitstdout()); } #endif // LOOP_HOIST_STATS #if TRACK_ENREG_STATS if (JitConfig.JitEnregStats() != 0) { - s_enregisterStats.Dump(fout); + s_enregisterStats.Dump(jitstdout()); } #endif // TRACK_ENREG_STATS #if MEASURE_PTRTAB_SIZE - fprintf(fout, "\n"); - fprintf(fout, "---------------------------------------------------\n"); - fprintf(fout, "GC pointer table stats\n"); - fprintf(fout, "---------------------------------------------------\n"); + jitprintf("\n"); + jitprintf("---------------------------------------------------\n"); + jitprintf("GC pointer table stats\n"); + jitprintf("---------------------------------------------------\n"); - fprintf(fout, "Reg pointer descriptor size (internal): %8u (avg %4u per method)\n", GCInfo::s_gcRegPtrDscSize, - GCInfo::s_gcRegPtrDscSize / genMethodCnt); + jitprintf("Reg pointer descriptor size (internal): %8u (avg %4u per method)\n", GCInfo::s_gcRegPtrDscSize, + GCInfo::s_gcRegPtrDscSize / genMethodCnt); - fprintf(fout, "Total pointer table size: %8u (avg %4u per method)\n", GCInfo::s_gcTotalPtrTabSize, - GCInfo::s_gcTotalPtrTabSize / genMethodCnt); + jitprintf("Total pointer table size: %8u (avg %4u per method)\n", GCInfo::s_gcTotalPtrTabSize, + GCInfo::s_gcTotalPtrTabSize / genMethodCnt); #endif // MEASURE_PTRTAB_SIZE @@ -1715,37 +1713,37 @@ void Compiler::compShutdown() if (genMethodCnt != 0) { - fprintf(fout, "\n"); - fprintf(fout, "A total of %6u methods compiled", genMethodCnt); + jitprintf("\n"); + jitprintf("A total of %6u methods compiled", genMethodCnt); #if DISPLAY_SIZES if (genMethodICnt || genMethodNCnt) { - fprintf(fout, " (%u interruptible, %u non-interruptible)", genMethodICnt, genMethodNCnt); + jitprintf(" (%u interruptible, %u non-interruptible)", genMethodICnt, genMethodNCnt); } #endif // DISPLAY_SIZES - fprintf(fout, ".\n"); + jitprintf(".\n"); } #endif // MEASURE_NODE_SIZE || MEASURE_BLOCK_SIZE || MEASURE_PTRTAB_SIZE || DISPLAY_SIZES #if EMITTER_STATS - emitterStats(fout); + emitterStats(jitstdout()); #endif #if MEASURE_FATAL - fprintf(fout, "\n"); - fprintf(fout, "---------------------------------------------------\n"); - fprintf(fout, "Fatal errors stats\n"); - fprintf(fout, "---------------------------------------------------\n"); - fprintf(fout, " badCode: %u\n", fatal_badCode); - fprintf(fout, " noWay: %u\n", fatal_noWay); - fprintf(fout, " implLimitation: %u\n", fatal_implLimitation); - fprintf(fout, " NOMEM: %u\n", fatal_NOMEM); - fprintf(fout, " noWayAssertBody: %u\n", fatal_noWayAssertBody); + jitprintf("\n"); + jitprintf("---------------------------------------------------\n"); + jitprintf("Fatal errors stats\n"); + jitprintf("---------------------------------------------------\n"); + jitprintf(" badCode: %u\n", fatal_badCode); + jitprintf(" noWay: %u\n", fatal_noWay); + jitprintf(" implLimitation: %u\n", fatal_implLimitation); + jitprintf(" NOMEM: %u\n", fatal_NOMEM); + jitprintf(" noWayAssertBody: %u\n", fatal_noWayAssertBody); #ifdef DEBUG - fprintf(fout, " noWayAssertBodyArgs: %u\n", fatal_noWayAssertBodyArgs); + jitprintf(" noWayAssertBodyArgs: %u\n", fatal_noWayAssertBodyArgs); #endif // DEBUG - fprintf(fout, " NYI: %u\n", fatal_NYI); + jitprintf(" NYI: %u\n", fatal_NYI); #endif // MEASURE_FATAL } @@ -1754,14 +1752,14 @@ void Compiler::compShutdown() */ /* static */ -void Compiler::compDisplayStaticSizes(FILE* fout) +void Compiler::compDisplayStaticSizes() { #if MEASURE_NODE_SIZE - GenTree::DumpNodeSizes(fout); + GenTree::DumpNodeSizes(); #endif #if EMITTER_STATS - emitterStaticStats(fout); + emitterStaticStats(); #endif } @@ -5177,7 +5175,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl #if TRACK_LSRA_STATS if (JitConfig.DisplayLsraStats() == 2) { - m_pLinearScan->dumpLsraStatsCsv(jitstdout); + m_pLinearScan->dumpLsraStatsCsv(jitstdout()); } #endif // TRACK_LSRA_STATS @@ -5879,7 +5877,7 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr, } #endif // FUNC_INFO_LOGGING - // if (s_compMethodsCount==0) setvbuf(jitstdout, NULL, _IONBF, 0); + // if (s_compMethodsCount==0) setvbuf(jitstdout(), NULL, _IONBF, 0); if (compIsForInlining()) { @@ -6363,7 +6361,7 @@ void Compiler::compCompileFinish() if (s_dspMemStats || verbose) { printf("\nAllocations for %s (MethodHash=%08x)\n", info.compFullName, info.compMethodHash()); - compArenaAllocator->dumpMemStats(jitstdout); + compArenaAllocator->dumpMemStats(jitstdout()); } #endif // DEBUG #endif // MEASURE_MEM_ALLOC diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 645e54258a637a..8339d6d274f4f5 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -10345,7 +10345,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX InlineInfo* inlineInfo); void compDone(); - static void compDisplayStaticSizes(FILE* fout); + static void compDisplayStaticSizes(); //------------ Some utility functions -------------- diff --git a/src/coreclr/jit/disasm.cpp b/src/coreclr/jit/disasm.cpp index e1926a3f640b7b..fd5c98eb068810 100644 --- a/src/coreclr/jit/disasm.cpp +++ b/src/coreclr/jit/disasm.cpp @@ -1478,12 +1478,12 @@ void DisAssembler::disAsmCode(BYTE* hotCodePtr, size_t hotCodeSize, BYTE* coldCo } #else // !DEBUG // NOTE: non-DEBUG builds always use jitstdout currently! - disAsmFile = jitstdout; + disAsmFile = jitstdout(); #endif // !DEBUG if (disAsmFile == nullptr) { - disAsmFile = jitstdout; + disAsmFile = jitstdout(); } // As this writes to a common file, this is not reentrant. @@ -1519,7 +1519,7 @@ void DisAssembler::disAsmCode(BYTE* hotCodePtr, size_t hotCodeSize, BYTE* coldCo DisasmBuffer(disAsmFile, /* printIt */ true); fprintf(disAsmFile, "\n"); - if (disAsmFile != jitstdout) + if (disAsmFile != jitstdout()) { fclose(disAsmFile); } diff --git a/src/coreclr/jit/ee_il_dll.cpp b/src/coreclr/jit/ee_il_dll.cpp index bcf7c7be401c21..57c52855ea8393 100644 --- a/src/coreclr/jit/ee_il_dll.cpp +++ b/src/coreclr/jit/ee_il_dll.cpp @@ -31,8 +31,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /*****************************************************************************/ -FILE* jitstdout = nullptr; - ICorJitHost* g_jitHost = nullptr; bool g_jitInitialized = false; @@ -72,15 +70,28 @@ extern "C" DLLEXPORT void jitStartup(ICorJitHost* jitHost) assert(!JitConfig.isInitialized()); JitConfig.initialize(jitHost); +#ifdef FEATURE_TRACELOGGING + JitTelemetry::NotifyDllProcessAttach(); +#endif + Compiler::compStartup(); + + g_jitInitialized = true; +} + +static FILE* volatile s_jitstdout; + +static FILE* jitstdoutInit() +{ const WCHAR* jitStdOutFile = JitConfig.JitStdOutFile(); + FILE* file = nullptr; if (jitStdOutFile != nullptr) { - jitstdout = _wfopen(jitStdOutFile, W("a")); - assert(jitstdout != nullptr); + file = _wfopen(jitStdOutFile, W("a")); + assert(file != nullptr); } #if !defined(HOST_UNIX) - if (jitstdout == nullptr) + if (file == nullptr) { int stdoutFd = _fileno(procstdout()); // Check fileno error output(s) -1 may overlap with errno result @@ -89,46 +100,61 @@ extern "C" DLLEXPORT void jitStartup(ICorJitHost* jitHost) // or bogus and avoid making further calls. if ((stdoutFd != -1) && (stdoutFd != -2) && (errno != EINVAL)) { - int jitstdoutFd = _dup(_fileno(procstdout())); + int jitstdoutFd = _dup(stdoutFd); // Check the error status returned by dup. if (jitstdoutFd != -1) { _setmode(jitstdoutFd, _O_TEXT); - jitstdout = _fdopen(jitstdoutFd, "w"); - assert(jitstdout != nullptr); + file = _fdopen(jitstdoutFd, "w"); + assert(file != nullptr); // Prevent the FILE* from buffering its output in order to avoid calls to // `fflush()` throughout the code. - setvbuf(jitstdout, nullptr, _IONBF, 0); + setvbuf(file, nullptr, _IONBF, 0); } } } #endif // !HOST_UNIX - // If jitstdout is still null, fallback to whatever procstdout() was - // initially set to. - if (jitstdout == nullptr) + if (file == nullptr) { - jitstdout = procstdout(); + file = procstdout(); } -#ifdef FEATURE_TRACELOGGING - JitTelemetry::NotifyDllProcessAttach(); -#endif - Compiler::compStartup(); + FILE* observed = InterlockedCompareExchangeT(&s_jitstdout, file, nullptr); - g_jitInitialized = true; + if (observed != nullptr) + { + if (file != procstdout()) + { + fclose(file); + } + + return observed; + } + + return file; } -#ifndef DEBUG +FILE* jitstdout() +{ + FILE* file = s_jitstdout; + if (file != nullptr) + { + return file; + } + + return jitstdoutInit(); +} + +// Like printf/logf, but only outputs to jitstdout -- skips call back into EE. void jitprintf(const char* fmt, ...) { va_list vl; va_start(vl, fmt); - vfprintf(jitstdout, fmt, vl); + vfprintf(jitstdout(), fmt, vl); va_end(vl); } -#endif void jitShutdown(bool processIsTerminating) { @@ -139,14 +165,15 @@ void jitShutdown(bool processIsTerminating) Compiler::compShutdown(); - if (jitstdout != procstdout()) + FILE* file = s_jitstdout; + if ((file != nullptr) && (file != procstdout())) { // When the process is terminating, the fclose call is unnecessary and is also prone to // crashing since the UCRT itself often frees the backing memory earlier on in the // termination sequence. if (!processIsTerminating) { - fclose(jitstdout); + fclose(file); } } diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index c85724f9240b98..8a671b7a757b88 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -215,7 +215,7 @@ unsigned emitter::emitInt32CnsCnt; unsigned emitter::emitNegCnsCnt; unsigned emitter::emitPow2CnsCnt; -void emitterStaticStats(FILE* fout) +void emitterStaticStats() { // The IG buffer size depends on whether we are storing a debug info pointer or not. For our purposes // here, do not include that. @@ -227,6 +227,8 @@ void emitterStaticStats(FILE* fout) insGroup* igDummy = nullptr; + FILE* fout = jitstdout(); + fprintf(fout, "\n"); fprintf(fout, "insGroup:\n"); fprintf(fout, "Offset / size of igNext = %3zu / %2zu\n", offsetof(insGroup, igNext), diff --git a/src/coreclr/jit/error.cpp b/src/coreclr/jit/error.cpp index 01e6f734b89f89..06635f5d582a1d 100644 --- a/src/coreclr/jit/error.cpp +++ b/src/coreclr/jit/error.cpp @@ -387,7 +387,7 @@ int logf(const char* fmt, ...) { // if the EE refuses to log it, we try to send it to stdout va_start(args, fmt); - written = vflogf(jitstdout, fmt, args); + written = vflogf(jitstdout(), fmt, args); va_end(args); } #if 0 // Enable this only when you need it @@ -448,7 +448,7 @@ void gcDump_logf(const char* fmt, ...) { // if the EE refuses to log it, we try to send it to stdout va_start(args, fmt); - vflogf(jitstdout, fmt, args); + vflogf(jitstdout(), fmt, args); va_end(args); } #if 0 // Enable this only when you need it diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp index e79bdb0e46368a..6dbc5e9a654845 100644 --- a/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/coreclr/jit/fgdiagnostic.cpp @@ -674,7 +674,7 @@ FILE* Compiler::fgOpenFlowGraphFile(bool* wbDontClose, Phases phase, PhasePositi } else if (strcmp(filename, "stdout") == 0) { - fgxFile = jitstdout; + fgxFile = jitstdout(); *wbDontClose = true; } else if (strcmp(filename, "stderr") == 0) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index d02ce4714d8a2e..a30c3794efdd29 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -481,10 +481,12 @@ void GenTree::ReportOperBashing(FILE* f) #if MEASURE_NODE_SIZE -void GenTree::DumpNodeSizes(FILE* fp) +void GenTree::DumpNodeSizes() { // Dump the sizes of the various GenTree flavors + FILE* fp = jitstdout(); + fprintf(fp, "Small tree node size = %zu bytes\n", TREE_NODE_SZ_SMALL); fprintf(fp, "Large tree node size = %zu bytes\n", TREE_NODE_SZ_LARGE); fprintf(fp, "\n"); diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 27688c3d41790d..109da6a15c30d8 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -2311,7 +2311,7 @@ struct GenTree void SetIndirExceptionFlags(Compiler* comp); #if MEASURE_NODE_SIZE - static void DumpNodeSizes(FILE* fp); + static void DumpNodeSizes(); #endif #ifdef DEBUG diff --git a/src/coreclr/jit/host.h b/src/coreclr/jit/host.h index c99a0601e499b0..0ccefae924e637 100644 --- a/src/coreclr/jit/host.h +++ b/src/coreclr/jit/host.h @@ -3,6 +3,8 @@ /*****************************************************************************/ +void jitprintf(const char* fmt, ...); + #ifdef DEBUG #undef printf @@ -44,7 +46,6 @@ extern "C" void ANALYZER_NORETURN __cdecl assertAbort(const char* why, const cha // Re-define printf in Release to use jitstdout (can be overwritten with DOTNET_JitStdOutFile=file) #undef printf #define printf jitprintf -void jitprintf(const char* fmt, ...); #undef assert #define assert(p) (void)0 @@ -55,7 +56,7 @@ void jitprintf(const char* fmt, ...); #define _HOST_H_ /*****************************************************************************/ -extern FILE* jitstdout; +FILE* jitstdout(); inline FILE* procstdout() { diff --git a/src/coreclr/jit/inline.cpp b/src/coreclr/jit/inline.cpp index bae5755707594d..0ded3ef3482a70 100644 --- a/src/coreclr/jit/inline.cpp +++ b/src/coreclr/jit/inline.cpp @@ -480,7 +480,7 @@ void InlineContext::DumpData(unsigned indent) { const char* inlineReason = InlGetObservationString(m_Observation); printf("%*s%u,\"%s\",\"%s\",", indent, "", GetOrdinal(), inlineReason, calleeName); - m_Policy->DumpData(jitstdout); + m_Policy->DumpData(jitstdout()); printf("\n"); } diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 5c8fe4aae77889..0a33ba3faba9bd 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -1421,7 +1421,7 @@ PhaseStatus LinearScan::doLinearScan() #endif ) { - dumpLsraStats(jitstdout); + dumpLsraStats(jitstdout()); } #endif // TRACK_LSRA_STATS From bf1e333ef05ce1977cca4f6502f020d19e214e7d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 11:31:42 -0700 Subject: [PATCH 268/783] [release/8.0] Check if loop body occured before loopTop and if so unmark alignment (#91918) * Check if loop body occured before loopTop" * Check if bbNatLoopNum is not NOT_IN_LOOP * review feedback --------- Co-authored-by: Kunal Pathak --- src/coreclr/jit/compiler.cpp | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 033e0990070d23..37534460a6c5c8 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -5280,6 +5280,13 @@ PhaseStatus Compiler::placeLoopAlignInstructions() weight_t minBlockSoFar = BB_MAX_WEIGHT; BasicBlock* bbHavingAlign = nullptr; BasicBlock::loopNumber currentAlignedLoopNum = BasicBlock::NOT_IN_LOOP; + bool visitedLoopNum[BasicBlock::MAX_LOOP_NUM]; + memset(visitedLoopNum, false, sizeof(visitedLoopNum)); + +#ifdef DEBUG + unsigned visitedBlockForLoopNum[BasicBlock::MAX_LOOP_NUM]; + memset(visitedBlockForLoopNum, 0, sizeof(visitedBlockForLoopNum)); +#endif if ((fgFirstBB != nullptr) && fgFirstBB->isLoopAlign()) { @@ -5302,7 +5309,7 @@ PhaseStatus Compiler::placeLoopAlignInstructions() } } - // If there is a unconditional jump (which is not part of callf/always pair) + // If there is an unconditional jump (which is not part of callf/always pair) if (opts.compJitHideAlignBehindJmp && (block->bbJumpKind == BBJ_ALWAYS) && !block->isBBCallAlwaysPairTail()) { // Track the lower weight blocks @@ -5356,12 +5363,19 @@ PhaseStatus Compiler::placeLoopAlignInstructions() madeChanges = true; unmarkedLoopAlign = true; } - else if ((block->bbNatLoopNum != BasicBlock::NOT_IN_LOOP) && (block->bbNatLoopNum == loopTop->bbNatLoopNum)) + else if ((loopTop->bbNatLoopNum != BasicBlock::NOT_IN_LOOP) && visitedLoopNum[loopTop->bbNatLoopNum]) { +#ifdef DEBUG + char buffer[100]; + sprintf_s(buffer, 100, "loop block " FMT_BB " appears before top of loop", + visitedBlockForLoopNum[loopTop->bbNatLoopNum]); +#endif + // In some odd cases we may see blocks within the loop before we see the // top block of the loop. Just bail on aligning such loops. // - loopTop->unmarkLoopAlign(this DEBUG_ARG("loop block appears before top of loop")); + + loopTop->unmarkLoopAlign(this DEBUG_ARG(buffer)); madeChanges = true; unmarkedLoopAlign = true; } @@ -5396,6 +5410,20 @@ PhaseStatus Compiler::placeLoopAlignInstructions() break; } } + + if (block->bbNatLoopNum != BasicBlock::NOT_IN_LOOP) + { +#ifdef DEBUG + if (!visitedLoopNum[block->bbNatLoopNum]) + { + // Record the first block for which bbNatLoopNum was seen for + // debugging purpose. + visitedBlockForLoopNum[block->bbNatLoopNum] = block->bbNum; + } +#endif + // If this block is part of loop, mark the loopNum as visited. + visitedLoopNum[block->bbNatLoopNum] = true; + } } assert(loopsToProcess == 0); From 644856c110bb27dcc8fad8664f7886393972aebd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 11:43:24 -0700 Subject: [PATCH 269/783] [release/8.0] Fix wasi build. (#92232) * Fix wasi build. * dummy change in wasi README to trigger a build * dummy change in wasi to trigger a build --------- Co-authored-by: Zoltan Varga Co-authored-by: Ankit Jain --- eng/pipelines/common/templates/pipeline-with-resources.yml | 4 ++-- src/mono/wasi/README.md | 3 ++- src/mono/wasi/build/WasiApp.targets | 2 -- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/eng/pipelines/common/templates/pipeline-with-resources.yml b/eng/pipelines/common/templates/pipeline-with-resources.yml index c30ce8597808d8..02242394fba671 100644 --- a/eng/pipelines/common/templates/pipeline-with-resources.yml +++ b/eng/pipelines/common/templates/pipeline-with-resources.yml @@ -85,12 +85,12 @@ resources: image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8 - container: browser_wasm - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly-20230913040940-1edc1c6 env: ROOTFS_DIR: /crossrootfs/x64 - container: wasi_wasm - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly-20230913040940-1edc1c6 env: ROOTFS_DIR: /crossrootfs/x64 diff --git a/src/mono/wasi/README.md b/src/mono/wasi/README.md index 66e59384297bb3..4c8759006359da 100644 --- a/src/mono/wasi/README.md +++ b/src/mono/wasi/README.md @@ -17,6 +17,7 @@ or for just native rebuild ./build.sh -bl -os wasi -subset mono.runtime+libs.native+mono.wasiruntime -c Debug ``` + ### 3. Run it Finally, you can build and run the sample: @@ -49,4 +50,4 @@ Download the Mono Debug extension and configure a launch.json like this: } ] } -``` \ No newline at end of file +``` diff --git a/src/mono/wasi/build/WasiApp.targets b/src/mono/wasi/build/WasiApp.targets index 1b8fc4e3fa9333..099ba8c3ebea27 100644 --- a/src/mono/wasi/build/WasiApp.targets +++ b/src/mono/wasi/build/WasiApp.targets @@ -4,8 +4,6 @@ + Provides the System.MathF for .NET Standard 2.0 + + true + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md index 5ce176a315dedb..b19975c09f41f4 100644 --- a/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md +++ b/src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md @@ -10,8 +10,6 @@ As of .NET Core 2.0 and .NET Standard 2.1, the C# language has support for math ## How to Use - - ```C# using System; diff --git a/src/libraries/Microsoft.Bcl.Numerics/src/System/MathF.cs b/src/libraries/Microsoft.Bcl.Numerics/src/System/MathF.cs new file mode 100644 index 00000000000000..128a3174ad0c4e --- /dev/null +++ b/src/libraries/Microsoft.Bcl.Numerics/src/System/MathF.cs @@ -0,0 +1,332 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/*============================================================ +** +** Purpose: Some single-precision floating-point math operations +** +===========================================================*/ + +//This class contains only static members and doesn't require serialization. + +//For most of this implementation for .NET Framework we just defer to System.Math and do a cast internally from single to double. +//We do this because it safer and less likely to break people since that is what they are alrady doing. Also, adding in the +//extra pinvokes needed to not do this route would probably incur an extra overhead that would be undersired. + +//For any version of .NET Core this just forwards directly to the MathF implementation inside the runtime. + +//There are a few cases where .NET Framework handles things differently than .NET Core does. For example, it returns -0 and +0 +//when using things like Min/Max, and they count as different values from each other. This is fixed in .NET Core, but since its +//inherent in .NET Framework we decided to leave that behavior as is for this BCL. + +using System.Diagnostics.Contracts; + +namespace System +{ + /// + /// Provides constants and static methods for trigonometric, logarithmic, and other common mathematical functions. + /// + public static class MathF + { + /// + /// Represents the ratio of the circumference of a circle to its diameter, specified by the constant, p. + /// + public const float PI = 3.14159265f; + + /// + /// Represents the natural logarithmic base, specified by the constant, e. + /// + public const float E = 2.71828183f; + + private static float NegativeZero = Int32BitsToSingle(unchecked((int)0x80000000)); + + private static unsafe float Int32BitsToSingle(int value) + { + return *((float*)&value); + } + + [Pure] + private static unsafe bool IsNegative(float f) + { + return (*(uint*)(&f) & 0x80000000) == 0x80000000; + } + + /// + /// Returns the absolute value of a single-precision floating-point number. + /// + /// The number to take the absolute value of. + /// The absolute value of + public static float Abs(float x) => Math.Abs(x); + + /// + /// Returns the angle whose cosine is the specified number. + /// + /// The number to take the acos of. + /// The acos of + public static float Acos(float x) => (float)Math.Acos(x); + + /// + /// Returns the angle whose sine is the specified number. + /// + /// The number to take the asin of. + /// The asin of + public static float Asin(float x) => (float)Math.Asin(x); + + /// + /// Returns the angle whose tangent is the specified number. + /// + /// The number to take the atan of. + /// The atan of + public static float Atan(float x) => (float)Math.Atan(x); + + /// + /// Returns the angle whose tangent is the quotient of two specified numbers. + /// + /// The first number. + /// The second number. + /// The angle whose tangent is the quotient of and + public static float Atan2(float y, float x) => (float)Math.Atan2(y, x); + + /// + /// Returns the smallest integral value that is greater than or equal to the specified single-precision floating-point number. + /// + /// The number to take the ceiling of. + /// The ceiling of + public static float Ceiling(float x) => (float)Math.Ceiling(x); + + /// + /// Returns the cosine of the specified angle. + /// + /// The angle to take the cosine of. + /// The cosine of + public static float Cos(float x) => (float)Math.Cos(x); + + /// + /// Returns the hyperbolic cosine of the specified angle. + /// + /// The angle to take the hyperbolic cosine of. + /// The hyperbolic cosine of + public static float Cosh(float x) => (float)Math.Cosh(x); + + /// + /// Returns e raised to the specified power. + /// + /// The number to raise e to. + /// e raised to the power of + public static float Exp(float x) => (float)Math.Exp(x); + + /// + /// Returns the largest integral value less than or equal to the specified single-precision floating-point number. + /// + /// The number to take the floor of. + /// The floor of + public static float Floor(float x) => (float)Math.Floor(x); + + /// + /// Returns the remainder resulting from the division of a specified number by another specified number. + /// + /// The numerator + /// The denominator + /// The result of dividing by + public static float IEEERemainder(float x, float y) + { + if (float.IsNaN(x)) + { + return x; // IEEE 754-2008: NaN payload must be preserved + } + + if (float.IsNaN(y)) + { + return y; // IEEE 754-2008: NaN payload must be preserved + } + + var regularMod = x % y; + + if (float.IsNaN(regularMod)) + { + return float.NaN; + } + + if ((regularMod == 0) && IsNegative(x)) + { + return NegativeZero; + } + + var alternativeResult = (regularMod - (Abs(y) * Sign(x))); + + if (Abs(alternativeResult) == Abs(regularMod)) + { + var divisionResult = x / y; + var roundedResult = Round(divisionResult); + + if (Abs(roundedResult) > Abs(divisionResult)) + { + return alternativeResult; + } + else + { + return regularMod; + } + } + + if (Abs(alternativeResult) < Abs(regularMod)) + { + return alternativeResult; + } + else + { + return regularMod; + } + } + + /// + /// Returns the natural (base e) logarithm of a specified number. + /// + /// The number to take the natural log of. + /// The natural log of + public static float Log(float x) => (float)Math.Log(x); + + /// + /// Returns the logarithm of a specified number in a specified base. + /// + /// The number to take the log of. + /// The base of the log + /// The log of with base + public static float Log(float x, float y) + { + if (float.IsNaN(x)) + { + return x; // IEEE 754-2008: NaN payload must be preserved + } + + if (float.IsNaN(y)) + { + return y; // IEEE 754-2008: NaN payload must be preserved + } + + if (y == 1) + { + return float.NaN; + } + + if ((x != 1) && ((y == 0) || float.IsPositiveInfinity(y))) + { + return float.NaN; + } + + return Log(x) / Log(y); + } + + /// + /// Returns the base 10 logarithm of a specified number. + /// + /// The number to take the base 10 log of. + /// The base 10 log of + public static float Log10(float x) => (float)Math.Log10(x); + + /// + /// Returns the larger of two single-precision floating-point numbers. + /// + /// The first number to compare. + /// The second number to compare. + /// The larger of and + public static float Max(float x, float y) => Math.Max(x, y); + + /// + /// Returns the smaller of two single-precision floating-point numbers. + /// + /// The first number to compare. + /// The second number to compare. + /// The smaller of and + public static float Min(float x, float y) => Math.Min(x, y); + + /// + /// Returns a specified number raised to the specified power. + /// + /// The base number. + /// The specified power. + /// raised to the power of + public static float Pow(float x, float y) => (float)Math.Pow(x, y); + + /// + /// Rounds a single-precision floating-point value to the nearest integral value, and rounds midpoint values to the nearest even number. + /// + /// The number to round. + /// The rounded representation of + public static float Round(float x) => (float)Math.Round(x); + + /// + /// Rounds a single-precision floating-point value to a specified number of fractional digits, and rounds midpoint values to the nearest even number. + /// + /// The number to round. + /// How many fractional digits to keep. + /// The rounded representation of with fractional digits + public static float Round(float x, int digits) => (float)Math.Round(x, digits); + + /// + /// Rounds a single-precision floating-point value to a specified number of fractional digits using the specified rounding convention. + /// + /// The number to round. + /// How many fractional digits to keep. + /// The rounding convention to use. + /// The rounded representation of with fractional digits using rounding convention + public static float Round(float x, int digits, MidpointRounding mode) => (float)Math.Round(x, digits, mode); + + /// + /// Rounds a single-precision floating-point value to an integer using the specified rounding convention. + /// + /// The number to round. + /// The rounding convention to use. + /// The rounded representation of using rounding convention + public static float Round(float x, MidpointRounding mode) => (float)Math.Round(x, mode); + + /// + /// Returns an integer that indicates the sign of a single-precision floating-point number. + /// + /// The number check the sign of. + /// The sign of + public static int Sign(float x) => Math.Sign(x); + + /// + /// Returns the sine of the specified angle. + /// + /// The angle to take the sine of. + /// The sine of + public static float Sin(float x) => (float)Math.Sin(x); + + /// + /// Returns the hyperbolic sine of the specified angle. + /// + /// The angle to take the hyperbolic sine of. + /// The hyperbolic sine of + public static float Sinh(float x) => (float)Math.Sinh(x); + + /// + /// Returns the square root of a specified number. + /// + /// The number to take the square root of. + /// The square root of + public static float Sqrt(float x) => (float)Math.Sqrt(x); + + /// + /// Returns the tangent of the specified angle. + /// + /// The angle to take the tangent of. + /// The tangent of + public static float Tan(float x) => (float)Math.Tan(x); + + /// + /// Returns the hyperbolic tangent of the specified angle. + /// + /// The angle to take the hyperbolic tangent of. + /// The hyperbolic tangent of + public static float Tanh(float x) => (float)Math.Tanh(x); + + /// + /// Calculates the integral part of a specified single-precision floating-point number. + /// + /// The number to truncate. + /// The truncated representation of + public static float Truncate(float x) => (float)Math.Truncate(x); + } +} diff --git a/src/libraries/Microsoft.Bcl.Numerics/src/System/Microsoft.Bcl.Numerics.Forwards.cs b/src/libraries/Microsoft.Bcl.Numerics/src/System/Microsoft.Bcl.Numerics.Forwards.cs new file mode 100644 index 00000000000000..641ce5525675f4 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.Numerics/src/System/Microsoft.Bcl.Numerics.Forwards.cs @@ -0,0 +1,4 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.MathF))] diff --git a/src/libraries/Microsoft.Bcl.Numerics/tests/MathF.cs b/src/libraries/Microsoft.Bcl.Numerics/tests/MathF.cs new file mode 100644 index 00000000000000..3aa148a2161564 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.Numerics/tests/MathF.cs @@ -0,0 +1,1169 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +#pragma warning disable xUnit1025 // reporting duplicate test cases due to not distinguishing 0.0 from -0.0 + +namespace System.Tests +{ + public static class MathFTests + { + // binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this + // is slightly too accurate when writing tests meant to run against libm implementations + // for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. + // + // The tests themselves will take CrossPlatformMachineEpsilon and adjust it according to the expected result + // so that the delta used for comparison will compare the most significant digits and ignore + // any digits that are outside the single precision range (6-9 digits). + + // For example, a test with an expect result in the format of 0.xxxxxxxxx will use + // CrossPlatformMachineEpsilon for the variance, while an expected result in the format of 0.0xxxxxxxxx + // will use CrossPlatformMachineEpsilon / 10 and expected result in the format of x.xxxxxx will + // use CrossPlatformMachineEpsilon * 10. + private const float CrossPlatformMachineEpsilon = 4.76837158e-07f; + + // The existing estimate functions either have an error of no more than 1.5 * 2^-12 (approx. 3.66e-04) + // or perform one Newton-Raphson iteration which, for the currently tested values, gives an error of + // no more than approx. 1.5 * 2^-7 (approx 1.17e-02). + private const double CrossPlatformMachineEpsilonForEstimates = 1.171875e-02f; + + [Fact] + public static void E() + { + Assert.Equal(2.71828183f, MathF.E); + } + + [Fact] + public static void Pi() + { + Assert.Equal(3.14159265f, MathF.PI); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.PositiveInfinity, 0.0f)] + [InlineData(-3.14159265f, 3.14159265f, CrossPlatformMachineEpsilon * 10)] // value: -(pi) expected: (pi) + [InlineData(-2.71828183f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // value: -(e) expected: (e) + [InlineData(-2.30258509f, 2.30258509f, CrossPlatformMachineEpsilon * 10)] // value: -(ln(10)) expected: (ln(10)) + [InlineData(-1.57079633f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // value: -(pi / 2) expected: (pi / 2) + [InlineData(-1.44269504f, 1.44269504f, CrossPlatformMachineEpsilon * 10)] // value: -(log2(e)) expected: (log2(e)) + [InlineData(-1.41421356f, 1.41421356f, CrossPlatformMachineEpsilon * 10)] // value: -(sqrt(2)) expected: (sqrt(2)) + [InlineData(-1.12837917f, 1.12837917f, CrossPlatformMachineEpsilon * 10)] // value: -(2 / sqrt(pi)) expected: (2 / sqrt(pi)) + [InlineData(-1.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.785398163f, 0.785398163f, CrossPlatformMachineEpsilon)] // value: -(pi / 4) expected: (pi / 4) + [InlineData(-0.707106781f, 0.707106781f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) expected: (1 / sqrt(2)) + [InlineData(-0.693147181f, 0.693147181f, CrossPlatformMachineEpsilon)] // value: -(ln(2)) expected: (ln(2)) + [InlineData(-0.636619772f, 0.636619772f, CrossPlatformMachineEpsilon)] // value: -(2 / pi) expected: (2 / pi) + [InlineData(-0.434294482f, 0.434294482f, CrossPlatformMachineEpsilon)] // value: -(log10(e)) expected: (log10(e)) + [InlineData(-0.318309886f, 0.318309886f, CrossPlatformMachineEpsilon)] // value: -(1 / pi) expected: (1 / pi) + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 0.0f)] + [InlineData(0.318309886f, 0.318309886f, CrossPlatformMachineEpsilon)] // value: (1 / pi) expected: (1 / pi) + [InlineData(0.434294482f, 0.434294482f, CrossPlatformMachineEpsilon)] // value: (log10(e)) expected: (log10(e)) + [InlineData(0.636619772f, 0.636619772f, CrossPlatformMachineEpsilon)] // value: (2 / pi) expected: (2 / pi) + [InlineData(0.693147181f, 0.693147181f, CrossPlatformMachineEpsilon)] // value: (ln(2)) expected: (ln(2)) + [InlineData(0.707106781f, 0.707106781f, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2)) expected: (1 / sqrt(2)) + [InlineData(0.785398163f, 0.785398163f, CrossPlatformMachineEpsilon)] // value: (pi / 4) expected: (pi / 4) + [InlineData(1.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(1.12837917f, 1.12837917f, CrossPlatformMachineEpsilon * 10)] // value: (2 / sqrt(pi)) expected: (2 / sqrt(pi)) + [InlineData(1.41421356f, 1.41421356f, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2)) expected: (sqrt(2)) + [InlineData(1.44269504f, 1.44269504f, CrossPlatformMachineEpsilon * 10)] // value: (log2(e)) expected: (log2(e)) + [InlineData(1.57079633f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2) expected: (pi / 2) + [InlineData(2.30258509f, 2.30258509f, CrossPlatformMachineEpsilon * 10)] // value: (ln(10)) expected: (ln(10)) + [InlineData(2.71828183f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // value: (e) expected: (e) + [InlineData(3.14159265f, 3.14159265f, CrossPlatformMachineEpsilon * 10)] // value: (pi) expected: (pi) + [InlineData(float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Abs(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Abs(value), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(-3.14159265f, float.NaN, 0.0f)] // value: -(pi) + [InlineData(-2.71828183f, float.NaN, 0.0f)] // value: -(e) + [InlineData(-1.41421356f, float.NaN, 0.0f)] // value: -(sqrt(2)) + [InlineData(-1.0f, 3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData(-0.911733915f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: (e) + [InlineData(-0.668201510f, 2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: (ln(10)) + [InlineData(-0.0f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData(0.127751218f, 1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData(0.155943695f, 1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData(0.428125148f, 1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData(0.540302306f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(0.707106781f, 0.785398163f, CrossPlatformMachineEpsilon)] // expected: (pi / 4), value: (1 / sqrt(2)) + [InlineData(0.760244597f, 0.707106781f, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData(0.769238901f, 0.693147181f, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData(0.804109828f, 0.636619772f, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData(0.907167129f, 0.434294482f, CrossPlatformMachineEpsilon)] // expected: (log10(e)) + [InlineData(0.949765715f, 0.318309886f, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData(1.0f, 0.0f, 0.0f)] + [InlineData(1.41421356f, float.NaN, 0.0f)] // value: (sqrt(2)) + [InlineData(2.71828183f, float.NaN, 0.0f)] // value: (e) + [InlineData(3.14159265f, float.NaN, 0.0f)] // value: (pi) + [InlineData(float.PositiveInfinity, float.NaN, 0.0f)] + public static void Acos(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Acos(value), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(-3.14159265f, float.NaN, 0.0f)] // value: -(pi) + [InlineData(-2.71828183f, float.NaN, 0.0f)] // value: -(e) + [InlineData(-1.41421356f, float.NaN, 0.0f)] // value: -(sqrt(2)) + [InlineData(-1.0f, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(-0.991806244f, -1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: -(log2(e)) + [InlineData(-0.987765946f, -1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: -(sqrt(2)) + [InlineData(-0.903719457f, -1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-0.841470985f, -1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.743980337f, -0.839007561f, CrossPlatformMachineEpsilon)] // expected: -(pi - ln(10)) + [InlineData(-0.707106781f, -0.785398163f, CrossPlatformMachineEpsilon)] // expected: -(pi / 4), value: (1 / sqrt(2)) + [InlineData(-0.649636939f, -0.707106781f, CrossPlatformMachineEpsilon)] // expected: -(1 / sqrt(2)) + [InlineData(-0.638961276f, -0.693147181f, CrossPlatformMachineEpsilon)] // expected: -(ln(2)) + [InlineData(-0.594480769f, -0.636619772f, CrossPlatformMachineEpsilon)] // expected: -(2 / pi) + [InlineData(-0.420770483f, -0.434294482f, CrossPlatformMachineEpsilon)] // expected: -(log10(e)) + [InlineData(-0.410781291f, -0.423310825f, CrossPlatformMachineEpsilon)] // expected: -(pi - e) + [InlineData(-0.312961796f, -0.318309886f, CrossPlatformMachineEpsilon)] // expected: -(1 / pi) + [InlineData(-0.0f, -0.0f, 0.0f)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 0.0f)] + [InlineData(0.312961796f, 0.318309886f, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData(0.410781291f, 0.423310825f, CrossPlatformMachineEpsilon)] // expected: (pi - e) + [InlineData(0.420770483f, 0.434294482f, CrossPlatformMachineEpsilon)] // expected: (log10(e)) + [InlineData(0.594480769f, 0.636619772f, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData(0.638961276f, 0.693147181f, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData(0.649636939f, 0.707106781f, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData(0.707106781f, 0.785398163f, CrossPlatformMachineEpsilon)] // expected: (pi / 4), value: (1 / sqrt(2)) + [InlineData(0.743980337f, 0.839007561f, CrossPlatformMachineEpsilon)] // expected: (pi - ln(10)) + [InlineData(0.841470985f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(0.903719457f, 1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData(0.987765946f, 1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData(0.991806244f, 1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData(1.0f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData(1.41421356f, float.NaN, 0.0f)] // value: (sqrt(2)) + [InlineData(2.71828183f, float.NaN, 0.0f)] // value: (e) + [InlineData(3.14159265f, float.NaN, 0.0f)] // value: (pi) + [InlineData(float.PositiveInfinity, float.NaN, 0.0f)] + public static void Asin(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Asin(value), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(-7.76357567f, -1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: -(log2(e)) + [InlineData(-6.33411917f, -1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: -(sqrt(2)) + [InlineData(-2.11087684f, -1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-1.55740772f, -1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-1.11340715f, -0.839007561f, CrossPlatformMachineEpsilon)] // expected: -(pi - ln(10)) + [InlineData(-1.0f, -0.785398163f, CrossPlatformMachineEpsilon)] // expected: -(pi / 4) + [InlineData(-0.854510432f, -0.707106781f, CrossPlatformMachineEpsilon)] // expected: -(1 / sqrt(2)) + [InlineData(-0.830640878f, -0.693147181f, CrossPlatformMachineEpsilon)] // expected: -(ln(2)) + [InlineData(-0.739302950f, -0.636619772f, CrossPlatformMachineEpsilon)] // expected: -(2 / pi) + [InlineData(-0.463829067f, -0.434294482f, CrossPlatformMachineEpsilon)] // expected: -(log10(e)) + [InlineData(-0.450549534f, -0.423310825f, CrossPlatformMachineEpsilon)] // expected: -(pi - e) + [InlineData(-0.329514733f, -0.318309886f, CrossPlatformMachineEpsilon)] // expected: -(1 / pi) + [InlineData(-0.0f, -0.0f, 0.0f)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 0.0f)] + [InlineData(0.329514733f, 0.318309886f, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData(0.450549534f, 0.423310825f, CrossPlatformMachineEpsilon)] // expected: (pi - e) + [InlineData(0.463829067f, 0.434294482f, CrossPlatformMachineEpsilon)] // expected: (log10(e)) + [InlineData(0.739302950f, 0.636619772f, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData(0.830640878f, 0.693147181f, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData(0.854510432f, 0.707106781f, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData(1.0f, 0.785398163f, CrossPlatformMachineEpsilon)] // expected: (pi / 4) + [InlineData(1.11340715f, 0.839007561f, CrossPlatformMachineEpsilon)] // expected: (pi - ln(10)) + [InlineData(1.55740772f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(2.11087684f, 1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData(6.33411917f, 1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData(7.76357567f, 1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData(float.PositiveInfinity, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + public static void Atan(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Atan(value), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, -1.0f, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(float.NegativeInfinity, -0.0f, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(float.NegativeInfinity, float.NaN, float.NaN, 0.0f)] + [InlineData(float.NegativeInfinity, 0.0f, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(float.NegativeInfinity, 1.0f, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(-1.0f, -1.0f, -2.35619449f, CrossPlatformMachineEpsilon * 10)] // expected: -(3 * pi / 4) + [InlineData(-1.0f, -0.0f, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(-1.0f, float.NaN, float.NaN, 0.0f)] + [InlineData(-1.0f, 0.0f, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(-1.0f, 1.0f, -0.785398163f, CrossPlatformMachineEpsilon)] // expected: -(pi / 4) + [InlineData(-1.0f, float.PositiveInfinity, -0.0f, 0.0f)] + [InlineData(-0.991806244f, -0.127751218f, -1.69889761f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi - log2(e)) + [InlineData(-0.991806244f, 0.127751218f, -1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: -(log2(e)) + [InlineData(-0.987765946f, -0.155943695f, -1.72737909f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi - sqrt(2)) + [InlineData(-0.987765946f, 0.155943695f, -1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: -(sqrt(2)) + [InlineData(-0.903719457f, -0.428125148f, -2.01321349f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi - (2 / sqrt(pi)) + [InlineData(-0.903719457f, 0.428125148f, -1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: -(2 / sqrt(pi) + [InlineData(-0.841470985f, -0.540302306f, -2.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi - 1) + [InlineData(-0.841470985f, 0.540302306f, -1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.743980337f, -0.668201510f, -2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: -(ln(10)) + [InlineData(-0.743980337f, 0.668201510f, -0.839007561f, CrossPlatformMachineEpsilon)] // expected: -(pi - ln(10)) + [InlineData(-0.707106781f, -0.707106781f, -2.35619449f, CrossPlatformMachineEpsilon * 10)] // expected: -(3 * pi / 4), y: -(1 / sqrt(2)) x: -(1 / sqrt(2)) + [InlineData(-0.707106781f, 0.707106781f, -0.785398163f, CrossPlatformMachineEpsilon)] // expected: -(pi / 4), y: -(1 / sqrt(2)) x: (1 / sqrt(2)) + [InlineData(-0.649636939f, -0.760244597f, -2.43448587f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi - (1 / sqrt(2)) + [InlineData(-0.649636939f, 0.760244597f, -0.707106781f, CrossPlatformMachineEpsilon)] // expected: -(1 / sqrt(2)) + [InlineData(-0.638961276f, -0.769238901f, -2.44844547f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi - ln(2)) + [InlineData(-0.638961276f, 0.769238901f, -0.693147181f, CrossPlatformMachineEpsilon)] // expected: -(ln(2)) + [InlineData(-0.594480769f, -0.804109828f, -2.50497288f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi - (2 / pi)) + [InlineData(-0.594480769f, 0.804109828f, -0.636619772f, CrossPlatformMachineEpsilon)] // expected: -(2 / pi) + [InlineData(-0.420770483f, -0.907167129f, -2.70729817f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi - log10(e)) + [InlineData(-0.420770483f, 0.907167129f, -0.434294482f, CrossPlatformMachineEpsilon)] // expected: -(log10(e)) + [InlineData(-0.410781291f, -0.911733915f, -2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: -(e) + [InlineData(-0.410781291f, 0.911733915f, -0.423310825f, CrossPlatformMachineEpsilon)] // expected: -(pi - e) + [InlineData(-0.312961796f, -0.949765715f, -2.82328277f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi - (1 / pi)) + [InlineData(-0.312961796f, 0.949765715f, -0.318309886f, CrossPlatformMachineEpsilon)] // expected: -(1 / pi) + [InlineData(-0.0f, float.NegativeInfinity, -3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi) + [InlineData(-0.0f, -1.0f, -3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi) + [InlineData(-0.0f, -0.0f, -3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi) + [InlineData(-0.0f, float.NaN, float.NaN, 0.0f)] + [InlineData(-0.0f, 0.0f, -0.0f, 0.0f)] + [InlineData(-0.0f, 1.0f, -0.0f, 0.0f)] + [InlineData(-0.0f, float.PositiveInfinity, -0.0f, 0.0f)] + [InlineData(float.NaN, float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(float.NaN, -1.0f, float.NaN, 0.0f)] + [InlineData(float.NaN, -0.0f, float.NaN, 0.0f)] + [InlineData(float.NaN, float.NaN, float.NaN, 0.0f)] + [InlineData(float.NaN, 0.0f, float.NaN, 0.0f)] + [InlineData(float.NaN, 1.0f, float.NaN, 0.0f)] + [InlineData(float.NaN, float.PositiveInfinity, float.NaN, 0.0f)] + [InlineData(0.0f, float.NegativeInfinity, 3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData(0.0f, -1.0f, 3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData(0.0f, -0.0f, 3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData(0.0f, float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 0.0f, 0.0f)] + [InlineData(0.0f, 1.0f, 0.0f, 0.0f)] + [InlineData(0.0f, float.PositiveInfinity, 0.0f, 0.0f)] + [InlineData(0.312961796f, -0.949765715f, 2.82328277f, CrossPlatformMachineEpsilon * 10)] // expected: (pi - (1 / pi)) + [InlineData(0.312961796f, 0.949765715f, 0.318309886f, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData(0.410781291f, -0.911733915f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: (e) + [InlineData(0.410781291f, 0.911733915f, 0.423310825f, CrossPlatformMachineEpsilon)] // expected: (pi - e) + [InlineData(0.420770483f, -0.907167129f, 2.70729817f, CrossPlatformMachineEpsilon * 10)] // expected: (pi - log10(e)) + [InlineData(0.420770483f, 0.907167129f, 0.434294482f, CrossPlatformMachineEpsilon)] // expected: (log10(e)) + [InlineData(0.594480769f, -0.804109828f, 2.50497288f, CrossPlatformMachineEpsilon * 10)] // expected: (pi - (2 / pi)) + [InlineData(0.594480769f, 0.804109828f, 0.636619772f, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData(0.638961276f, -0.769238901f, 2.44844547f, CrossPlatformMachineEpsilon * 10)] // expected: (pi - ln(2)) + [InlineData(0.638961276f, 0.769238901f, 0.693147181f, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData(0.649636939f, -0.760244597f, 2.43448587f, CrossPlatformMachineEpsilon * 10)] // expected: (pi - (1 / sqrt(2)) + [InlineData(0.649636939f, 0.760244597f, 0.707106781f, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData(0.707106781f, -0.707106781f, 2.35619449f, CrossPlatformMachineEpsilon * 10)] // expected: (3 * pi / 4), y: (1 / sqrt(2)) x: -(1 / sqrt(2)) + [InlineData(0.707106781f, 0.707106781f, 0.785398163f, CrossPlatformMachineEpsilon)] // expected: (pi / 4), y: (1 / sqrt(2)) x: (1 / sqrt(2)) + [InlineData(0.743980337f, -0.668201510f, 2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: (ln(10)) + [InlineData(0.743980337f, 0.668201510f, 0.839007561f, CrossPlatformMachineEpsilon)] // expected: (pi - ln(10)) + [InlineData(0.841470985f, -0.540302306f, 2.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: (pi - 1) + [InlineData(0.841470985f, 0.540302306f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(0.903719457f, -0.428125148f, 2.01321349f, CrossPlatformMachineEpsilon * 10)] // expected: (pi - (2 / sqrt(pi)) + [InlineData(0.903719457f, 0.428125148f, 1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData(0.987765946f, -0.155943695f, 1.72737909f, CrossPlatformMachineEpsilon * 10)] // expected: (pi - sqrt(2)) + [InlineData(0.987765946f, 0.155943695f, 1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData(0.991806244f, -0.127751218f, 1.69889761f, CrossPlatformMachineEpsilon * 10)] // expected: (pi - log2(e)) + [InlineData(0.991806244f, 0.127751218f, 1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData(1.0f, -1.0f, 2.35619449f, CrossPlatformMachineEpsilon * 10)] // expected: (3 * pi / 4) + [InlineData(1.0f, -0.0f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData(1.0f, float.NaN, float.NaN, 0.0f)] + [InlineData(1.0f, 0.0f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData(1.0f, 1.0f, 0.785398163f, CrossPlatformMachineEpsilon)] // expected: (pi / 4) + [InlineData(1.0f, float.PositiveInfinity, 0.0f, 0.0f)] + [InlineData(float.PositiveInfinity, -1.0f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData(float.PositiveInfinity, -0.0f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData(float.PositiveInfinity, float.NaN, float.NaN, 0.0f)] + [InlineData(float.PositiveInfinity, 0.0f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData(float.PositiveInfinity, 1.0f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + public static void Atan2(float y, float x, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Atan2(y, x), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.NegativeInfinity, 0.0f)] + [InlineData(-3.14159265f, -3.0f, 0.0f)] // value: -(pi) + [InlineData(-2.71828183f, -2.0f, 0.0f)] // value: -(e) + [InlineData(-2.30258509f, -2.0f, 0.0f)] // value: -(ln(10)) + [InlineData(-1.57079633f, -1.0f, 0.0f)] // value: -(pi / 2) + [InlineData(-1.44269504f, -1.0f, 0.0f)] // value: -(log2(e)) + [InlineData(-1.41421356f, -1.0f, 0.0f)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -1.0f, 0.0f)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -1.0f, 0.0f)] +#if NETFRAMEWORK + [InlineData(-0.785398163f, 0.0f, 0.0f)] // value: (pi / 4) + [InlineData(-0.707106781f, 0.0f, 0.0f)] // value: (1 / sqrt(2)) + [InlineData(-0.693147181f, 0.0f, 0.0f)] // value: (ln(2)) + [InlineData(-0.636619772f, 0.0f, 0.0f)] // value: (2 / pi) + [InlineData(-0.434294482f, 0.0f, 0.0f)] // value: (log10(e)) + [InlineData(-0.318309886f, 0.0f, 0.0f)] // value: (1 / pi) + [InlineData(-0.0f, -0.0f, 0.0f)] +#else + [InlineData(-0.785398163f, -0.0f, 0.0f)] // value: (pi / 4) + [InlineData(-0.707106781f, -0.0f, 0.0f)] // value: (1 / sqrt(2)) + [InlineData(-0.693147181f, -0.0f, 0.0f)] // value: (ln(2)) + [InlineData(-0.636619772f, -0.0f, 0.0f)] // value: (2 / pi) + [InlineData(-0.434294482f, -0.0f, 0.0f)] // value: (log10(e)) + [InlineData(-0.318309886f, -0.0f, 0.0f)] // value: (1 / pi) + [InlineData(-0.0f, -0.0f, 0.0f)] +#endif + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 0.0f)] + [InlineData(0.318309886f, 1.0f, 0.0f)] // value: (1 / pi) + [InlineData(0.434294482f, 1.0f, 0.0f)] // value: (log10(e)) + [InlineData(0.636619772f, 1.0f, 0.0f)] // value: (2 / pi) + [InlineData(0.693147181f, 1.0f, 0.0f)] // value: (ln(2)) + [InlineData(0.707106781f, 1.0f, 0.0f)] // value: (1 / sqrt(2)) + [InlineData(0.785398163f, 1.0f, 0.0f)] // value: (pi / 4) + [InlineData(1.0f, 1.0f, 0.0f)] + [InlineData(1.12837917f, 2.0f, 0.0f)] // value: (2 / sqrt(pi)) + [InlineData(1.41421356f, 2.0f, 0.0f)] // value: (sqrt(2)) + [InlineData(1.44269504f, 2.0f, 0.0f)] // value: (log2(e)) + [InlineData(1.57079633f, 2.0f, 0.0f)] // value: (pi / 2) + [InlineData(2.30258509f, 3.0f, 0.0f)] // value: (ln(10)) + [InlineData(2.71828183f, 3.0f, 0.0f)] // value: (e) + [InlineData(3.14159265f, 4.0f, 0.0f)] // value: (pi) + [InlineData(float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Ceiling(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Ceiling(value), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(-3.14159265f, -1.0f, CrossPlatformMachineEpsilon * 10)] // value: -(pi) + [InlineData(-2.71828183f, -0.911733918f, CrossPlatformMachineEpsilon)] // value: -(e) + [InlineData(-2.30258509f, -0.668201510f, CrossPlatformMachineEpsilon)] // value: -(ln(10)) + [InlineData(-1.57079633f, 0.0f, CrossPlatformMachineEpsilon)] // value: -(pi / 2) + [InlineData(-1.44269504f, 0.127751218f, CrossPlatformMachineEpsilon)] // value: -(log2(e)) + [InlineData(-1.41421356f, 0.155943695f, CrossPlatformMachineEpsilon)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, 0.428125148f, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, 0.540302306f, CrossPlatformMachineEpsilon)] + [InlineData(-0.785398163f, 0.707106781f, CrossPlatformMachineEpsilon)] // value: -(pi / 4), expected: (1 / sqrt(2)) + [InlineData(-0.707106781f, 0.760244597f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, 0.769238901f, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.636619772f, 0.804109828f, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.434294482f, 0.907167129f, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.318309886f, 0.949765715f, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(0.318309886f, 0.949765715f, CrossPlatformMachineEpsilon)] // value: (1 / pi) + [InlineData(0.434294482f, 0.907167129f, CrossPlatformMachineEpsilon)] // value: (log10(e)) + [InlineData(0.636619772f, 0.804109828f, CrossPlatformMachineEpsilon)] // value: (2 / pi) + [InlineData(0.693147181f, 0.769238901f, CrossPlatformMachineEpsilon)] // value: (ln(2)) + [InlineData(0.707106781f, 0.760244597f, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2)) + [InlineData(0.785398163f, 0.707106781f, CrossPlatformMachineEpsilon)] // value: (pi / 4), expected: (1 / sqrt(2)) + [InlineData(1.0f, 0.540302306f, CrossPlatformMachineEpsilon)] + [InlineData(1.12837917f, 0.428125148f, CrossPlatformMachineEpsilon)] // value: (2 / sqrt(pi)) + [InlineData(1.41421356f, 0.155943695f, CrossPlatformMachineEpsilon)] // value: (sqrt(2)) + [InlineData(1.44269504f, 0.127751218f, CrossPlatformMachineEpsilon)] // value: (log2(e)) + [InlineData(1.57079633f, 0.0f, CrossPlatformMachineEpsilon)] // value: (pi / 2) + [InlineData(2.30258509f, -0.668201510f, CrossPlatformMachineEpsilon)] // value: (ln(10)) + [InlineData(2.71828183f, -0.911733918f, CrossPlatformMachineEpsilon)] // value: (e) + [InlineData(3.14159265f, -1.0f, CrossPlatformMachineEpsilon * 10)] // value: (pi) + [InlineData(float.PositiveInfinity, float.NaN, 0.0f)] + public static void Cos(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Cos(value), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.PositiveInfinity, 0.0f)] + [InlineData(-3.14159265f, 11.5919533f, CrossPlatformMachineEpsilon * 100)] // value: (pi) + [InlineData(-2.71828183f, 7.61012514f, CrossPlatformMachineEpsilon * 10)] // value: (e) + [InlineData(-2.30258509f, 5.05f, CrossPlatformMachineEpsilon * 10)] // value: (ln(10)) + [InlineData(-1.57079633f, 2.50917848f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2) + [InlineData(-1.44269504f, 2.23418810f, CrossPlatformMachineEpsilon * 10)] // value: (log2(e)) + [InlineData(-1.41421356f, 2.17818356f, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2)) + [InlineData(-1.12837917f, 1.70710014f, CrossPlatformMachineEpsilon * 10)] // value: (2 / sqrt(pi)) + [InlineData(-1.0f, 1.54308063f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.785398163f, 1.32460909f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 4) + [InlineData(-0.707106781f, 1.26059184f, CrossPlatformMachineEpsilon * 10)] // value: (1 / sqrt(2)) + [InlineData(-0.693147181f, 1.25f, CrossPlatformMachineEpsilon * 10)] // value: (ln(2)) + [InlineData(-0.636619772f, 1.20957949f, CrossPlatformMachineEpsilon * 10)] // value: (2 / pi) + [InlineData(-0.434294482f, 1.09579746f, CrossPlatformMachineEpsilon * 10)] // value: (log10(e)) + [InlineData(-0.318309886f, 1.05108979f, CrossPlatformMachineEpsilon * 10)] // value: (1 / pi) + [InlineData(-0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(0.318309886f, 1.05108979f, CrossPlatformMachineEpsilon * 10)] // value: (1 / pi) + [InlineData(0.434294482f, 1.09579746f, CrossPlatformMachineEpsilon * 10)] // value: (log10(e)) + [InlineData(0.636619772f, 1.20957949f, CrossPlatformMachineEpsilon * 10)] // value: (2 / pi) + [InlineData(0.693147181f, 1.25f, CrossPlatformMachineEpsilon * 10)] // value: (ln(2)) + [InlineData(0.707106781f, 1.26059184f, CrossPlatformMachineEpsilon * 10)] // value: (1 / sqrt(2)) + [InlineData(0.785398163f, 1.32460909f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 4) + [InlineData(1.0f, 1.54308063f, CrossPlatformMachineEpsilon * 10)] + [InlineData(1.12837917f, 1.70710014f, CrossPlatformMachineEpsilon * 10)] // value: (2 / sqrt(pi)) + [InlineData(1.41421356f, 2.17818356f, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2)) + [InlineData(1.44269504f, 2.23418810f, CrossPlatformMachineEpsilon * 10)] // value: (log2(e)) + [InlineData(1.57079633f, 2.50917848f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2) + [InlineData(2.30258509f, 5.05f, CrossPlatformMachineEpsilon * 10)] // value: (ln(10)) + [InlineData(2.71828183f, 7.61012514f, CrossPlatformMachineEpsilon * 10)] // value: (e) + [InlineData(3.14159265f, 11.5919533f, CrossPlatformMachineEpsilon * 100)] // value: (pi) + [InlineData(float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Cosh(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Cosh(value), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, 0.0f, CrossPlatformMachineEpsilon)] + [InlineData(-3.14159265f, 0.0432139183f, CrossPlatformMachineEpsilon / 10)] // value: -(pi) + [InlineData(-2.71828183f, 0.0659880358f, CrossPlatformMachineEpsilon / 10)] // value: -(e) + [InlineData(-2.30258509f, 0.1f, CrossPlatformMachineEpsilon)] // value: -(ln(10)) + [InlineData(-1.57079633f, 0.207879576f, CrossPlatformMachineEpsilon)] // value: -(pi / 2) + [InlineData(-1.44269504f, 0.236290088f, CrossPlatformMachineEpsilon)] // value: -(log2(e)) + [InlineData(-1.41421356f, 0.243116734f, CrossPlatformMachineEpsilon)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, 0.323557264f, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, 0.367879441f, CrossPlatformMachineEpsilon)] + [InlineData(-0.785398163f, 0.455938128f, CrossPlatformMachineEpsilon)] // value: -(pi / 4) + [InlineData(-0.707106781f, 0.493068691f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, 0.5f, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.636619772f, 0.529077808f, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.434294482f, 0.647721485f, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.318309886f, 0.727377349f, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(0.318309886f, 1.37480223f, CrossPlatformMachineEpsilon * 10)] // value: (1 / pi) + [InlineData(0.434294482f, 1.54387344f, CrossPlatformMachineEpsilon * 10)] // value: (log10(e)) + [InlineData(0.636619772f, 1.89008116f, CrossPlatformMachineEpsilon * 10)] // value: (2 / pi) + [InlineData(0.693147181f, 2.0f, CrossPlatformMachineEpsilon * 10)] // value: (ln(2)) + [InlineData(0.707106781f, 2.02811498f, CrossPlatformMachineEpsilon * 10)] // value: (1 / sqrt(2)) + [InlineData(0.785398163f, 2.19328005f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 4) + [InlineData(1.0f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: (e) + [InlineData(1.12837917f, 3.09064302f, CrossPlatformMachineEpsilon * 10)] // value: (2 / sqrt(pi)) + [InlineData(1.41421356f, 4.11325038f, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2)) + [InlineData(1.44269504f, 4.23208611f, CrossPlatformMachineEpsilon * 10)] // value: (log2(e)) + [InlineData(1.57079633f, 4.81047738f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2) + [InlineData(2.30258509f, 10.0f, CrossPlatformMachineEpsilon * 100)] // value: (ln(10)) + [InlineData(2.71828183f, 15.1542622f, CrossPlatformMachineEpsilon * 100)] // value: (e) + [InlineData(3.14159265f, 23.1406926f, CrossPlatformMachineEpsilon * 100)] // value: (pi) + [InlineData(float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Exp(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Exp(value), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.NegativeInfinity, 0.0f)] + [InlineData(-3.14159265f, -4.0f, 0.0f)] // value: -(pi) + [InlineData(-2.71828183f, -3.0f, 0.0f)] // value: -(e) + [InlineData(-2.30258509f, -3.0f, 0.0f)] // value: -(ln(10)) + [InlineData(-1.57079633f, -2.0f, 0.0f)] // value: -(pi / 2) + [InlineData(-1.44269504f, -2.0f, 0.0f)] // value: -(log2(e)) + [InlineData(-1.41421356f, -2.0f, 0.0f)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -2.0f, 0.0f)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -1.0f, 0.0f)] + [InlineData(-0.785398163f, -1.0f, 0.0f)] // value: -(pi / 4) + [InlineData(-0.707106781f, -1.0f, 0.0f)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, -1.0f, 0.0f)] // value: -(ln(2)) + [InlineData(-0.636619772f, -1.0f, 0.0f)] // value: -(2 / pi) + [InlineData(-0.434294482f, -1.0f, 0.0f)] // value: -(log10(e)) + [InlineData(-0.318309886f, -1.0f, 0.0f)] // value: -(1 / pi) + [InlineData(-0.0f, -0.0f, 0.0f)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 0.0f)] + [InlineData(0.318309886f, 0.0f, 0.0f)] // value: (1 / pi) + [InlineData(0.434294482f, 0.0f, 0.0f)] // value: (log10(e)) + [InlineData(0.636619772f, 0.0f, 0.0f)] // value: (2 / pi) + [InlineData(0.693147181f, 0.0f, 0.0f)] // value: (ln(2)) + [InlineData(0.707106781f, 0.0f, 0.0f)] // value: (1 / sqrt(2)) + [InlineData(0.785398163f, 0.0f, 0.0f)] // value: (pi / 4) + [InlineData(1.0f, 1.0f, 0.0f)] + [InlineData(1.12837917f, 1.0f, 0.0f)] // value: (2 / sqrt(pi)) + [InlineData(1.41421356f, 1.0f, 0.0f)] // value: (sqrt(2)) + [InlineData(1.44269504f, 1.0f, 0.0f)] // value: (log2(e)) + [InlineData(1.57079633f, 1.0f, 0.0f)] // value: (pi / 2) + [InlineData(2.30258509f, 2.0f, 0.0f)] // value: (ln(10)) + [InlineData(2.71828183f, 2.0f, 0.0f)] // value: (e) + [InlineData(3.14159265f, 3.0f, 0.0f)] // value: (pi) + [InlineData(float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Floor(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Floor(value), allowedVariance); + } + + [Fact] + public static void IEEERemainder() + { + Assert.Equal(-1.0f, MathF.IEEERemainder(3.0f, 2.0f)); + Assert.Equal(0.0f, MathF.IEEERemainder(4.0f, 2.0f)); + Assert.Equal(1.0f, MathF.IEEERemainder(10.0f, 3.0f)); + Assert.Equal(-1.0f, MathF.IEEERemainder(11.0f, 3.0f)); + Assert.Equal(-2.0f, MathF.IEEERemainder(28.0f, 5.0f)); + AssertExtensions.Equal(1.8f, MathF.IEEERemainder(17.8f, 4.0f), CrossPlatformMachineEpsilon * 10); + AssertExtensions.Equal(1.4f, MathF.IEEERemainder(17.8f, 4.1f), CrossPlatformMachineEpsilon * 10); + AssertExtensions.Equal(0.1000004f, MathF.IEEERemainder(-16.3f, 4.1f), CrossPlatformMachineEpsilon / 10); + AssertExtensions.Equal(1.4f, MathF.IEEERemainder(17.8f, -4.1f), CrossPlatformMachineEpsilon * 10); + AssertExtensions.Equal(-1.4f, MathF.IEEERemainder(-17.8f, -4.1f), CrossPlatformMachineEpsilon * 10); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(-3.14159265f, float.NaN, 0.0f)] // value: -(pi) + [InlineData(-2.71828183f, float.NaN, 0.0f)] // value: -(e) + [InlineData(-1.41421356f, float.NaN, 0.0f)] // value: -(sqrt(2)) + [InlineData(-1.0f, float.NaN, 0.0f)] + [InlineData(-0.693147181f, float.NaN, 0.0f)] // value: -(ln(2)) + [InlineData(-0.434294482f, float.NaN, 0.0f)] // value: -(log10(e)) + [InlineData(-0.0f, float.NegativeInfinity, 0.0f)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, float.NegativeInfinity, 0.0f)] + [InlineData(0.0432139183f, -3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi) + [InlineData(0.0659880358f, -2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: -(e) + [InlineData(0.1f, -2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: -(ln(10)) + [InlineData(0.207879576f, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(0.236290088f, -1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: -(log2(e)) + [InlineData(0.243116734f, -1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: -(sqrt(2)) + [InlineData(0.323557264f, -1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(0.367879441f, -1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(0.455938128f, -0.785398163f, CrossPlatformMachineEpsilon)] // expected: -(pi / 4) + [InlineData(0.493068691f, -0.707106781f, CrossPlatformMachineEpsilon)] // expected: -(1 / sqrt(2)) + [InlineData(0.5f, -0.693147181f, CrossPlatformMachineEpsilon)] // expected: -(ln(2)) + [InlineData(0.529077808f, -0.636619772f, CrossPlatformMachineEpsilon)] // expected: -(2 / pi) + [InlineData(0.647721485f, -0.434294482f, CrossPlatformMachineEpsilon)] // expected: -(log10(e)) + [InlineData(0.727377349f, -0.318309886f, CrossPlatformMachineEpsilon)] // expected: -(1 / pi) + [InlineData(1.0f, 0.0f, 0.0f)] + [InlineData(1.37480223f, 0.318309886f, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData(1.54387344f, 0.434294482f, CrossPlatformMachineEpsilon)] // expected: (log10(e)) + [InlineData(1.89008116f, 0.636619772f, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData(2.0f, 0.693147181f, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData(2.02811498f, 0.707106781f, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData(2.19328005f, 0.785398163f, CrossPlatformMachineEpsilon)] // expected: (pi / 4) + [InlineData(2.71828183f, 1.0f, CrossPlatformMachineEpsilon * 10)] // value: (e) + [InlineData(3.09064302f, 1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData(4.11325038f, 1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData(4.23208611f, 1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData(4.81047738f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData(10.0f, 2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: (ln(10)) + [InlineData(15.1542622f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: (e) + [InlineData(23.1406926f, 3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData(float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Log(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Log(value), allowedVariance); + } + + [Fact] + public static void LogWithBase() + { + Assert.Equal(1.0f, MathF.Log(3.0f, 3.0f)); + AssertExtensions.Equal(2.40217350f, MathF.Log(14.0f, 3.0f), CrossPlatformMachineEpsilon * 10); + Assert.Equal(float.NegativeInfinity, MathF.Log(0.0f, 3.0f)); + Assert.Equal(float.NaN, MathF.Log(-3.0f, 3.0f)); + Assert.Equal(float.NaN, MathF.Log(float.NaN, 3.0f)); + Assert.Equal(float.PositiveInfinity, MathF.Log(float.PositiveInfinity, 3.0f)); + Assert.Equal(float.NaN, MathF.Log(float.NegativeInfinity, 3.0f)); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(-3.14159265f, float.NaN, 0.0f)] // value: -(pi) + [InlineData(-2.71828183f, float.NaN, 0.0f)] // value: -(e) + [InlineData(-1.41421356f, float.NaN, 0.0f)] // value: -(sqrt(2)) + [InlineData(-1.0f, float.NaN, 0.0f)] + [InlineData(-0.693147181f, float.NaN, 0.0f)] // value: -(ln(2)) + [InlineData(-0.434294482f, float.NaN, 0.0f)] // value: -(log10(e)) + [InlineData(-0.0f, float.NegativeInfinity, 0.0f)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, float.NegativeInfinity, 0.0f)] + [InlineData(0.000721784159f, -3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi) + [InlineData(0.00191301410f, -2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: -(e) + [InlineData(0.00498212830f, -2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: -(ln(10)) + [InlineData(0.0268660410f, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(0.0360831928f, -1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: -(log2(e)) + [InlineData(0.0385288847f, -1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: -(sqrt(2)) + [InlineData(0.0744082059f, -1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(0.1f, -1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(0.163908636f, -0.785398163f, CrossPlatformMachineEpsilon)] // expected: -(pi / 4) + [InlineData(0.196287760f, -0.707106781f, CrossPlatformMachineEpsilon)] // expected: -(1 / sqrt(2)) + [InlineData(0.202699566f, -0.693147181f, CrossPlatformMachineEpsilon)] // expected: -(ln(2)) + [InlineData(0.230876765f, -0.636619772f, CrossPlatformMachineEpsilon)] // expected: -(2 / pi) + [InlineData(0.367879441f, -0.434294482f, CrossPlatformMachineEpsilon)] // expected: -(log10(e)) + [InlineData(0.480496373f, -0.318309886f, CrossPlatformMachineEpsilon)] // expected: -(1 / pi) + [InlineData(1.0f, 0.0f, 0.0f)] + [InlineData(2.08118116f, 0.318309886f, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData(2.71828183f, 0.434294482f, CrossPlatformMachineEpsilon)] // expected: (log10(e)) value: (e) + [InlineData(4.33131503f, 0.636619772f, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData(4.93340967f, 0.693147181f, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData(5.09456117f, 0.707106781f, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData(6.10095980f, 0.785398163f, CrossPlatformMachineEpsilon)] // expected: (pi / 4) + [InlineData(10.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(13.4393779f, 1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData(25.9545535f, 1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData(27.7137338f, 1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData(37.2217105f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData(200.717432f, 2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: (ln(10)) + [InlineData(522.735300f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: (e) + [InlineData(1385.45573f, 3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData(float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Log10(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Log10(value), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.PositiveInfinity, float.PositiveInfinity)] + [InlineData(float.PositiveInfinity, float.NegativeInfinity, float.PositiveInfinity)] + [InlineData(float.MinValue, float.MaxValue, float.MaxValue)] + [InlineData(float.MaxValue, float.MinValue, float.MaxValue)] + [InlineData(float.NaN, float.NaN, float.NaN)] + [InlineData(float.NaN, 1.0f, float.NaN)] + [InlineData(1.0f, float.NaN, float.NaN)] + [InlineData(float.PositiveInfinity, float.NaN, float.NaN)] + [InlineData(float.NegativeInfinity, float.NaN, float.NaN)] + [InlineData(float.NaN, float.PositiveInfinity, float.NaN)] + [InlineData(float.NaN, float.NegativeInfinity, float.NaN)] + [InlineData(-0.0f, 0.0f, 0.0f)] +#if NETFRAMEWORK + [InlineData(0.0f, -0.0f, -0.0f)] +#else + [InlineData(0.0f, -0.0f, 0.0f)] +#endif + [InlineData(2.0f, -3.0f, 2.0f)] + [InlineData(-3.0f, 2.0f, 2.0f)] + [InlineData(3.0f, -2.0f, 3.0f)] + [InlineData(-2.0f, 3.0f, 3.0f)] + public static void Max(float x, float y, float expectedResult) + { + AssertExtensions.Equal(expectedResult, MathF.Max(x, y), 0.0f); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.PositiveInfinity, float.NegativeInfinity)] + [InlineData(float.PositiveInfinity, float.NegativeInfinity, float.NegativeInfinity)] + [InlineData(float.MinValue, float.MaxValue, float.MinValue)] + [InlineData(float.MaxValue, float.MinValue, float.MinValue)] + [InlineData(float.NaN, float.NaN, float.NaN)] + [InlineData(float.NaN, 1.0f, float.NaN)] + [InlineData(1.0f, float.NaN, float.NaN)] + [InlineData(float.PositiveInfinity, float.NaN, float.NaN)] + [InlineData(float.NegativeInfinity, float.NaN, float.NaN)] + [InlineData(float.NaN, float.PositiveInfinity, float.NaN)] + [InlineData(float.NaN, float.NegativeInfinity, float.NaN)] +#if NETFRAMEWORK + [InlineData(-0.0f, 0.0f, 0.0f)] +#else + [InlineData(-0.0f, 0.0f, -0.0f)] +#endif + [InlineData(0.0f, -0.0f, -0.0f)] + [InlineData(2.0f, -3.0f, -3.0f)] + [InlineData(-3.0f, 2.0f, -3.0f)] + [InlineData(3.0f, -2.0f, -2.0f)] + [InlineData(-2.0f, 3.0f, -2.0f)] + public static void Min(float x, float y, float expectedResult) + { + AssertExtensions.Equal(expectedResult, MathF.Min(x, y), 0.0f); + } + + + [Theory] + [InlineData(float.NegativeInfinity, float.NegativeInfinity, 0.0f, 0.0f)] + [InlineData(float.NegativeInfinity, -1.0f, -0.0f, 0.0f)] + [InlineData(float.NegativeInfinity, -0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(float.NegativeInfinity, float.NaN, float.NaN, 0.0f)] + [InlineData(float.NegativeInfinity, 0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(float.NegativeInfinity, 1.0f, float.NegativeInfinity, 0.0f)] + [InlineData(float.NegativeInfinity, float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + [InlineData(-10.0f, float.NegativeInfinity, 0.0f, 0.0f)] + [InlineData(-10.0f, -1.57079633f, float.NaN, 0.0f)] // y: -(pi / 2) + [InlineData(-10.0f, -1.0f, -0.1f, CrossPlatformMachineEpsilon)] + [InlineData(-10.0f, -0.785398163f, float.NaN, 0.0f)] // y: -(pi / 4) + [InlineData(-10.0f, -0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-10.0f, float.NaN, float.NaN, 0.0f)] + [InlineData(-10.0f, 0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-10.0f, 0.785398163f, float.NaN, 0.0f)] // y: (pi / 4) + [InlineData(-10.0f, 1.0f, -10.0f, CrossPlatformMachineEpsilon * 100)] + [InlineData(-10.0f, 1.57079633f, float.NaN, 0.0f)] // y: (pi / 2) + [InlineData(-10.0f, float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + [InlineData(-2.71828183f, float.NegativeInfinity, 0.0f, 0.0f)] // x: -(e) + [InlineData(-2.71828183f, -1.57079633f, float.NaN, 0.0f)] // x: -(e) y: -(pi / 2) + [InlineData(-2.71828183f, -1.0f, -0.367879441f, CrossPlatformMachineEpsilon)] // x: -(e) + [InlineData(-2.71828183f, -0.785398163f, float.NaN, 0.0f)] // x: -(e) y: -(pi / 4) + [InlineData(-2.71828183f, -0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] // x: -(e) + [InlineData(-2.71828183f, float.NaN, float.NaN, 0.0f)] + [InlineData(-2.71828183f, 0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] // x: -(e) + [InlineData(-2.71828183f, 0.785398163f, float.NaN, 0.0f)] // x: -(e) y: (pi / 4) + [InlineData(-2.71828183f, 1.0f, -2.71828183f, CrossPlatformMachineEpsilon * 10)] // x: -(e) expected: (e) + [InlineData(-2.71828183f, 1.57079633f, float.NaN, 0.0f)] // x: -(e) y: (pi / 2) + [InlineData(-2.71828183f, float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + [InlineData(-1.0f, -1.0f, -1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-1.0f, -0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-1.0f, float.NaN, float.NaN, 0.0f)] + [InlineData(-1.0f, 0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-1.0f, 1.0f, -1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.0f, float.NegativeInfinity, float.PositiveInfinity, 0.0f)] + [InlineData(-0.0f, -3.0f, float.NegativeInfinity, 0.0f)] + [InlineData(-0.0f, -2.0f, float.PositiveInfinity, 0.0f)] + [InlineData(-0.0f, -1.57079633f, float.PositiveInfinity, 0.0f)] // y: -(pi / 2) + [InlineData(-0.0f, -1.0f, float.NegativeInfinity, 0.0f)] + [InlineData(-0.0f, -0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.0f, float.NaN, float.NaN, 0.0f)] + [InlineData(-0.0f, 0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.0f, 1.0f, -0.0f, 0.0f)] + [InlineData(-0.0f, 1.57079633f, 0.0f, 0.0f)] // y: -(pi / 2) + [InlineData(-0.0f, 2.0f, 0.0f, 0.0f)] + [InlineData(-0.0f, 3.0f, -0.0f, 0.0f)] + [InlineData(-0.0f, float.PositiveInfinity, 0.0f, 0.0f)] + [InlineData(float.NaN, float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(float.NaN, -1.0f, float.NaN, 0.0f)] + [InlineData(float.NaN, float.NaN, float.NaN, 0.0f)] + [InlineData(float.NaN, 1.0f, float.NaN, 0.0f)] + [InlineData(float.NaN, float.PositiveInfinity, float.NaN, 0.0f)] + [InlineData(0.0f, float.NegativeInfinity, float.PositiveInfinity, 0.0f)] + [InlineData(0.0f, -3.0f, float.PositiveInfinity, 0.0f)] + [InlineData(0.0f, -2.0f, float.PositiveInfinity, 0.0f)] + [InlineData(0.0f, -1.57079633f, float.PositiveInfinity, 0.0f)] // y: -(pi / 2) + [InlineData(0.0f, -1.0f, float.PositiveInfinity, 0.0f)] + [InlineData(0.0f, -0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(0.0f, float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(0.0f, 1.0f, 0.0f, 0.0f)] + [InlineData(0.0f, 1.57079633f, 0.0f, 0.0f)] // y: -(pi / 2) + [InlineData(0.0f, 2.0f, 0.0f, 0.0f)] + [InlineData(0.0f, 3.0f, 0.0f, 0.0f)] + [InlineData(0.0f, float.PositiveInfinity, 0.0f, 0.0f)] + [InlineData(1.0f, float.NegativeInfinity, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(1.0f, -1.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(1.0f, -0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(1.0f, 0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(1.0f, 1.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(1.0f, float.PositiveInfinity, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(2.71828183f, float.NegativeInfinity, 0.0f, 0.0f)] + [InlineData(2.71828183f, -3.14159265f, 0.0432139183f, CrossPlatformMachineEpsilon / 10)] // x: (e) y: -(pi) + [InlineData(2.71828183f, -2.71828183f, 0.0659880358f, CrossPlatformMachineEpsilon / 10)] // x: (e) y: -(e) + [InlineData(2.71828183f, -2.30258509f, 0.1f, CrossPlatformMachineEpsilon)] // x: (e) y: -(ln(10)) + [InlineData(2.71828183f, -1.57079633f, 0.207879576f, CrossPlatformMachineEpsilon)] // x: (e) y: -(pi / 2) + [InlineData(2.71828183f, -1.44269504f, 0.236290088f, CrossPlatformMachineEpsilon)] // x: (e) y: -(log2(e)) + [InlineData(2.71828183f, -1.41421356f, 0.243116734f, CrossPlatformMachineEpsilon)] // x: (e) y: -(sqrt(2)) + [InlineData(2.71828183f, -1.12837917f, 0.323557264f, CrossPlatformMachineEpsilon)] // x: (e) y: -(2 / sqrt(pi)) + [InlineData(2.71828183f, -1.0f, 0.367879441f, CrossPlatformMachineEpsilon)] // x: (e) + [InlineData(2.71828183f, -0.785398163f, 0.455938128f, CrossPlatformMachineEpsilon)] // x: (e) y: -(pi / 4) + [InlineData(2.71828183f, -0.707106781f, 0.493068691f, CrossPlatformMachineEpsilon)] // x: (e) y: -(1 / sqrt(2)) + [InlineData(2.71828183f, -0.693147181f, 0.5f, CrossPlatformMachineEpsilon)] // x: (e) y: -(ln(2)) + [InlineData(2.71828183f, -0.636619772f, 0.529077808f, CrossPlatformMachineEpsilon)] // x: (e) y: -(2 / pi) + [InlineData(2.71828183f, -0.434294482f, 0.647721485f, CrossPlatformMachineEpsilon)] // x: (e) y: -(log10(e)) + [InlineData(2.71828183f, -0.318309886f, 0.727377349f, CrossPlatformMachineEpsilon)] // x: (e) y: -(1 / pi) + [InlineData(2.71828183f, -0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] // x: (e) + [InlineData(2.71828183f, float.NaN, float.NaN, 0.0f)] + [InlineData(2.71828183f, 0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] // x: (e) + [InlineData(2.71828183f, 0.318309886f, 1.37480223f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (1 / pi) + [InlineData(2.71828183f, 0.434294482f, 1.54387344f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (log10(e)) + [InlineData(2.71828183f, 0.636619772f, 1.89008116f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (2 / pi) + [InlineData(2.71828183f, 0.693147181f, 2.0f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (ln(2)) + [InlineData(2.71828183f, 0.707106781f, 2.02811498f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (1 / sqrt(2)) + [InlineData(2.71828183f, 0.785398163f, 2.19328005f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi / 4) + [InlineData(2.71828183f, 1.0f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // x: (e) expected: (e) + [InlineData(2.71828183f, 1.12837917f, 3.09064302f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (2 / sqrt(pi)) + [InlineData(2.71828183f, 1.41421356f, 4.11325038f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (sqrt(2)) + [InlineData(2.71828183f, 1.44269504f, 4.23208611f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (log2(e)) + [InlineData(2.71828183f, 1.57079633f, 4.81047738f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi / 2) + [InlineData(2.71828183f, 2.30258509f, 10.0f, CrossPlatformMachineEpsilon * 100)] // x: (e) y: (ln(10)) + [InlineData(2.71828183f, 2.71828183f, 15.1542622f, CrossPlatformMachineEpsilon * 100)] // x: (e) y: (e) + [InlineData(2.71828183f, 3.14159265f, 23.1406926f, CrossPlatformMachineEpsilon * 100)] // x: (e) y: (pi) + [InlineData(2.71828183f, float.PositiveInfinity, float.PositiveInfinity, 0.0f)] // x: (e) + [InlineData(10.0f, float.NegativeInfinity, 0.0f, 0.0f)] + [InlineData(10.0f, -3.14159265f, 0.000721784159f, CrossPlatformMachineEpsilon / 1000)] // y: -(pi) + [InlineData(10.0f, -2.71828183f, 0.00191301410f, CrossPlatformMachineEpsilon / 100)] // y: -(e) + [InlineData(10.0f, -2.30258509f, 0.00498212830f, CrossPlatformMachineEpsilon / 100)] // y: -(ln(10)) + [InlineData(10.0f, -1.57079633f, 0.0268660410f, CrossPlatformMachineEpsilon / 10)] // y: -(pi / 2) + [InlineData(10.0f, -1.44269504f, 0.0360831928f, CrossPlatformMachineEpsilon / 10)] // y: -(log2(e)) + [InlineData(10.0f, -1.41421356f, 0.0385288847f, CrossPlatformMachineEpsilon / 10)] // y: -(sqrt(2)) + [InlineData(10.0f, -1.12837917f, 0.0744082059f, CrossPlatformMachineEpsilon / 10)] // y: -(2 / sqrt(pi)) + [InlineData(10.0f, -1.0f, 0.1f, CrossPlatformMachineEpsilon)] + [InlineData(10.0f, -0.785398163f, 0.163908636f, CrossPlatformMachineEpsilon)] // y: -(pi / 4) + [InlineData(10.0f, -0.707106781f, 0.196287760f, CrossPlatformMachineEpsilon)] // y: -(1 / sqrt(2)) + [InlineData(10.0f, -0.693147181f, 0.202699566f, CrossPlatformMachineEpsilon)] // y: -(ln(2)) + [InlineData(10.0f, -0.636619772f, 0.230876765f, CrossPlatformMachineEpsilon)] // y: -(2 / pi) + [InlineData(10.0f, -0.434294482f, 0.367879441f, CrossPlatformMachineEpsilon)] // y: -(log10(e)) + [InlineData(10.0f, -0.318309886f, 0.480496373f, CrossPlatformMachineEpsilon)] // y: -(1 / pi) + [InlineData(10.0f, -0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(10.0f, float.NaN, float.NaN, 0.0f)] + [InlineData(10.0f, 0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(10.0f, 0.318309886f, 2.08118116f, CrossPlatformMachineEpsilon * 10)] // y: (1 / pi) + [InlineData(10.0f, 0.434294482f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // y: (log10(e)) expected: (e) + [InlineData(10.0f, 0.636619772f, 4.33131503f, CrossPlatformMachineEpsilon * 10)] // y: (2 / pi) + [InlineData(10.0f, 0.693147181f, 4.93340967f, CrossPlatformMachineEpsilon * 10)] // y: (ln(2)) + [InlineData(10.0f, 0.707106781f, 5.09456117f, CrossPlatformMachineEpsilon * 10)] // y: (1 / sqrt(2)) + [InlineData(10.0f, 0.785398163f, 6.10095980f, CrossPlatformMachineEpsilon * 10)] // y: (pi / 4) + [InlineData(10.0f, 1.0f, 10.0f, CrossPlatformMachineEpsilon * 100)] + [InlineData(10.0f, 1.12837917f, 13.4393779f, CrossPlatformMachineEpsilon * 100)] // y: (2 / sqrt(pi)) + [InlineData(10.0f, 1.41421356f, 25.9545535f, CrossPlatformMachineEpsilon * 100)] // y: (sqrt(2)) + [InlineData(10.0f, 1.44269504f, 27.7137338f, CrossPlatformMachineEpsilon * 100)] // y: (log2(e)) + [InlineData(10.0f, 1.57079633f, 37.2217105f, CrossPlatformMachineEpsilon * 100)] // y: (pi / 2) + [InlineData(10.0f, 2.30258509f, 200.717432f, CrossPlatformMachineEpsilon * 1000)] // y: (ln(10)) + [InlineData(10.0f, 2.71828183f, 522.735300f, CrossPlatformMachineEpsilon * 1000)] // y: (e) + [InlineData(10.0f, 3.14159265f, 1385.45573f, CrossPlatformMachineEpsilon * 10000)] // y: (pi) + [InlineData(10.0f, float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + [InlineData(float.PositiveInfinity, float.NegativeInfinity, 0.0f, 0.0f)] + [InlineData(float.PositiveInfinity, -1.0f, 0.0f, 0.0f)] + [InlineData(float.PositiveInfinity, -0.0f, 1.0f, 0.0f)] + [InlineData(float.PositiveInfinity, float.NaN, float.NaN, 0.0f)] + [InlineData(float.PositiveInfinity, 0.0f, 1.0f, 0.0f)] + [InlineData(float.PositiveInfinity, 1.0f, float.PositiveInfinity, 0.0f)] + [InlineData(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Pow(float x, float y, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Pow(x, y), allowedVariance); + } + + public static IEnumerable Round_Digits_TestData + { + get + { + yield return new object[] { float.NaN, float.NaN, 3, MidpointRounding.ToEven }; + yield return new object[] { float.PositiveInfinity, float.PositiveInfinity, 3, MidpointRounding.ToEven }; + yield return new object[] { float.NegativeInfinity, float.NegativeInfinity, 3, MidpointRounding.ToEven }; + yield return new object[] { 0, 0, 3, MidpointRounding.ToEven }; + yield return new object[] { 3.42156f, 3.422f, 3, MidpointRounding.ToEven }; + yield return new object[] { -3.42156f, -3.422f, 3, MidpointRounding.ToEven }; + + yield return new object[] { float.NaN, float.NaN, 3, MidpointRounding.AwayFromZero }; + yield return new object[] { float.PositiveInfinity, float.PositiveInfinity, 3, MidpointRounding.AwayFromZero }; + yield return new object[] { float.NegativeInfinity, float.NegativeInfinity, 3, MidpointRounding.AwayFromZero }; + yield return new object[] { 0, 0, 3, MidpointRounding.AwayFromZero }; + yield return new object[] { 3.42156f, 3.422f, 3, MidpointRounding.AwayFromZero }; + yield return new object[] { -3.42156f, -3.422f, 3, MidpointRounding.AwayFromZero }; + } + } + + [Fact] + public static void Round() + { + Assert.Equal(0.0f, MathF.Round(0.0f)); + Assert.Equal(1.0f, MathF.Round(1.4f)); + Assert.Equal(2.0f, MathF.Round(1.5f)); + Assert.Equal(2e7f, MathF.Round(2e7f)); + Assert.Equal(0.0f, MathF.Round(-0.0f)); + Assert.Equal(-1.0f, MathF.Round(-1.4f)); + Assert.Equal(-2.0f, MathF.Round(-1.5f)); + Assert.Equal(-2e7f, MathF.Round(-2e7f)); + } + + [Theory] + [InlineData(MidpointRounding.ToEven)] + [InlineData(MidpointRounding.AwayFromZero)] + public static void Round_Digits_ByMidpointRounding(MidpointRounding mode) + { + Assert.Equal(float.PositiveInfinity, MathF.Round(float.PositiveInfinity, 3, mode)); + Assert.Equal(float.NegativeInfinity, MathF.Round(float.NegativeInfinity, 3, mode)); + } + + [Theory] + [MemberData(nameof(Round_Digits_TestData))] + public static void Round_Digits(float x, float expected, int digits, MidpointRounding mode) + { + AssertExtensions.Equal(expected, MathF.Round(x, digits, mode), CrossPlatformMachineEpsilon * 10); + } + + [Fact] + public static void Sign() + { + Assert.Equal(0, MathF.Sign(0.0f)); + Assert.Equal(0, MathF.Sign(-0.0f)); + Assert.Equal(-1, MathF.Sign(-3.14f)); + Assert.Equal(1, MathF.Sign(3.14f)); + Assert.Equal(-1, MathF.Sign(float.NegativeInfinity)); + Assert.Equal(1, MathF.Sign(float.PositiveInfinity)); + Assert.Throws(() => MathF.Sign(float.NaN)); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(-3.14159265f, -0.0f, CrossPlatformMachineEpsilon)] // value: -(pi) + [InlineData(-2.71828183f, -0.410781291f, CrossPlatformMachineEpsilon)] // value: -(e) + [InlineData(-2.30258509f, -0.743980337f, CrossPlatformMachineEpsilon)] // value: -(ln(10)) + [InlineData(-1.57079633f, -1.0f, CrossPlatformMachineEpsilon * 10)] // value: -(pi / 2) + [InlineData(-1.44269504f, -0.991806244f, CrossPlatformMachineEpsilon)] // value: -(log2(e)) + [InlineData(-1.41421356f, -0.987765946f, CrossPlatformMachineEpsilon)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -0.903719457f, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -0.841470985f, CrossPlatformMachineEpsilon)] + [InlineData(-0.785398163f, -0.707106781f, CrossPlatformMachineEpsilon)] // value: -(pi / 4), expected: -(1 / sqrt(2)) + [InlineData(-0.707106781f, -0.649636939f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, -0.638961276f, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.636619772f, -0.594480769f, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.434294482f, -0.420770483f, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.318309886f, -0.312961796f, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0f, -0.0f, 0.0f)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 0.0f)] + [InlineData(0.318309886f, 0.312961796f, CrossPlatformMachineEpsilon)] // value: (1 / pi) + [InlineData(0.434294482f, 0.420770483f, CrossPlatformMachineEpsilon)] // value: (log10(e)) + [InlineData(0.636619772f, 0.594480769f, CrossPlatformMachineEpsilon)] // value: (2 / pi) + [InlineData(0.693147181f, 0.638961276f, CrossPlatformMachineEpsilon)] // value: (ln(2)) + [InlineData(0.707106781f, 0.649636939f, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2)) + [InlineData(0.785398163f, 0.707106781f, CrossPlatformMachineEpsilon)] // value: (pi / 4), expected: (1 / sqrt(2)) + [InlineData(1.0f, 0.841470985f, CrossPlatformMachineEpsilon)] + [InlineData(1.12837917f, 0.903719457f, CrossPlatformMachineEpsilon)] // value: (2 / sqrt(pi)) + [InlineData(1.41421356f, 0.987765946f, CrossPlatformMachineEpsilon)] // value: (sqrt(2)) + [InlineData(1.44269504f, 0.991806244f, CrossPlatformMachineEpsilon)] // value: (log2(e)) + [InlineData(1.57079633f, 1.0f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2) + [InlineData(2.30258509f, 0.743980337f, CrossPlatformMachineEpsilon)] // value: (ln(10)) + [InlineData(2.71828183f, 0.410781291f, CrossPlatformMachineEpsilon)] // value: (e) + [InlineData(3.14159265f, 0.0f, CrossPlatformMachineEpsilon)] // value: (pi) + [InlineData(float.PositiveInfinity, float.NaN, 0.0f)] + public static void Sin(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Sin(value), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.NegativeInfinity, 0.0f)] + [InlineData(-3.14159265f, -11.5487394f, CrossPlatformMachineEpsilon * 100)] // value: -(pi) + [InlineData(-2.71828183f, -7.54413710f, CrossPlatformMachineEpsilon * 10)] // value: -(e) + [InlineData(-2.30258509f, -4.95f, CrossPlatformMachineEpsilon * 10)] // value: -(ln(10)) + [InlineData(-1.57079633f, -2.30129890f, CrossPlatformMachineEpsilon * 10)] // value: -(pi / 2) + [InlineData(-1.44269504f, -1.99789801f, CrossPlatformMachineEpsilon * 10)] // value: -(log2(e)) + [InlineData(-1.41421356f, -1.93506682f, CrossPlatformMachineEpsilon * 10)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -1.38354288f, CrossPlatformMachineEpsilon * 10)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -1.17520119f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.785398163f, -0.868670961f, CrossPlatformMachineEpsilon)] // value: -(pi / 4) + [InlineData(-0.707106781f, -0.767523145f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, -0.75f, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.636619772f, -0.680501678f, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.434294482f, -0.448075979f, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.318309886f, -0.323712439f, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0f, -0.0f, 0.0f)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 0.0f)] + [InlineData(0.318309886f, 0.323712439f, CrossPlatformMachineEpsilon)] // value: (1 / pi) + [InlineData(0.434294482f, 0.448075979f, CrossPlatformMachineEpsilon)] // value: (log10(e)) + [InlineData(0.636619772f, 0.680501678f, CrossPlatformMachineEpsilon)] // value: (2 / pi) + [InlineData(0.693147181f, 0.75f, CrossPlatformMachineEpsilon)] // value: (ln(2)) + [InlineData(0.707106781f, 0.767523145f, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2)) + [InlineData(0.785398163f, 0.868670961f, CrossPlatformMachineEpsilon)] // value: (pi / 4) + [InlineData(1.0f, 1.17520119f, CrossPlatformMachineEpsilon * 10)] + [InlineData(1.12837917f, 1.38354288f, CrossPlatformMachineEpsilon * 10)] // value: (2 / sqrt(pi)) + [InlineData(1.41421356f, 1.93506682f, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2)) + [InlineData(1.44269504f, 1.99789801f, CrossPlatformMachineEpsilon * 10)] // value: (log2(e)) + [InlineData(1.57079633f, 2.30129890f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2) + [InlineData(2.30258509f, 4.95f, CrossPlatformMachineEpsilon * 10)] // value: (ln(10)) + [InlineData(2.71828183f, 7.54413710f, CrossPlatformMachineEpsilon * 10)] // value: (e) + [InlineData(3.14159265f, 11.5487394f, CrossPlatformMachineEpsilon * 100)] // value: (pi) + [InlineData(float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Sinh(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Sinh(value), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(-3.14159265f, float.NaN, 0.0f)] // value: (pi) + [InlineData(-2.71828183f, float.NaN, 0.0f)] // value: (e) + [InlineData(-2.30258509f, float.NaN, 0.0f)] // value: (ln(10)) + [InlineData(-1.57079633f, float.NaN, 0.0f)] // value: (pi / 2) + [InlineData(-1.44269504f, float.NaN, 0.0f)] // value: (log2(e)) + [InlineData(-1.41421356f, float.NaN, 0.0f)] // value: (sqrt(2)) + [InlineData(-1.12837917f, float.NaN, 0.0f)] // value: (2 / sqrt(pi)) + [InlineData(-1.0f, float.NaN, 0.0f)] + [InlineData(-0.785398163f, float.NaN, 0.0f)] // value: (pi / 4) + [InlineData(-0.707106781f, float.NaN, 0.0f)] // value: (1 / sqrt(2)) + [InlineData(-0.693147181f, float.NaN, 0.0f)] // value: (ln(2)) + [InlineData(-0.636619772f, float.NaN, 0.0f)] // value: (2 / pi) + [InlineData(-0.434294482f, float.NaN, 0.0f)] // value: (log10(e)) + [InlineData(-0.318309886f, float.NaN, 0.0f)] // value: (1 / pi) + [InlineData(-0.0f, -0.0f, 0.0f)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 0.0f)] + [InlineData(0.318309886f, 0.564189584f, CrossPlatformMachineEpsilon)] // value: (1 / pi) + [InlineData(0.434294482f, 0.659010229f, CrossPlatformMachineEpsilon)] // value: (log10(e)) + [InlineData(0.636619772f, 0.797884561f, CrossPlatformMachineEpsilon)] // value: (2 / pi) + [InlineData(0.693147181f, 0.832554611f, CrossPlatformMachineEpsilon)] // value: (ln(2)) + [InlineData(0.707106781f, 0.840896415f, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2)) + [InlineData(0.785398163f, 0.886226925f, CrossPlatformMachineEpsilon)] // value: (pi / 4) + [InlineData(1.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(1.12837917f, 1.06225193f, CrossPlatformMachineEpsilon * 10)] // value: (2 / sqrt(pi)) + [InlineData(1.41421356f, 1.18920712f, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2)) + [InlineData(1.44269504f, 1.20112241f, CrossPlatformMachineEpsilon * 10)] // value: (log2(e)) + [InlineData(1.57079633f, 1.25331414f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2) + [InlineData(2.30258509f, 1.51742713f, CrossPlatformMachineEpsilon * 10)] // value: (ln(10)) + [InlineData(2.71828183f, 1.64872127f, CrossPlatformMachineEpsilon * 10)] // value: (e) + [InlineData(3.14159265f, 1.77245385F, CrossPlatformMachineEpsilon * 10)] // value: (pi) + [InlineData(float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Sqrt(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Sqrt(value), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(-3.14159265f, -0.0f, CrossPlatformMachineEpsilon)] // value: -(pi) + [InlineData(-2.71828183f, 0.450549534f, CrossPlatformMachineEpsilon)] // value: -(e) + [InlineData(-2.30258509f, 1.11340715f, CrossPlatformMachineEpsilon * 10)] // value: -(ln(10)) + [InlineData(-1.57079633f, 22877332.0f, 10.0f)] // value: -(pi / 2) + [InlineData(-1.44269504f, -7.76357567f, CrossPlatformMachineEpsilon * 10)] // value: -(log2(e)) + [InlineData(-1.41421356f, -6.33411917f, CrossPlatformMachineEpsilon * 10)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -2.11087684f, CrossPlatformMachineEpsilon * 10)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -1.55740772f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.785398163f, -1.0f, CrossPlatformMachineEpsilon * 10)] // value: -(pi / 4) + [InlineData(-0.707106781f, -0.854510432f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, -0.830640878f, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.636619772f, -0.739302950f, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.434294482f, -0.463829067f, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.318309886f, -0.329514733f, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0f, -0.0f, 0.0f)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 0.0f)] + [InlineData(0.318309886f, 0.329514733f, CrossPlatformMachineEpsilon)] // value: (1 / pi) + [InlineData(0.434294482f, 0.463829067f, CrossPlatformMachineEpsilon)] // value: (log10(e)) + [InlineData(0.636619772f, 0.739302950f, CrossPlatformMachineEpsilon)] // value: (2 / pi) + [InlineData(0.693147181f, 0.830640878f, CrossPlatformMachineEpsilon)] // value: (ln(2)) + [InlineData(0.707106781f, 0.854510432f, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2)) + [InlineData(0.785398163f, 1.0f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 4) + [InlineData(1.0f, 1.55740772f, CrossPlatformMachineEpsilon * 10)] + [InlineData(1.12837917f, 2.11087684f, CrossPlatformMachineEpsilon * 10)] // value: (2 / sqrt(pi)) + [InlineData(1.41421356f, 6.33411917f, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2)) + [InlineData(1.44269504f, 7.76357567f, CrossPlatformMachineEpsilon * 10)] // value: (log2(e)) + [InlineData(1.57079633f, -22877332.0f, 10.0f)] // value: (pi / 2) + [InlineData(2.30258509f, -1.11340715f, CrossPlatformMachineEpsilon * 10)] // value: (ln(10)) + [InlineData(2.71828183f, -0.450549534f, CrossPlatformMachineEpsilon)] // value: (e) + [InlineData(3.14159265f, 0.0f, CrossPlatformMachineEpsilon)] // value: (pi) + [InlineData(float.PositiveInfinity, float.NaN, 0.0f)] + public static void Tan(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Tan(value), allowedVariance); + } + + [Theory] + [InlineData(float.NegativeInfinity, -1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-3.14159265f, -0.996272076f, CrossPlatformMachineEpsilon)] // value: -(pi) + [InlineData(-2.71828183f, -0.991328916f, CrossPlatformMachineEpsilon)] // value: -(e) + [InlineData(-2.30258509f, -0.980198020f, CrossPlatformMachineEpsilon)] // value: -(ln(10)) + [InlineData(-1.57079633f, -0.917152336f, CrossPlatformMachineEpsilon)] // value: -(pi / 2) + [InlineData(-1.44269504f, -0.894238946f, CrossPlatformMachineEpsilon)] // value: -(log2(e)) + [InlineData(-1.41421356f, -0.888385562f, CrossPlatformMachineEpsilon)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -0.810463806f, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -0.761594156f, CrossPlatformMachineEpsilon)] + [InlineData(-0.785398163f, -0.655794203f, CrossPlatformMachineEpsilon)] // value: -(pi / 4) + [InlineData(-0.707106781f, -0.608859365f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, -0.6f, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.636619772f, -0.562593600f, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.434294482f, -0.408904012f, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.318309886f, -0.307977913f, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0f, -0.0f, 0.0f)] + [InlineData(float.NaN, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 0.0f)] + [InlineData(0.318309886f, 0.307977913f, CrossPlatformMachineEpsilon)] // value: (1 / pi) + [InlineData(0.434294482f, 0.408904012f, CrossPlatformMachineEpsilon)] // value: (log10(e)) + [InlineData(0.636619772f, 0.562593600f, CrossPlatformMachineEpsilon)] // value: (2 / pi) + [InlineData(0.693147181f, 0.6f, CrossPlatformMachineEpsilon)] // value: (ln(2)) + [InlineData(0.707106781f, 0.608859365f, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2)) + [InlineData(0.785398163f, 0.655794203f, CrossPlatformMachineEpsilon)] // value: (pi / 4) + [InlineData(1.0f, 0.761594156f, CrossPlatformMachineEpsilon)] + [InlineData(1.12837917f, 0.810463806f, CrossPlatformMachineEpsilon)] // value: (2 / sqrt(pi)) + [InlineData(1.41421356f, 0.888385562f, CrossPlatformMachineEpsilon)] // value: (sqrt(2)) + [InlineData(1.44269504f, 0.894238946f, CrossPlatformMachineEpsilon)] // value: (log2(e)) + [InlineData(1.57079633f, 0.917152336f, CrossPlatformMachineEpsilon)] // value: (pi / 2) + [InlineData(2.30258509f, 0.980198020f, CrossPlatformMachineEpsilon)] // value: (ln(10)) + [InlineData(2.71828183f, 0.991328916f, CrossPlatformMachineEpsilon)] // value: (e) + [InlineData(3.14159265f, 0.996272076f, CrossPlatformMachineEpsilon)] // value: (pi) + [InlineData(float.PositiveInfinity, 1.0f, CrossPlatformMachineEpsilon * 10)] + public static void Tanh(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, MathF.Tanh(value), allowedVariance); + } + + [Fact] + public static void Truncate() + { + Assert.Equal(0.0f, MathF.Truncate(0.12345f)); + Assert.Equal(3.0f, MathF.Truncate(3.14159f)); + Assert.Equal(-3.0f, MathF.Truncate(-3.14159f)); + } + + public static IEnumerable Round_ToEven_TestData() + { + yield return new object[] { 1f, 1f }; + yield return new object[] { 0.5f, 0f }; + yield return new object[] { 1.5f, 2f }; + yield return new object[] { 2.5f, 2f }; + yield return new object[] { 3.5f, 4f }; + yield return new object[] { 0.49999997f, 0f }; + yield return new object[] { 1.5f, 2f }; + yield return new object[] { 2.5f, 2f }; + yield return new object[] { 3.5f, 4f }; + yield return new object[] { 4.5f, 4f }; + yield return new object[] { 3.1415927f, 3f }; + yield return new object[] { 2.7182817f, 3f }; + yield return new object[] { 1385.4557f, 1385f }; + yield return new object[] { 3423.4343f, 3423f }; + yield return new object[] { 535345.5f, 535346f }; + yield return new object[] { 535345.5f, 535346f }; + yield return new object[] { 535345.5f, 535346f }; + yield return new object[] { 535345.4f, 535345f }; + yield return new object[] { 535345.6f, 535346f }; + yield return new object[] { -2.7182817f, -3f }; + yield return new object[] { 10f, 10f }; + yield return new object[] { -10f, -10f }; + yield return new object[] { -0f, -0f }; + yield return new object[] { 0f, 0f }; + yield return new object[] { float.NaN, float.NaN }; + yield return new object[] { float.PositiveInfinity, float.PositiveInfinity }; + yield return new object[] { float.NegativeInfinity, float.NegativeInfinity }; + yield return new object[] { 3.4028235E+38f, 3.4028235E+38f }; + yield return new object[] { -3.4028235E+38f, -3.4028235E+38f }; + } + + [Theory] + [MemberData(nameof(Round_ToEven_TestData))] + public static void Round_ToEven_0(float value, float expected) + { + // Math.Round has special fast paths when MidpointRounding is a const + // Don't replace it with a variable + Assert.Equal(expected, MathF.Round(value, MidpointRounding.ToEven)); + Assert.Equal(expected, MathF.Round(value, 0, MidpointRounding.ToEven)); + } + + public static IEnumerable Round_AwayFromZero_TestData() + { + yield return new object[] { 1f, 1f }; + yield return new object[] { 0.5f, 1f }; + yield return new object[] { 1.5f, 2f }; + yield return new object[] { 2.5f, 3f }; + yield return new object[] { 3.5f, 4f }; + yield return new object[] { 0.49999997f, 0f }; + yield return new object[] { 1.5f, 2f }; + yield return new object[] { 2.5f, 3f }; + yield return new object[] { 3.5f, 4f }; + yield return new object[] { 4.5f, 5f }; + yield return new object[] { 3.1415927f, 3f }; + yield return new object[] { 2.7182817f, 3f }; + yield return new object[] { 1385.4557f, 1385f }; + yield return new object[] { 3423.4343f, 3423f }; + yield return new object[] { 535345.5f, 535346f }; + yield return new object[] { 535345.5f, 535346f }; + yield return new object[] { 535345.5f, 535346f }; + yield return new object[] { 535345.4f, 535345f }; + yield return new object[] { 535345.6f, 535346f }; + yield return new object[] { -2.7182817f, -3f }; + yield return new object[] { 10f, 10f }; + yield return new object[] { -10f, -10f }; + yield return new object[] { -0f, -0f }; + yield return new object[] { 0f, 0f }; + yield return new object[] { float.NaN, float.NaN }; + yield return new object[] { float.PositiveInfinity, float.PositiveInfinity }; + yield return new object[] { float.NegativeInfinity, float.NegativeInfinity }; + yield return new object[] { 3.4028235E+38f, 3.4028235E+38f }; + yield return new object[] { -3.4028235E+38f, -3.4028235E+38f }; + } + + [Theory] + [MemberData(nameof(Round_AwayFromZero_TestData))] + public static void Round_AwayFromZero_0(float value, float expected) + { + // Math.Round has special fast paths when MidpointRounding is a const + // Don't replace it with a variable + Assert.Equal(expected, MathF.Round(value, MidpointRounding.AwayFromZero)); + Assert.Equal(expected, MathF.Round(value, 0, MidpointRounding.AwayFromZero)); + } + } +} diff --git a/src/libraries/Microsoft.Bcl.Numerics/tests/Microsoft.Bcl.Numerics.Tests.csproj b/src/libraries/Microsoft.Bcl.Numerics/tests/Microsoft.Bcl.Numerics.Tests.csproj new file mode 100644 index 00000000000000..8f2abec46041a7 --- /dev/null +++ b/src/libraries/Microsoft.Bcl.Numerics/tests/Microsoft.Bcl.Numerics.Tests.csproj @@ -0,0 +1,15 @@ + + + + $(NetFrameworkMinimum);$(NetCoreAppCurrent) + + + + + + + + + + + diff --git a/src/libraries/System.Numerics.Tensors/Directory.Build.props b/src/libraries/System.Numerics.Tensors/Directory.Build.props deleted file mode 100644 index 36078bccbf7aa8..00000000000000 --- a/src/libraries/System.Numerics.Tensors/Directory.Build.props +++ /dev/null @@ -1,8 +0,0 @@ - - - - - true - false - - \ No newline at end of file diff --git a/src/libraries/System.Numerics.Tensors/README.md b/src/libraries/System.Numerics.Tensors/README.md index 026563de81306d..6190da60e77c51 100644 --- a/src/libraries/System.Numerics.Tensors/README.md +++ b/src/libraries/System.Numerics.Tensors/README.md @@ -1,2 +1,3 @@ # System.Numerics.Tensors -This library has not been shipped publicly and is not accepting contributions at this time. \ No newline at end of file + +Provides APIs for performing primitive operations over tensors represented by spans of memory. diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.cs b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.cs index 3161a4c7e780ce..50eaa00160e5cb 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.cs +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.cs @@ -6,151 +6,47 @@ namespace System.Numerics.Tensors { - public static partial class ArrayTensorExtensions + public static partial class TensorPrimitives { - public static System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor(this System.Array array, bool reverseStride = false) { throw null; } - public static System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor(this T[,,] array, bool reverseStride = false) { throw null; } - public static System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor(this T[,] array, bool reverseStride = false) { throw null; } - public static System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor(this T[] array) { throw null; } - public static System.Numerics.Tensors.SparseTensor ToSparseTensor(this System.Array array, bool reverseStride = false) { throw null; } - public static System.Numerics.Tensors.SparseTensor ToSparseTensor(this T[,,] array, bool reverseStride = false) { throw null; } - public static System.Numerics.Tensors.SparseTensor ToSparseTensor(this T[,] array, bool reverseStride = false) { throw null; } - public static System.Numerics.Tensors.SparseTensor ToSparseTensor(this T[] array) { throw null; } - public static System.Numerics.Tensors.DenseTensor ToTensor(this System.Array array, bool reverseStride = false) { throw null; } - public static System.Numerics.Tensors.DenseTensor ToTensor(this T[,,] array, bool reverseStride = false) { throw null; } - public static System.Numerics.Tensors.DenseTensor ToTensor(this T[,] array, bool reverseStride = false) { throw null; } - public static System.Numerics.Tensors.DenseTensor ToTensor(this T[] array) { throw null; } - } - public partial class CompressedSparseTensor : System.Numerics.Tensors.Tensor - { - public CompressedSparseTensor(System.Memory values, System.Memory compressedCounts, System.Memory indices, int nonZeroCount, System.ReadOnlySpan dimensions, bool reverseStride = false) : base (default(System.Array), default(bool)) { } - public CompressedSparseTensor(System.ReadOnlySpan dimensions, bool reverseStride = false) : base (default(System.Array), default(bool)) { } - public CompressedSparseTensor(System.ReadOnlySpan dimensions, int capacity, bool reverseStride = false) : base (default(System.Array), default(bool)) { } - public int Capacity { get { throw null; } } - public System.Memory CompressedCounts { get { throw null; } } - public System.Memory Indices { get { throw null; } } - public override T this[System.ReadOnlySpan indices] { get { throw null; } set { } } - public int NonZeroCount { get { throw null; } } - public System.Memory Values { get { throw null; } } - public override System.Numerics.Tensors.Tensor Clone() { throw null; } - public override System.Numerics.Tensors.Tensor CloneEmpty(System.ReadOnlySpan dimensions) { throw null; } - public override T GetValue(int index) { throw null; } - public override System.Numerics.Tensors.Tensor Reshape(System.ReadOnlySpan dimensions) { throw null; } - public override void SetValue(int index, T value) { } - public override System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor() { throw null; } - public override System.Numerics.Tensors.DenseTensor ToDenseTensor() { throw null; } - public override System.Numerics.Tensors.SparseTensor ToSparseTensor() { throw null; } - } - public partial class DenseTensor : System.Numerics.Tensors.Tensor - { - public DenseTensor(int length) : base (default(System.Array), default(bool)) { } - public DenseTensor(System.Memory memory, System.ReadOnlySpan dimensions, bool reverseStride = false) : base (default(System.Array), default(bool)) { } - public DenseTensor(System.ReadOnlySpan dimensions, bool reverseStride = false) : base (default(System.Array), default(bool)) { } - public System.Memory Buffer { get { throw null; } } - public override System.Numerics.Tensors.Tensor Clone() { throw null; } - public override System.Numerics.Tensors.Tensor CloneEmpty(System.ReadOnlySpan dimensions) { throw null; } - protected override void CopyTo(T[] array, int arrayIndex) { } - public override T GetValue(int index) { throw null; } - protected override int IndexOf(T item) { throw null; } - public override System.Numerics.Tensors.Tensor Reshape(System.ReadOnlySpan dimensions) { throw null; } - public override void SetValue(int index, T value) { } - } - public partial class SparseTensor : System.Numerics.Tensors.Tensor - { - public SparseTensor(System.ReadOnlySpan dimensions, bool reverseStride = false, int capacity = 0) : base (default(System.Array), default(bool)) { } - public int NonZeroCount { get { throw null; } } - public override System.Numerics.Tensors.Tensor Clone() { throw null; } - public override System.Numerics.Tensors.Tensor CloneEmpty(System.ReadOnlySpan dimensions) { throw null; } - public override T GetValue(int index) { throw null; } - public override System.Numerics.Tensors.Tensor Reshape(System.ReadOnlySpan dimensions) { throw null; } - public override void SetValue(int index, T value) { } - public override System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor() { throw null; } - public override System.Numerics.Tensors.DenseTensor ToDenseTensor() { throw null; } - public override System.Numerics.Tensors.SparseTensor ToSparseTensor() { throw null; } - } - public static partial class Tensor - { - public static System.Numerics.Tensors.Tensor CreateFromDiagonal(System.Numerics.Tensors.Tensor diagonal) { throw null; } - public static System.Numerics.Tensors.Tensor CreateFromDiagonal(System.Numerics.Tensors.Tensor diagonal, int offset) { throw null; } - public static System.Numerics.Tensors.Tensor CreateIdentity(int size) { throw null; } - public static System.Numerics.Tensors.Tensor CreateIdentity(int size, bool columMajor) { throw null; } - public static System.Numerics.Tensors.Tensor CreateIdentity(int size, bool columMajor, T oneValue) { throw null; } - } - public abstract partial class Tensor : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable - { - protected Tensor(System.Array fromArray, bool reverseStride) { } - protected Tensor(int length) { } - protected Tensor(System.ReadOnlySpan dimensions, bool reverseStride) { } - public System.ReadOnlySpan Dimensions { get { throw null; } } - public bool IsFixedSize { get { throw null; } } - public bool IsReadOnly { get { throw null; } } - public bool IsReversedStride { get { throw null; } } - public virtual T this[params int[] indices] { get { throw null; } set { } } - public virtual T this[System.ReadOnlySpan indices] { get { throw null; } set { } } - public long Length { get { throw null; } } - public int Rank { get { throw null; } } - public System.ReadOnlySpan Strides { get { throw null; } } - int System.Collections.Generic.ICollection.Count { get { throw null; } } - T System.Collections.Generic.IList.this[int index] { get { throw null; } set { } } - int System.Collections.Generic.IReadOnlyCollection.Count { get { throw null; } } - T System.Collections.Generic.IReadOnlyList.this[int index] { get { throw null; } } - int System.Collections.ICollection.Count { get { throw null; } } - bool System.Collections.ICollection.IsSynchronized { get { throw null; } } - object System.Collections.ICollection.SyncRoot { get { throw null; } } - object? System.Collections.IList.this[int index] { get { throw null; } set { } } - public abstract System.Numerics.Tensors.Tensor Clone(); - public virtual System.Numerics.Tensors.Tensor CloneEmpty() { throw null; } - public virtual System.Numerics.Tensors.Tensor CloneEmpty(System.ReadOnlySpan dimensions) { throw null; } - public virtual System.Numerics.Tensors.Tensor CloneEmpty() { throw null; } - public abstract System.Numerics.Tensors.Tensor CloneEmpty(System.ReadOnlySpan dimensions); - public static int Compare(System.Numerics.Tensors.Tensor left, System.Numerics.Tensors.Tensor right) { throw null; } - protected virtual bool Contains(T item) { throw null; } - protected virtual void CopyTo(T[] array, int arrayIndex) { } - public static bool Equals(System.Numerics.Tensors.Tensor left, System.Numerics.Tensors.Tensor right) { throw null; } - public virtual void Fill(T value) { } - public string GetArrayString(bool includeWhitespace = true) { throw null; } - public System.Numerics.Tensors.Tensor GetDiagonal() { throw null; } - public System.Numerics.Tensors.Tensor GetDiagonal(int offset) { throw null; } - public System.Numerics.Tensors.Tensor GetTriangle() { throw null; } - public System.Numerics.Tensors.Tensor GetTriangle(int offset) { throw null; } - public System.Numerics.Tensors.Tensor GetUpperTriangle() { throw null; } - public System.Numerics.Tensors.Tensor GetUpperTriangle(int offset) { throw null; } - public abstract T GetValue(int index); - protected virtual int IndexOf(T item) { throw null; } - public abstract System.Numerics.Tensors.Tensor Reshape(System.ReadOnlySpan dimensions); - public abstract void SetValue(int index, T value); - public struct Enumerator : System.Collections.Generic.IEnumerator - { - public T Current { get; private set; } - object? System.Collections.IEnumerator.Current => throw null; - public bool MoveNext() => throw null; - public void Reset() { } - public void Dispose() { } - } - public Enumerator GetEnumerator() => throw null; - void System.Collections.Generic.ICollection.Add(T item) { } - void System.Collections.Generic.ICollection.Clear() { } - bool System.Collections.Generic.ICollection.Contains(T item) { throw null; } - void System.Collections.Generic.ICollection.CopyTo(T[] array, int arrayIndex) { } - bool System.Collections.Generic.ICollection.Remove(T item) { throw null; } - System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } - int System.Collections.Generic.IList.IndexOf(T item) { throw null; } - void System.Collections.Generic.IList.Insert(int index, T item) { } - void System.Collections.Generic.IList.RemoveAt(int index) { } - void System.Collections.ICollection.CopyTo(System.Array array, int index) { } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - int System.Collections.IList.Add(object? value) { throw null; } - void System.Collections.IList.Clear() { } - bool System.Collections.IList.Contains(object? value) { throw null; } - int System.Collections.IList.IndexOf(object? value) { throw null; } - void System.Collections.IList.Insert(int index, object? value) { } - void System.Collections.IList.Remove(object? value) { } - void System.Collections.IList.RemoveAt(int index) { } - int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } - int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - public virtual System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor() { throw null; } - public virtual System.Numerics.Tensors.DenseTensor ToDenseTensor() { throw null; } - public virtual System.Numerics.Tensors.SparseTensor ToSparseTensor() { throw null; } + public static void Add(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { } + public static void Add(System.ReadOnlySpan x, float y, System.Span destination) { } + public static void AddMultiply(System.ReadOnlySpan x, System.ReadOnlySpan y, System.ReadOnlySpan multiplier, System.Span destination) { } + public static void AddMultiply(System.ReadOnlySpan x, System.ReadOnlySpan y, float multiplier, System.Span destination) { } + public static void AddMultiply(System.ReadOnlySpan x, float y, System.ReadOnlySpan multiplier, System.Span destination) { } + public static void Cosh(System.ReadOnlySpan x, System.Span destination) { } + public static float CosineSimilarity(System.ReadOnlySpan x, System.ReadOnlySpan y) { throw null; } + public static float Distance(System.ReadOnlySpan x, System.ReadOnlySpan y) { throw null; } + public static void Divide(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { } + public static void Divide(System.ReadOnlySpan x, float y, System.Span destination) { } + public static float Dot(System.ReadOnlySpan x, System.ReadOnlySpan y) { throw null; } + public static void Exp(System.ReadOnlySpan x, System.Span destination) { } + public static int IndexOfMax(System.ReadOnlySpan x) { throw null; } + public static int IndexOfMaxMagnitude(System.ReadOnlySpan x) { throw null; } + public static int IndexOfMin(System.ReadOnlySpan x) { throw null; } + public static int IndexOfMinMagnitude(System.ReadOnlySpan x) { throw null; } + public static float L2Normalize(System.ReadOnlySpan x) { throw null; } + public static void Log(System.ReadOnlySpan x, System.Span destination) { } + public static float Max(System.ReadOnlySpan x) { throw null; } + public static float MaxMagnitude(System.ReadOnlySpan x) { throw null; } + public static float Min(System.ReadOnlySpan x) { throw null; } + public static float MinMagnitude(System.ReadOnlySpan x) { throw null; } + public static void Multiply(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { } + public static void Multiply(System.ReadOnlySpan x, float y, System.Span destination) { } + public static void MultiplyAdd(System.ReadOnlySpan x, System.ReadOnlySpan y, System.ReadOnlySpan addend, System.Span destination) { } + public static void MultiplyAdd(System.ReadOnlySpan x, System.ReadOnlySpan y, float addend, System.Span destination) { } + public static void MultiplyAdd(System.ReadOnlySpan x, float y, System.ReadOnlySpan addend, System.Span destination) { } + public static void Negate(System.ReadOnlySpan x, System.Span destination) { } + public static float Product(System.ReadOnlySpan x) { throw null; } + public static float ProductOfDifferences(System.ReadOnlySpan x, System.ReadOnlySpan y) { throw null; } + public static float ProductOfSums(System.ReadOnlySpan x, System.ReadOnlySpan y) { throw null; } + public static void Sigmoid(System.ReadOnlySpan x, System.Span destination) { } + public static void Sinh(System.ReadOnlySpan x, System.Span destination) { } + public static void SoftMax(System.ReadOnlySpan x, System.Span destination) { } + public static void Subtract(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { } + public static void Subtract(System.ReadOnlySpan x, float y, System.Span destination) { } + public static float Sum(System.ReadOnlySpan x) { throw null; } + public static float SumOfMagnitudes(System.ReadOnlySpan x) { throw null; } + public static float SumOfSquares(System.ReadOnlySpan x) { throw null; } + public static void Tanh(System.ReadOnlySpan x, System.Span destination) { } } } diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj index cabfe50e267cfb..89bdef6ea38ed9 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj @@ -1,4 +1,5 @@ + $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) @@ -7,7 +8,12 @@ + + + + + \ No newline at end of file diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs new file mode 100644 index 00000000000000..1cde4351546b26 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// ------------------------------------------------------------------------------ +// Changes to this file must follow the https://aka.ms/api-review process. +// ------------------------------------------------------------------------------ + +namespace System.Numerics.Tensors +{ + public static partial class TensorPrimitives + { + public static void ConvertToHalf(System.ReadOnlySpan source, System.Span destination) { throw null; } + public static void ConvertToSingle(System.ReadOnlySpan source, System.Span destination) { throw null; } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/Properties/InternalsVisibleTo.cs b/src/libraries/System.Numerics.Tensors/src/Properties/InternalsVisibleTo.cs deleted file mode 100644 index 2b044e474d570a..00000000000000 --- a/src/libraries/System.Numerics.Tensors/src/Properties/InternalsVisibleTo.cs +++ /dev/null @@ -1,6 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("System.Numerics.Tensors.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004b86c4cb78549b34bab61a3b1800e23bfeb5b3ec390074041536a7e3cbd97f5f04cf0f857155a8928eaa29ebfd11cfbbad3ba70efea7bda3226c6a8d370a4cd303f714486b6ebc225985a638471e6ef571cc92a4613c00b8fa65d61ccee0cbe5f36330c9a01f4183559f1bef24cc2917c6d913e3a541333a1d05d9bed22b38cb")] diff --git a/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx b/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx index 57f792dde51dc2..45f0d8fa17893a 100644 --- a/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx +++ b/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx @@ -117,52 +117,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Array must contain elements. + + Destination is too short. - - Cannot compare {0} to {1}. + + Input span arguments must not be empty. - - Cannot compare {0} to {1} with different dimension {2}, {3} != {4}. - - - Cannot compare {0} with different dimension {1}, {2} != {3}. - - - Cannot compare {0} with Rank {1} to {2} with Rank {3}. - - - Cannot compute diagonal of {0} with Rank less than 2. - - - Cannot compute diagonal with offset {0}. - - - Tensor {0} must have at least one dimension. - - - Cannot compute triangle of {0} with Rank less than 2. - - - Cannot reshape array due to mismatch in lengths, currently {0} would become {1}. - - - Dimensions must be positive and non-zero. - - - Dimensions must contain elements. - - - Length of {0} ({1}) must match product of {2} ({3}). - - - The number of elements in the Tensor is greater than the available space from index to the end of the destination array. - - - Only single dimensional arrays are supported for the requested action. - - - The value "{0}" is not of type "{1}" and cannot be used in this generic collection. + + Input span arguments must all have the same length. \ No newline at end of file diff --git a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj index 521f8055a4fa61..097fa244ad4913 100644 --- a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj @@ -1,30 +1,36 @@ + $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true - - $(NoWarn);1591 true - Tensor class which represents and extends multi-dimensional arrays. - -Commonly Used Types: -System.Numerics.Tensors.Tensor<T> -System.Numerics.Tensors.CompressedSparseTensor<T> -System.Numerics.Tensors.DenseTensor<T> -System.Numerics.Tensors.SparseTensor<T> + Provides support for operating over tensors. + + true - - - - - - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/ArrayTensorExtensions.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/ArrayTensorExtensions.cs deleted file mode 100644 index 05e12a62c990e4..00000000000000 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/ArrayTensorExtensions.cs +++ /dev/null @@ -1,149 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Numerics.Tensors -{ - public static class ArrayTensorExtensions - { - /// - /// Creates a copy of this single-dimensional array as a DenseTensor<T> - /// - /// Type contained in the array to copy to the DenseTensor<T>. - /// The array to create a DenseTensor<T> from. - /// A 1-dimensional DenseTensor<T> with the same length and content as . - public static DenseTensor ToTensor(this T[] array) - { - return new DenseTensor(array); - } - - /// - /// Creates a copy of this two-dimensional array as a DenseTensor<T> - /// - /// Type contained in the array to copy to the DenseTensor<T>. - /// The array to create a DenseTensor<T> from. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): row-major. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): column-major. - /// A 2-dimensional DenseTensor<T> with the same dimensions and content as . - public static DenseTensor ToTensor(this T[,] array, bool reverseStride = false) - { - return new DenseTensor(array, reverseStride); - } - - /// - /// Creates a copy of this three-dimensional array as a DenseTensor<T> - /// - /// Type contained in the array to copy to the DenseTensor<T>. - /// The array to create a DenseTensor<T> from. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - /// A 3-dimensional DenseTensor<T> with the same dimensions and content as . - public static DenseTensor ToTensor(this T[,,] array, bool reverseStride = false) - { - return new DenseTensor(array, reverseStride); - } - - /// - /// Creates a copy of this n-dimensional array as a DenseTensor<T> - /// - /// Type contained in the array to copy to the DenseTensor<T>. - /// The array to create a DenseTensor<T> from. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - /// A n-dimensional DenseTensor<T> with the same dimensions and content as . - public static DenseTensor ToTensor(this Array array, bool reverseStride = false) - { - return new DenseTensor(array, reverseStride); - } - - /// - /// Creates a copy of this single-dimensional array as a SparseTensor<T> - /// - /// Type contained in the array to copy to the SparseTensor<T>. - /// The array to create a SparseTensor<T> from. - /// A 1-dimensional SparseTensor<T> with the same length and content as . - public static SparseTensor ToSparseTensor(this T[] array) - { - return new SparseTensor(array); - } - - /// - /// Creates a copy of this two-dimensional array as a SparseTensor<T> - /// - /// Type contained in the array to copy to the SparseTensor<T>. - /// The array to create a SparseTensor<T> from. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): row-major. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): column-major. - /// A 2-dimensional SparseTensor<T> with the same dimensions and content as . - public static SparseTensor ToSparseTensor(this T[,] array, bool reverseStride = false) - { - return new SparseTensor(array, reverseStride); - } - - /// - /// Creates a copy of this three-dimensional array as a SparseTensor<T> - /// - /// Type contained in the array to copy to the SparseTensor<T>. - /// The array to create a SparseTensor<T> from. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - /// A 3-dimensional SparseTensor<T> with the same dimensions and content as . - public static SparseTensor ToSparseTensor(this T[,,] array, bool reverseStride = false) - { - return new SparseTensor(array, reverseStride); - } - - /// - /// Creates a copy of this n-dimensional array as a SparseTensor<T> - /// - /// Type contained in the array to copy to the SparseTensor<T>. - /// The array to create a SparseTensor<T> from. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - /// A n-dimensional SparseTensor<T> with the same dimensions and content as . - public static SparseTensor ToSparseTensor(this Array array, bool reverseStride = false) - { - return new SparseTensor(array, reverseStride); - } - - /// - /// Creates a copy of this single-dimensional array as a CompressedSparseTensor<T> - /// - /// Type contained in the array to copy to the CompressedSparseTensor<T>. - /// The array to create a CompressedSparseTensor<T> from. - /// A 1-dimensional CompressedSparseTensor<T> with the same length and content as . - public static CompressedSparseTensor ToCompressedSparseTensor(this T[] array) - { - return new CompressedSparseTensor(array); - } - - /// - /// Creates a copy of this two-dimensional array as a CompressedSparseTensor<T> - /// - /// Type contained in the array to copy to the CompressedSparseTensor<T>. - /// The array to create a CompressedSparseTensor<T> from. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): row-major. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): column-major. - /// A 2-dimensional CompressedSparseTensor<T> with the same dimensions and content as . - public static CompressedSparseTensor ToCompressedSparseTensor(this T[,] array, bool reverseStride = false) - { - return new CompressedSparseTensor(array, reverseStride); - } - - /// - /// Creates a copy of this three-dimensional array as a CompressedSparseTensor<T> - /// - /// Type contained in the array to copy to the CompressedSparseTensor<T>. - /// The array to create a CompressedSparseTensor<T> from. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - /// A 3-dimensional CompressedSparseTensor<T> with the same dimensions and content as . - public static CompressedSparseTensor ToCompressedSparseTensor(this T[,,] array, bool reverseStride = false) - { - return new CompressedSparseTensor(array, reverseStride); - } - - /// - /// Creates a copy of this n-dimensional array as a CompressedSparseTensor<T> - /// - /// Type contained in the array to copy to the CompressedSparseTensor<T>. - /// The array to create a CompressedSparseTensor<T> from. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - /// A n-dimensional CompressedSparseTensor<T> with the same dimensions and content as . - public static CompressedSparseTensor ToCompressedSparseTensor(this Array array, bool reverseStride = false) - { - return new CompressedSparseTensor(array, reverseStride); - } - } -} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/ArrayUtilities.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/ArrayUtilities.cs deleted file mode 100644 index 97152090dfea06..00000000000000 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/ArrayUtilities.cs +++ /dev/null @@ -1,216 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; - -namespace System.Numerics.Tensors -{ - internal static class ArrayUtilities - { - public const int StackallocMax = 16; - - public static long GetProduct(ReadOnlySpan dimensions, int startIndex = 0) - { - if (dimensions.Length == 0) - { - return 0; - } - - long product = 1; - for (int i = startIndex; i < dimensions.Length; i++) - { - if (dimensions[i] < 0) - { - throw new ArgumentOutOfRangeException($"{nameof(dimensions)}[{i}]"); - } - - // we use a long which should be much larger than is ever used here, - // but still force checked - checked - { - product *= dimensions[i]; - } - } - - return product; - } - - public static bool IsAscending(ReadOnlySpan values) - { - for (int i = 1; i < values.Length; i++) - { - if (values[i] < values[i - 1]) - { - return false; - } - } - - return true; - } - - public static bool IsDescending(ReadOnlySpan values) - { - for (int i = 1; i < values.Length; i++) - { - if (values[i] > values[i - 1]) - { - return false; - } - } - - return true; - } - - /// - /// Gets the set of strides that can be used to calculate the offset of n-dimensions in a 1-dimensional layout - /// - /// - /// - /// - public static int[] GetStrides(ReadOnlySpan dimensions, bool reverseStride = false) - { - int[] strides = new int[dimensions.Length]; - - int stride = 1; - if (reverseStride) - { - for (int i = 0; i < strides.Length; i++) - { - strides[i] = stride; - stride *= dimensions[i]; - } - } - else - { - for (int i = strides.Length - 1; i >= 0; i--) - { - strides[i] = stride; - stride *= dimensions[i]; - } - } - - return strides; - } - - public static void SplitStrides(int[] strides, int[] splitAxes, int[] newStrides, int stridesOffset, int[] splitStrides, int splitStridesOffset) - { - int newStrideIndex = 0; - for (int i = 0; i < strides.Length; i++) - { - int stride = strides[i]; - bool isSplit = false; - for (int j = 0; j < splitAxes.Length; j++) - { - if (splitAxes[j] == i) - { - splitStrides[splitStridesOffset + j] = stride; - isSplit = true; - break; - } - } - - if (!isSplit) - { - newStrides[stridesOffset + newStrideIndex++] = stride; - } - } - } - - /// - /// Calculates the 1-d index for n-d indices in layout specified by strides. - /// - /// - /// - /// - /// - public static int GetIndex(int[] strides, ReadOnlySpan indices, int startFromDimension = 0) - { - Debug.Assert(strides.Length == indices.Length); - - int index = 0; - for (int i = startFromDimension; i < indices.Length; i++) - { - index += strides[i] * indices[i]; - } - - return index; - } - - /// - /// Calculates the n-d indices from the 1-d index in a layout specified by strides - /// - /// - /// - /// - /// - /// - public static void GetIndices(ReadOnlySpan strides, bool reverseStride, int index, int[] indices, int startFromDimension = 0) - { - Debug.Assert(reverseStride ? IsAscending(strides) : IsDescending(strides), "Index decomposition requires ordered strides"); - Debug.Assert(strides.Length == indices.Length); - - int remainder = index; - for (int i = startFromDimension; i < strides.Length; i++) - { - // reverse the index for reverseStride so that we divide by largest stride first - var nIndex = reverseStride ? strides.Length - 1 - i : i; - - var stride = strides[nIndex]; - indices[nIndex] = remainder / stride; - remainder %= stride; - } - } - - /// - /// Calculates the n-d indices from the 1-d index in a layout specified by strides - /// - /// - /// - /// - /// - /// - public static void GetIndices(ReadOnlySpan strides, bool reverseStride, int index, Span indices, int startFromDimension = 0) - { - Debug.Assert(reverseStride ? IsAscending(strides) : IsDescending(strides), "Index decomposition requires ordered strides"); - Debug.Assert(strides.Length == indices.Length); - - int remainder = index; - for (int i = startFromDimension; i < strides.Length; i++) - { - // reverse the index for reverseStride so that we divide by largest stride first - var nIndex = reverseStride ? strides.Length - 1 - i : i; - - var stride = strides[nIndex]; - indices[nIndex] = remainder / stride; - remainder %= stride; - } - } - - /// - /// Takes an 1-d index over n-d sourceStrides and recalculates it assuming same n-d coordinates over a different n-d strides - /// - public static int TransformIndexByStrides(int index, int[] sourceStrides, bool sourceReverseStride, int[] transformStrides) - { - Debug.Assert(index >= 0); - Debug.Assert(sourceReverseStride ? IsAscending(sourceStrides) : IsDescending(sourceStrides), "Index decomposition requires ordered strides"); - Debug.Assert(sourceStrides.Length == transformStrides.Length); - - int transformIndex = 0; - int remainder = index; - - for (int i = 0; i < sourceStrides.Length; i++) - { - // reverse the index for reverseStride so that we divide by largest stride first - var nIndex = sourceReverseStride ? sourceStrides.Length - 1 - i : i; - - var sourceStride = sourceStrides[nIndex]; - var transformStride = transformStrides[nIndex]; - - transformIndex += transformStride * (remainder / sourceStride); - remainder %= sourceStride; - } - - return transformIndex; - } - } -} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/CompressedSparseTensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/CompressedSparseTensor.cs deleted file mode 100644 index b41915acddd5ab..00000000000000 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/CompressedSparseTensor.cs +++ /dev/null @@ -1,517 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Linq; - -namespace System.Numerics.Tensors -{ - /// - /// Represents a tensor using compressed sparse format - /// For a two dimensional tensor this is referred to as compressed sparse row (CSR, CRS, Yale), compressed sparse column (CSC, CCS) - /// - /// In this format, data that is in the same value for the compressed dimension has locality - /// - /// In standard layout of a dense tensor, data with the same value for first dimensions has locality. - /// As such we'll use reverseStride = false (default) to mean that the first dimension is compressed (CSR) - /// and reverseStride = true to mean that the last dimension is compressed (CSC) - /// - /// - /// - public class CompressedSparseTensor : Tensor - { - private Memory values; - private readonly Memory compressedCounts; - private Memory indices; - - private int nonZeroCount; - - private readonly int[] nonCompressedStrides; - private readonly int compressedDimension; - - private const int defaultCapacity = 64; - - /// - /// Constructs a new CompressedSparseTensor of the specified dimensions and stride ordering. - /// - /// An span of integers that represent the size of each dimension of the CompressedSparseTensor to create. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - public CompressedSparseTensor(ReadOnlySpan dimensions, bool reverseStride = false) : this(dimensions, defaultCapacity, reverseStride) - { } - - /// - /// Constructs a new CompressedSparseTensor of the specified dimensions, initial capacity, and stride ordering. - /// - /// An span of integers that represent the size of each dimension of the CompressedSparseTensor to create. - /// The number of non-zero values this tensor can store without resizing. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - public CompressedSparseTensor(ReadOnlySpan dimensions, int capacity, bool reverseStride = false) : base(dimensions, reverseStride) - { - nonZeroCount = 0; - compressedDimension = reverseStride ? Rank - 1 : 0; - nonCompressedStrides = (int[])strides.Clone(); - nonCompressedStrides[compressedDimension] = 0; - var compressedDimensionLength = dimensions[compressedDimension]; - compressedCounts = new int[compressedDimensionLength + 1]; - values = new T[capacity]; - indices = new int[capacity]; - } - - /// - /// Constructs a new CompressedSparseTensor of the specified dimensions, wrapping existing backing memory for the contents. - /// Growing this CompressedSparseTensor will re-allocate the backing memory. - /// - /// Memory storing non-zero values to construct this tensor with. - /// Memory storing the counts of non-zero elements at each index of the compressed dimension. - /// Memory storing the linearized index (excluding the compressed dimension) of non-zero elements. - /// The number of valid entries (eg: non-zero values) in and . - /// An span of integers that represent the size of each dimension of the CompressedSparseTensor to create. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - public CompressedSparseTensor(Memory values, Memory compressedCounts, Memory indices, int nonZeroCount, ReadOnlySpan dimensions, bool reverseStride = false) : base(dimensions, reverseStride) - { - compressedDimension = reverseStride ? Rank - 1 : 0; - nonCompressedStrides = (int[])strides.Clone(); - nonCompressedStrides[compressedDimension] = 0; - this.values = values; - this.compressedCounts = compressedCounts; - this.indices = indices; - this.nonZeroCount = nonZeroCount; - } - - internal CompressedSparseTensor(Array fromArray, bool reverseStride = false) : base(fromArray, reverseStride) - { - nonZeroCount = 0; - compressedDimension = reverseStride ? Rank - 1 : 0; - nonCompressedStrides = (int[])strides.Clone(); - nonCompressedStrides[compressedDimension] = 0; - var compressedDimensionLength = dimensions[compressedDimension]; - compressedCounts = new int[compressedDimensionLength + 1]; - - int index = 0; - if (reverseStride) - { - // Array is always row-major - var sourceStrides = ArrayUtilities.GetStrides(dimensions); - - foreach (T item in fromArray) - { - if (!item!.Equals(Zero)) - { - var destIndex = ArrayUtilities.TransformIndexByStrides(index, sourceStrides, false, strides); - var compressedIndex = destIndex / strides[compressedDimension]; - var nonCompressedIndex = destIndex % strides[compressedDimension]; - - SetAt(item, compressedIndex, nonCompressedIndex); - } - - index++; - } - } - else - { - foreach (T item in fromArray) - { - if (!item!.Equals(Zero)) - { - var compressedIndex = index / strides[compressedDimension]; - var nonCompressedIndex = index % strides[compressedDimension]; - - SetAt(item, compressedIndex, nonCompressedIndex); - } - - index++; - } - } - } - - /// - /// Obtains the value at the specified indices - /// - /// A span of integers that represent the indices specifying the position of the element to get. - /// The value at the specified position in this Tensor. - public override T this[ReadOnlySpan indices] - { - get - { - var compressedIndex = indices[compressedDimension]; - var nonCompressedIndex = ArrayUtilities.GetIndex(nonCompressedStrides, indices); - - - if (TryFindIndex(compressedIndex, nonCompressedIndex, out int valueIndex)) - { - return values.Span[valueIndex]; - } - - return Zero; - } - - set - { - var compressedIndex = indices[compressedDimension]; - var nonCompressedIndex = ArrayUtilities.GetIndex(nonCompressedStrides, indices); - - SetAt(value, compressedIndex, nonCompressedIndex); - } - } - - /// - /// Gets the value at the specified index, where index is lineraized as a dot product between indices and strides. - /// - /// An integer index computed as a dot-product of indices. - /// The value at the specified position in this Tensor. - public override T GetValue(int index) - { - var compressedDimensionStride = strides[compressedDimension]; - Debug.Assert(compressedDimensionStride == strides.Max()); - - var compressedIndex = index / compressedDimensionStride; - var nonCompressedIndex = index % compressedDimensionStride; - - - if (TryFindIndex(compressedIndex, nonCompressedIndex, out int valueIndex)) - { - return values.Span[valueIndex]; - } - - return Zero; - } - - /// - /// Sets the value at the specified index, where index is a linearized version of n-dimension indices using strides. - /// - /// An integer index computed as a dot-product of indices. - /// The new value to set at the specified position in this Tensor. - public override void SetValue(int index, T value) - { - var compressedDimensionStride = strides[compressedDimension]; - Debug.Assert(compressedDimensionStride == strides.Max()); - - var compressedIndex = index / compressedDimensionStride; - var nonCompressedIndex = index % compressedDimensionStride; - - SetAt(value, compressedIndex, nonCompressedIndex); - - } - - /// - /// Gets the number of non-zero values this tensor can store without resizing. - /// - public int Capacity => values.Length; - - /// - /// Get's the number on non-zero values currently being stored in this tensor. - /// - public int NonZeroCount => nonZeroCount; - - /// - /// Memory storing non-zero values. - /// - public Memory Values => values; - - /// - /// Memory storing the counts of non-zero elements at each index of the compressed dimension. - /// - public Memory CompressedCounts => compressedCounts; - - /// - /// Memory storing the linearized index (excluding the compressed dimension) of non-zero elements. - /// - public Memory Indices => indices; - - private void EnsureCapacity(int min, int allocateIndex = -1) - { - if (values.Length < min) - { - var newCapacity = values.Length == 0 ? defaultCapacity : values.Length * 2; - - if (newCapacity > Length) - { - newCapacity = (int)Length; - } - - if (newCapacity < min) - { - newCapacity = min; - } - - Memory newValues = new T[newCapacity]; - Memory newIndices = new int[newCapacity]; - - if (nonZeroCount > 0) - { - if (allocateIndex == -1) - { - var valuesSpan = values.Span.Slice(0, nonZeroCount); - var indicesSpan = indices.Span.Slice(0, nonZeroCount); - - valuesSpan.CopyTo(newValues.Span); - indicesSpan.CopyTo(newIndices.Span); - } - else - { - Debug.Assert(allocateIndex <= nonZeroCount); - // leave a gap at allocateIndex - - // copy range before allocateIndex - if (allocateIndex > 0) - { - var valuesSpan = values.Span.Slice(0, allocateIndex); - var indicesSpan = indices.Span.Slice(0, allocateIndex); - - valuesSpan.CopyTo(newValues.Span); - indicesSpan.CopyTo(newIndices.Span); - } - - if (allocateIndex < nonZeroCount) - { - var valuesSpan = values.Span.Slice(allocateIndex, nonZeroCount - allocateIndex); - var indicesSpan = indices.Span.Slice(allocateIndex, nonZeroCount - allocateIndex); - - var newValuesSpan = newValues.Span.Slice(allocateIndex + 1, nonZeroCount - allocateIndex); - var newIndicesSpan = newIndices.Span.Slice(allocateIndex + 1, nonZeroCount - allocateIndex); - - valuesSpan.CopyTo(newValuesSpan); - indicesSpan.CopyTo(newIndicesSpan); - } - } - } - - values = newValues; - indices = newIndices; - } - } - - private void InsertAt(int valueIndex, T value, int compressedIndex, int nonCompressedIndex) - { - Debug.Assert(valueIndex <= nonZeroCount); - Debug.Assert(compressedIndex < compressedCounts.Length - 1); - - if (values.Length <= valueIndex) - { - // allocate a new array, leaving a gap - EnsureCapacity(valueIndex + 1, valueIndex); - } - else if (nonZeroCount != valueIndex) - { - // shift values to make a gap - values.Span.Slice(valueIndex, nonZeroCount - valueIndex).CopyTo(values.Span.Slice(valueIndex + 1)); - indices.Span.Slice(valueIndex, nonZeroCount - valueIndex).CopyTo(indices.Span.Slice(valueIndex + 1)); - } - - values.Span[valueIndex] = value; - indices.Span[valueIndex] = nonCompressedIndex; - - var compressedCountsSpan = compressedCounts.Span.Slice(compressedIndex + 1); - for (int i = 0; i < compressedCountsSpan.Length; i++) - { - compressedCountsSpan[i]++; - } - nonZeroCount++; - } - - private void RemoveAt(int valueIndex, int compressedIndex) - { - Debug.Assert(valueIndex < nonZeroCount); - Debug.Assert(compressedIndex < compressedCounts.Length - 1); - - // shift values to close the gap - values.Span.Slice(valueIndex + 1, nonZeroCount - valueIndex - 1).CopyTo(values.Span.Slice(valueIndex)); - indices.Span.Slice(valueIndex + 1, nonZeroCount - valueIndex - 1).CopyTo(indices.Span.Slice(valueIndex)); - - var compressedCountsSpan = compressedCounts.Span.Slice(compressedIndex + 1); - for (int i = 0; i < compressedCountsSpan.Length; i++) - { - compressedCountsSpan[i]--; - } - nonZeroCount--; - } - - private void SetAt(T value, int compressedIndex, int nonCompressedIndex) - { - bool isZero = value!.Equals(Zero); - - if (TryFindIndex(compressedIndex, nonCompressedIndex, out int valueIndex)) - { - if (isZero) - { - RemoveAt(valueIndex, compressedIndex); - } - else - { - values.Span[valueIndex] = value; - indices.Span[valueIndex] = nonCompressedIndex; - } - } - else if (!isZero) - { - InsertAt(valueIndex, value, compressedIndex, nonCompressedIndex); - } - } - - /// - /// Trys to find the place to store a value - /// - /// - /// - /// - /// True if element is found at specific index, false if no specific index is found and insertion point is returned - private bool TryFindIndex(int compressedIndex, int nonCompressedIndex, out int valueIndex) - { - if (nonZeroCount == 0) - { - valueIndex = 0; - return false; - } - - Debug.Assert(compressedIndex < compressedCounts.Length - 1); - - var compressedCountsSpan = compressedCounts.Span; - var lowerValueIndex = compressedCountsSpan[compressedIndex]; - var upperValueIndex = compressedCountsSpan[compressedIndex + 1]; - var indicesSpan = indices.Span; - - // could be a faster search - for (valueIndex = lowerValueIndex; valueIndex < upperValueIndex; valueIndex++) - { - if (indicesSpan[valueIndex] == nonCompressedIndex) - { - return true; - } - } - - return false; - } - - /// - /// Creates a shallow copy of this tensor, with new backing storage. - /// - /// A shallow copy of this tensor. - public override Tensor Clone() - { - return new CompressedSparseTensor(values.ToArray(), compressedCounts.ToArray(), indices.ToArray(), nonZeroCount, dimensions, IsReversedStride); - } - - /// - /// Creates a new Tensor of a different type with the specified dimensions and the same layout as this tensor with elements initialized to their default value. - /// - /// Type contained in the returned Tensor. - /// An span of integers that represent the size of each dimension of the CompressedSparseTensor to create. - /// A new tensor with the same layout as this tensor but different type and dimensions. - public override Tensor CloneEmpty(ReadOnlySpan dimensions) - { - return new CompressedSparseTensor(dimensions, IsReversedStride); - } - - /// - /// Reshapes the current tensor to new dimensions. Unlike other Tensor implementations, CompressedSparseTensor<T> must allocate new backing storage to represent a reshaped Tensor. - /// - /// An span of integers that represent the size of each dimension of the CompressedSparseTensor to create. - /// A new tensor that reinterprets the content of this tensor to new dimensions (assuming the same linear index for each element). - public override Tensor Reshape(ReadOnlySpan dimensions) - { - // reshape currently has shallow semantics which are not compatible with the backing storage for CompressedSparseTensor - // which bakes in information about dimensions (compressedCounts and indices) - - var newCompressedDimension = IsReversedStride ? dimensions.Length - 1 : 0; - var newCompressedDimensionLength = dimensions[newCompressedDimension]; - var newCompressedDimensionStride = (int)(Length / newCompressedDimensionLength); - - var newValues = (T[])values.ToArray(); - var newCompressedCounts = new int[newCompressedDimensionLength + 1]; - var newIndices = new int[indices.Length]; - - var compressedIndex = 0; - - var compressedCountsSpan = compressedCounts.Span; - var indicesSpan = indices.Span.Slice(0, nonZeroCount); - for (int valueIndex = 0; valueIndex < indicesSpan.Length; valueIndex++) - { - while (valueIndex >= compressedCountsSpan[compressedIndex + 1]) - { - compressedIndex++; - Debug.Assert(compressedIndex < compressedCounts.Length); - } - - var currentIndex = indicesSpan[valueIndex] + compressedIndex * strides[compressedDimension]; - - newIndices[valueIndex] = currentIndex % newCompressedDimensionStride; - - var newCompressedIndex = currentIndex / newCompressedDimensionStride; - newCompressedCounts[newCompressedIndex + 1] = valueIndex + 1; - } - - return new CompressedSparseTensor(newValues, newCompressedCounts, newIndices, nonZeroCount, dimensions, IsReversedStride); - } - - /// - /// Creates a copy of this tensor as a DenseTensor<T>. - /// - /// A copy of this tensor as a DenseTensor<T> - public override DenseTensor ToDenseTensor() - { - var denseTensor = new DenseTensor(Dimensions, reverseStride: IsReversedStride); - - var compressedIndex = 0; - - var compressedCountsSpan = compressedCounts.Span; - var indicesSpan = indices.Span.Slice(0, nonZeroCount); - var valuesSpan = values.Span.Slice(0, nonZeroCount); - for (int valueIndex = 0; valueIndex < valuesSpan.Length; valueIndex++) - { - while (valueIndex >= compressedCountsSpan[compressedIndex + 1]) - { - compressedIndex++; - Debug.Assert(compressedIndex < compressedCounts.Length); - } - - var index = indicesSpan[valueIndex] + compressedIndex * strides[compressedDimension]; - - denseTensor.SetValue(index, valuesSpan[valueIndex]); - } - - return denseTensor; - } - - /// - /// Creates a copy of this tensor as a new CompressedSparseTensor<T> eliminating any unused space in the backing storage. - /// - /// A copy of this tensor as a CompressedSparseTensor<T>. - public override CompressedSparseTensor ToCompressedSparseTensor() - { - // Create a copy of the backing storage, eliminating any unused space. - var newValues = values.Slice(0, nonZeroCount).ToArray(); - var newIndices = indices.Slice(0, nonZeroCount).ToArray(); - - return new CompressedSparseTensor(newValues, compressedCounts.ToArray(), newIndices, nonZeroCount, dimensions, IsReversedStride); - } - - /// - /// Creates a copy of this tensor as a SparseTensor<T>. - /// - /// A copy of this tensor as a SparseTensor<T>. - public override SparseTensor ToSparseTensor() - { - var sparseTensor = new SparseTensor(dimensions, capacity: NonZeroCount, reverseStride: IsReversedStride); - - var compressedIndex = 0; - - var compressedCountsSpan = compressedCounts.Span; - var indicesSpan = indices.Span.Slice(0, nonZeroCount); - var valuesSpan = values.Span.Slice(0, nonZeroCount); - for (int valueIndex = 0; valueIndex < valuesSpan.Length; valueIndex++) - { - while (valueIndex >= compressedCountsSpan[compressedIndex + 1]) - { - compressedIndex++; - Debug.Assert(compressedIndex < compressedCounts.Length); - } - - var index = indicesSpan[valueIndex] + compressedIndex * strides[compressedDimension]; - - sparseTensor.SetValue(index, valuesSpan[valueIndex]); - } - - return sparseTensor; - } - } -} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/DenseTensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/DenseTensor.cs deleted file mode 100644 index 5f8715be3d18c8..00000000000000 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/DenseTensor.cs +++ /dev/null @@ -1,178 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; - -namespace System.Numerics.Tensors -{ - /// - /// Represents a multi-dimensional collection of objects of type T that can be accessed by indices. DenseTensor stores values in a contiguous sequential block of memory where all values are represented. - /// - /// type contained within the Tensor. Typically a value type such as int, double, float, etc. - public class DenseTensor : Tensor - { - private readonly Memory memory; - - internal DenseTensor(Array fromArray, bool reverseStride = false) : base(fromArray, reverseStride) - { - // copy initial array - var backingArray = new T[fromArray.Length]; - - int index = 0; - if (reverseStride) - { - // Array is always row-major - var sourceStrides = ArrayUtilities.GetStrides(dimensions); - - foreach (var item in fromArray) - { - var destIndex = ArrayUtilities.TransformIndexByStrides(index++, sourceStrides, false, strides); - backingArray[destIndex] = (T)item!; - } - } - else - { - foreach (var item in fromArray) - { - backingArray[index++] = (T)item!; - } - } - memory = backingArray; - } - - /// - /// Initializes a rank-1 Tensor using the specified . - /// - /// Size of the 1-dimensional tensor - public DenseTensor(int length) : base(length) - { - memory = new T[length]; - } - - /// - /// Initializes a rank-n Tensor using the dimensions specified in . - /// - /// An span of integers that represent the size of each dimension of the DenseTensor to create. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - public DenseTensor(ReadOnlySpan dimensions, bool reverseStride = false) : base(dimensions, reverseStride) - { - memory = new T[Length]; - } - - /// - /// Constructs a new DenseTensor of the specified dimensions, wrapping existing backing memory for the contents. - /// - /// - /// An span of integers that represent the size of each dimension of the DenseTensor to create. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - public DenseTensor(Memory memory, ReadOnlySpan dimensions, bool reverseStride = false) : base(dimensions, reverseStride) - { - this.memory = memory; - - if (Length != memory.Length) - { - throw new ArgumentException(SR.Format(SR.LengthMustMatch, nameof(memory), memory.Length, nameof(dimensions), Length)); - } - } - - /// - /// Memory storing backing values of this tensor. - /// - public Memory Buffer => memory; - - /// - /// Gets the value at the specified index, where index is a linearized version of n-dimension indices using strides. - /// - /// An integer index computed as a dot-product of indices. - /// The value at the specified position in this Tensor. - public override T GetValue(int index) - { - return Buffer.Span[index]; - } - - /// - /// Sets the value at the specified index, where index is a linearized version of n-dimension indices using strides. - /// - /// An integer index computed as a dot-product of indices. - /// The new value to set at the specified position in this Tensor. - public override void SetValue(int index, T value) - { - Buffer.Span[index] = value; - } - - protected override void CopyTo(T[] array, int arrayIndex) - { - if (array is null) - { - throw new ArgumentNullException(nameof(array)); - } - - if (array.Length < arrayIndex + Length) - { - throw new ArgumentException(SR.NumberGreaterThenAvailableSpace, nameof(array)); - } - - Buffer.Span.CopyTo(array.AsSpan(arrayIndex)); - } - - protected override int IndexOf(T item) - { - // TODO: use Span.IndexOf when/if it removes the IEquatable type constraint - if (MemoryMarshal.TryGetArray(Buffer, out var arraySegment)) - { - var result = Array.IndexOf(arraySegment.Array!, item, arraySegment.Offset, arraySegment.Count); - if (result != -1) - { - result -= arraySegment.Offset; - } - return result; - } - else - { - return base.IndexOf(item); - } - } - - /// - /// Creates a shallow copy of this tensor, with new backing storage. - /// - /// A shallow copy of this tensor. - public override Tensor Clone() - { - return new DenseTensor(Buffer.ToArray(), dimensions, IsReversedStride); - } - - /// - /// Creates a new Tensor of a different type with the specified dimensions and the same layout as this tensor with elements initialized to their default value. - /// - /// Type contained in the returned Tensor. - /// An span of integers that represent the size of each dimension of the DenseTensor to create. - /// A new tensor with the same layout as this tensor but different type and dimensions. - public override Tensor CloneEmpty(ReadOnlySpan dimensions) - { - return new DenseTensor(dimensions, IsReversedStride); - } - - /// - /// Reshapes the current tensor to new dimensions, using the same backing storage. - /// - /// An span of integers that represent the size of each dimension of the DenseTensor to create. - /// A new tensor that reinterprets backing Buffer of this tensor with different dimensions. - public override Tensor Reshape(ReadOnlySpan dimensions) - { - if (dimensions.Length == 0) - { - throw new ArgumentException(SR.DimensionsMustContainElements, nameof(dimensions)); - } - - var newSize = ArrayUtilities.GetProduct(dimensions); - - if (newSize != Length) - { - throw new ArgumentException(SR.Format(SR.CannotReshapeArrayDueToMismatchInLengths, Length, newSize), nameof(dimensions)); - } - - return new DenseTensor(Buffer, dimensions, IsReversedStride); - } - } -} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/SparseTensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/SparseTensor.cs deleted file mode 100644 index 83948a0b918b7d..00000000000000 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/SparseTensor.cs +++ /dev/null @@ -1,177 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; - -namespace System.Numerics.Tensors -{ - /// - /// Represents a multi-dimensional collection of objects of type T that can be accessed by indices. Unlike other Tensor<T> implementations SparseTensor<T> does not expose its backing storage. It is meant as an intermediate to be used to build other Tensors, such as CompressedSparseTensor. Unlike CompressedSparseTensor where insertions are O(n), insertions to SparseTensor<T> are nominally O(1). - /// - /// type contained within the Tensor. Typically a value type such as int, double, float, etc. - public class SparseTensor : Tensor - { - private readonly Dictionary values; - /// - /// Constructs a new SparseTensor of the specified dimensions, initial capacity, and stride ordering. - /// - /// An span of integers that represent the size of each dimension of the SparseTensor to create. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - /// The number of non-zero values this tensor can store without resizing. - public SparseTensor(ReadOnlySpan dimensions, bool reverseStride = false, int capacity = 0) : base(dimensions, reverseStride) - { - values = new Dictionary(capacity); - } - - internal SparseTensor(Dictionary values, ReadOnlySpan dimensions, bool reverseStride = false) : base(dimensions, reverseStride) - { - this.values = values; - } - - internal SparseTensor(Array fromArray, bool reverseStride = false) : base(fromArray, reverseStride) - { - values = new Dictionary(fromArray.Length); - - int index = 0; - if (reverseStride) - { - // Array is always row-major - var sourceStrides = ArrayUtilities.GetStrides(dimensions); - - foreach (T item in fromArray) - { - if (!item!.Equals(Zero)) - { - var destIndex = ArrayUtilities.TransformIndexByStrides(index, sourceStrides, false, strides); - values[destIndex] = item; - } - - index++; - } - } - else - { - foreach (T item in fromArray) - { - if (!item!.Equals(Zero)) - { - values[index] = item; - } - - index++; - } - } - } - - /// - /// Gets the value at the specified index, where index is a linearized version of n-dimension indices using strides. - /// - /// An integer index computed as a dot-product of indices. - /// The value at the specified position in this Tensor. - public override T GetValue(int index) - { - - if (!values.TryGetValue(index, out T? value)) - { - value = Zero; - } - - return value; - } - - /// - /// Sets the value at the specified index, where index is a linearized version of n-dimension indices using strides. - /// - /// An integer index computed as a dot-product of indices. - /// The new value to set at the specified position in this Tensor. - public override void SetValue(int index, T value) - { - if (value!.Equals(Zero)) - { - values.Remove(index); - } - else - { - values[index] = value; - } - } - - /// - /// Get's the number on non-zero values currently being stored in this tensor. - /// - public int NonZeroCount => values.Count; - - /// - /// Creates a shallow copy of this tensor, with new backing storage. - /// - /// A shallow copy of this tensor. - public override Tensor Clone() - { - var valueCopy = new Dictionary(values); - return new SparseTensor(valueCopy, dimensions, IsReversedStride); - } - - /// - /// Creates a new Tensor of a different type with the specified dimensions and the same layout as this tensor with elements initialized to their default value. - /// - /// Type contained in the returned Tensor. - /// An span of integers that represent the size of each dimension of the SparseTensor to create. - /// A new tensor with the same layout as this tensor but different type and dimensions. - public override Tensor CloneEmpty(ReadOnlySpan dimensions) - { - return new SparseTensor(dimensions, IsReversedStride); - } - - /// - /// Reshapes the current tensor to new dimensions, using the same backing storage. - /// - /// An span of integers that represent the size of each dimension of the SparseTensor to create. - /// A new tensor that reinterprets backing storage of this tensor with different dimensions. - public override Tensor Reshape(ReadOnlySpan dimensions) - { - return new SparseTensor(values, dimensions, IsReversedStride); - } - - /// - /// Creates a copy of this tensor as a DenseTensor<T>. - /// - /// A copy of this tensor as a DenseTensor<T> - public override DenseTensor ToDenseTensor() - { - var denseTensor = new DenseTensor(Dimensions, reverseStride: IsReversedStride); - - // only set non-zero values - foreach (var pair in values) - { - denseTensor.SetValue(pair.Key, pair.Value); - } - - return denseTensor; - } - - /// - /// Creates a copy of this tensor as a new SparseTensor<T> eliminating any unused space in the backing storage. - /// - /// A copy of this tensor as a SparseTensor<T> eliminated any usused space in the backing storage. - public override SparseTensor ToSparseTensor() - { - var valueCopy = new Dictionary(values); - return new SparseTensor(valueCopy, dimensions, IsReversedStride); - } - - /// - /// Creates a copy of this tensor as a CompressedSparseTensor<T>. - /// - /// A copy of this tensor as a CompressedSparseTensor<T>. - public override CompressedSparseTensor ToCompressedSparseTensor() - { - var compressedSparseTensor = new CompressedSparseTensor(dimensions, capacity: NonZeroCount, reverseStride: IsReversedStride); - - foreach (var pair in values) - { - compressedSparseTensor.SetValue(pair.Key, pair.Value); - } - return compressedSparseTensor; - } - } -} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/Tensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/Tensor.cs deleted file mode 100644 index f63547682dd24b..00000000000000 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/Tensor.cs +++ /dev/null @@ -1,1365 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; - -namespace System.Numerics.Tensors -{ - /// - /// Various methods for creating and manipulating Tensor<T> - /// - public static partial class Tensor - { - /// - /// Creates an identity tensor of the specified size. An identity tensor is a two dimensional tensor with 1s in the diagonal. - /// - /// type contained within the Tensor. Typically a value type such as int, double, float, etc. - /// Width and height of the identity tensor to create. - /// a by with 1s along the diagonal and zeros elsewhere. - public static Tensor CreateIdentity(int size) - { - return CreateIdentity(size, false, Tensor.One); - } - - /// - /// Creates an identity tensor of the specified size and layout (row vs column major). An identity tensor is a two dimensional tensor with 1s in the diagonal. - /// - /// type contained within the Tensor. Typically a value type such as int, double, float, etc. - /// Width and height of the identity tensor to create. - /// >False to indicate that the first dimension is most minor (closest) and the last dimension is most major (farthest): row-major. True to indicate that the last dimension is most minor (closest together) and the first dimension is most major (farthest apart): column-major. - /// a by with 1s along the diagonal and zeros elsewhere. - public static Tensor CreateIdentity(int size, bool columMajor) - { - return CreateIdentity(size, columMajor, Tensor.One); - } - - /// - /// Creates an identity tensor of the specified size and layout (row vs column major) using the specified one value. An identity tensor is a two dimensional tensor with 1s in the diagonal. This may be used in case T is a type that doesn't have a known 1 value. - /// - /// type contained within the Tensor. Typically a value type such as int, double, float, etc. - /// Width and height of the identity tensor to create. - /// >False to indicate that the first dimension is most minor (closest) and the last dimension is most major (farthest): row-major. True to indicate that the last dimension is most minor (closest together) and the first dimension is most major (farthest apart): column-major. - /// Value of that is used along the diagonal. - /// a by with 1s along the diagonal and zeros elsewhere. - public static Tensor CreateIdentity(int size, bool columMajor, T oneValue) - { - Span dimensions = stackalloc int[2]; - dimensions[0] = dimensions[1] = size; - - var result = new DenseTensor(dimensions, columMajor); - - for (int i = 0; i < size; i++) - { - result.SetValue(i * size + i, oneValue); - } - - return result; - } - - /// - /// Creates a n+1-rank tensor using the specified n-rank diagonal. Values not on the diagonal will be filled with zeros. - /// - /// type contained within the Tensor. Typically a value type such as int, double, float, etc. - /// Tensor representing the diagonal to build the new tensor from. - /// A new tensor of the same layout and order as of one higher rank, with the values of along the diagonal and zeros elsewhere. - public static Tensor CreateFromDiagonal(Tensor diagonal) - { - return CreateFromDiagonal(diagonal, 0); - } - - /// - /// Creates a n+1-dimension tensor using the specified n-dimension diagonal at the specified offset from the center. Values not on the diagonal will be filled with zeros. - /// - /// type contained within the Tensor. Typically a value type such as int, double, float, etc. - /// Tensor representing the diagonal to build the new tensor from. - /// Offset of diagonal to set in returned tensor. 0 for the main diagonal, less than zero for diagonals below, greater than zero from diagonals above. - /// A new tensor of the same layout and order as of one higher rank, with the values of along the specified diagonal and zeros elsewhere. - public static Tensor CreateFromDiagonal(Tensor diagonal, int offset) - { - if (diagonal.Rank < 1) - { - throw new ArgumentException(SR.Format(SR.MustHaveAtLeastOneDimension, nameof(diagonal)), nameof(diagonal)); - } - - int diagonalLength = diagonal.dimensions[0]; - - // TODO: allow specification of axis1 and axis2? - var rank = diagonal.dimensions.Length + 1; - Span dimensions = rank < ArrayUtilities.StackallocMax ? stackalloc int[rank] : new int[rank]; - - // assume square - var axisLength = diagonalLength + Math.Abs(offset); - dimensions[0] = dimensions[1] = axisLength; - - for (int i = 1; i < diagonal.dimensions.Length; i++) - { - dimensions[i + 1] = diagonal.dimensions[i]; - } - - var result = diagonal.CloneEmpty(dimensions); - - var sizePerDiagonal = diagonal.Length / diagonalLength; - - var diagProjectionStride = diagonal.IsReversedStride && diagonal.Rank > 1 ? diagonal.strides[1] : 1; - var resultProjectionStride = result.IsReversedStride && result.Rank > 2 ? result.strides[2] : 1; - - for (int diagIndex = 0; diagIndex < diagonalLength; diagIndex++) - { - var resultIndex0 = offset < 0 ? diagIndex - offset : diagIndex; - var resultIndex1 = offset > 0 ? diagIndex + offset : diagIndex; - - var resultBase = resultIndex0 * result.strides[0] + resultIndex1 * result.strides[1]; - var diagBase = diagIndex * diagonal.strides[0]; - - for (int diagProjectionOffset = 0; diagProjectionOffset < sizePerDiagonal; diagProjectionOffset++) - { - result.SetValue(resultBase + diagProjectionOffset * resultProjectionStride, - diagonal.GetValue(diagBase + diagProjectionOffset * diagProjectionStride)); - } - } - - return result; - } - } - - /// - /// Represents a multi-dimensional collection of objects of type T that can be accessed by indices. - /// - /// type contained within the Tensor. Typically a value type such as int, double, float, etc. - [DebuggerDisplay("{GetArrayString(false)}")] - // When we cross-compile for frameworks that expose ICloneable this must implement ICloneable as well. - public abstract class Tensor : IList, IList, IReadOnlyList, IStructuralComparable, IStructuralEquatable - { - internal static T Zero - { - get - { - if (typeof(T) == typeof(bool)) - { - return (T)(object)(false); - } - else if (typeof(T) == typeof(byte)) - { - return (T)(object)(byte)(0); - } - else if (typeof(T) == typeof(char)) - { - return (T)(object)(char)(0); - } - else if (typeof(T) == typeof(decimal)) - { - return (T)(object)(decimal)(0); - } - else if (typeof(T) == typeof(double)) - { - return (T)(object)(double)(0); - } - else if (typeof(T) == typeof(float)) - { - return (T)(object)(float)(0); - } - else if (typeof(T) == typeof(int)) - { - return (T)(object)(int)(0); - } - else if (typeof(T) == typeof(long)) - { - return (T)(object)(long)(0); - } - else if (typeof(T) == typeof(sbyte)) - { - return (T)(object)(sbyte)(0); - } - else if (typeof(T) == typeof(short)) - { - return (T)(object)(short)(0); - } - else if (typeof(T) == typeof(uint)) - { - return (T)(object)(uint)(0); - } - else if (typeof(T) == typeof(ulong)) - { - return (T)(object)(ulong)(0); - } - else if (typeof(T) == typeof(ushort)) - { - return (T)(object)(ushort)(0); - } - - throw new NotSupportedException(); - } - } - - internal static T One - { - get - { - if (typeof(T) == typeof(bool)) - { - return (T)(object)(true); - } - else if (typeof(T) == typeof(byte)) - { - return (T)(object)(byte)(1); - } - else if (typeof(T) == typeof(char)) - { - return (T)(object)(char)(1); - } - else if (typeof(T) == typeof(decimal)) - { - return (T)(object)(decimal)(1); - } - else if (typeof(T) == typeof(double)) - { - return (T)(object)(double)(1); - } - else if (typeof(T) == typeof(float)) - { - return (T)(object)(float)(1); - } - else if (typeof(T) == typeof(int)) - { - return (T)(object)(int)(1); - } - else if (typeof(T) == typeof(long)) - { - return (T)(object)(long)(1); - } - else if (typeof(T) == typeof(sbyte)) - { - return (T)(object)(sbyte)(1); - } - else if (typeof(T) == typeof(short)) - { - return (T)(object)(short)(1); - } - else if (typeof(T) == typeof(uint)) - { - return (T)(object)(uint)(1); - } - else if (typeof(T) == typeof(ulong)) - { - return (T)(object)(ulong)(1); - } - else if (typeof(T) == typeof(ushort)) - { - return (T)(object)(ushort)(1); - } - - throw new NotSupportedException(); - } - } - - internal readonly int[] dimensions; - internal readonly int[] strides; - private readonly bool isReversedStride; - - private readonly long length; - - /// - /// Initialize a 1-dimensional tensor of the specified length - /// - /// Size of the 1-dimensional tensor - protected Tensor(int length) - { - dimensions = new[] { length }; - strides = new[] { 1 }; - isReversedStride = false; - this.length = length; - } - - /// - /// Initialize an n-dimensional tensor with the specified dimensions and layout. ReverseStride=true gives a stride of 1-element witdth to the first dimension (0). ReverseStride=false gives a stride of 1-element width to the last dimension (n-1). - /// - /// An span of integers that represent the size of each dimension of the Tensor to create. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - protected Tensor(ReadOnlySpan dimensions, bool reverseStride) - { - if (dimensions.Length == 0) - { - throw new ArgumentException(SR.DimensionsMustContainElements, nameof(dimensions)); - } - - this.dimensions = new int[dimensions.Length]; - long size = 1; - for (int i = 0; i < dimensions.Length; i++) - { - if (dimensions[i] < 1) - { - throw new ArgumentOutOfRangeException(nameof(dimensions), SR.DimensionsMustBePositiveAndNonZero); - } - this.dimensions[i] = dimensions[i]; - size *= dimensions[i]; - } - - strides = ArrayUtilities.GetStrides(dimensions, reverseStride); - isReversedStride = reverseStride; - - length = size; - } - - /// - /// Initializes tensor with same dimensions as array, content of array is ignored. ReverseStride=true gives a stride of 1-element witdth to the first dimension (0). ReverseStride=false gives a stride of 1-element width to the last dimension (n-1). - /// - /// Array from which to derive dimensions. - /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor. - protected Tensor(Array fromArray, bool reverseStride) - { - if (fromArray is null) - { - throw new ArgumentNullException(nameof(fromArray)); - } - - if (fromArray.Rank == 0) - { - throw new ArgumentException(SR.ArrayMustContainElements, nameof(fromArray)); - } - - dimensions = new int[fromArray.Rank]; - long size = 1; - for (int i = 0; i < dimensions.Length; i++) - { - dimensions[i] = fromArray.GetLength(i); - size *= dimensions[i]; - } - - strides = ArrayUtilities.GetStrides(dimensions, reverseStride); - isReversedStride = reverseStride; - - length = size; - } - - /// - /// Total length of the Tensor. - /// - public long Length => length; - - /// - /// Rank of the tensor: number of dimensions. - /// - public int Rank => dimensions.Length; - - /// - /// True if strides are reversed (AKA Column-major) - /// - public bool IsReversedStride => isReversedStride; - - /// - /// Returns a readonly view of the dimensions of this tensor. - /// - public ReadOnlySpan Dimensions => dimensions; - - /// - /// Returns a readonly view of the strides of this tensor. - /// - public ReadOnlySpan Strides => strides; - - /// - /// Sets all elements in Tensor to . - /// - /// Value to fill - public virtual void Fill(T value) - { - for (int i = 0; i < Length; i++) - { - SetValue(i, value); - } - } - - /// - /// Creates a shallow copy of this tensor, with new backing storage. - /// - /// A shallow copy of this tensor. - public abstract Tensor Clone(); - - /// - /// Creates a new Tensor with the same layout and dimensions as this tensor with elements initialized to their default value. - /// - /// A new Tensor with the same layout and dimensions as this tensor with elements initialized to their default value. - public virtual Tensor CloneEmpty() - { - return CloneEmpty(dimensions); - } - - /// - /// Creates a new Tensor with the specified dimensions and the same layout as this tensor with elements initialized to their default value. - /// - /// An span of integers that represent the size of each dimension of the DenseTensor to create. - /// A new Tensor with the same layout as this tensor and specified with elements initialized to their default value. - public virtual Tensor CloneEmpty(ReadOnlySpan dimensions) - { - return CloneEmpty(dimensions); - } - - /// - /// Creates a new Tensor of a different type with the same layout and size as this tensor with elements initialized to their default value. - /// - /// Type contained within the new Tensor. Typically a value type such as int, double, float, etc. - /// A new Tensor with the same layout and dimensions as this tensor with elements of type initialized to their default value. - public virtual Tensor CloneEmpty() - { - return CloneEmpty(dimensions); - } - - /// - /// Creates a new Tensor of a different type with the specified dimensions and the same layout as this tensor with elements initialized to their default value. - /// - /// Type contained within the new Tensor. Typically a value type such as int, double, float, etc. - /// An span of integers that represent the size of each dimension of the DenseTensor to create. - /// A new Tensor with the same layout as this tensor of specified with elements of type initialized to their default value. - public abstract Tensor CloneEmpty(ReadOnlySpan dimensions); - - /// - /// Gets the n-1 dimension diagonal from the n dimension tensor. - /// - /// An n-1 dimension tensor with the values from the main diagonal of this tensor. - public Tensor GetDiagonal() - { - return GetDiagonal(0); - } - - /// - /// Gets the n-1 dimension diagonal from the n dimension tensor at the specified offset from center. - /// - /// Offset of diagonal to set in returned tensor. 0 for the main diagonal, less than zero for diagonals below, greater than zero from diagonals above. - /// An n-1 dimension tensor with the values from the specified diagonal of this tensor. - public Tensor GetDiagonal(int offset) - { - // Get diagonal of first two dimensions for all remaining dimensions - - // diagnonal is as follows: - // { 1, 2, 4 } - // { 8, 3, 9 } - // { 0, 7, 5 } - // The diagonal at offset 0 is { 1, 3, 5 } - // The diagonal at offset 1 is { 2, 9 } - // The diagonal at offset -1 is { 8, 7 } - - if (Rank < 2) - { - throw new InvalidOperationException(SR.Format(SR.CannotComputeDiagonal, nameof(Tensor))); - } - - // TODO: allow specification of axis1 and axis2? - var axisLength0 = dimensions[0]; - var axisLength1 = dimensions[1]; - - // the diagonal will be the length of the smaller axis - // if offset it positive, the length will shift along the second axis - // if the offset is negative, the length will shift along the first axis - // In that way the length of the diagonal will be - // Min(offset < 0 ? axisLength0 + offset : axisLength0, offset > 0 ? axisLength1 - offset : axisLength1) - // To illustrate, consider the following - // { 1, 2, 4, 3, 7 } - // { 8, 3, 9, 2, 6 } - // { 0, 7, 5, 2, 9 } - // The diagonal at offset 0 is { 1, 3, 5 }, Min(3, 5) = 3 - // The diagonal at offset 1 is { 2, 9, 2 }, Min(3, 5 - 1) = 3 - // The diagonal at offset 3 is { 3, 6 }, Min(3, 5 - 3) = 2 - // The diagonal at offset -1 is { 8, 7 }, Min(3 - 1, 5) = 2 - var offsetAxisLength0 = offset < 0 ? axisLength0 + offset : axisLength0; - var offsetAxisLength1 = offset > 0 ? axisLength1 - offset : axisLength1; - - var diagonalLength = Math.Min(offsetAxisLength0, offsetAxisLength1); - - if (diagonalLength <= 0) - { - throw new ArgumentException(SR.Format(SR.CannotComputeDiagonalWithOffset, offset), nameof(offset)); - } - - var newTensorRank = Rank - 1; - var newTensorDimensions = newTensorRank < ArrayUtilities.StackallocMax ? stackalloc int[newTensorRank] : new int[newTensorRank]; - newTensorDimensions[0] = diagonalLength; - - for (int i = 2; i < dimensions.Length; i++) - { - newTensorDimensions[i - 1] = dimensions[i]; - } - - var diagonalTensor = CloneEmpty(newTensorDimensions); - var sizePerDiagonal = diagonalTensor.Length / diagonalTensor.Dimensions[0]; - - var diagProjectionStride = diagonalTensor.IsReversedStride && diagonalTensor.Rank > 1 ? diagonalTensor.strides[1] : 1; - var sourceProjectionStride = IsReversedStride && Rank > 2 ? strides[2] : 1; - - for (int diagIndex = 0; diagIndex < diagonalLength; diagIndex++) - { - var sourceIndex0 = offset < 0 ? diagIndex - offset : diagIndex; - var sourceIndex1 = offset > 0 ? diagIndex + offset : diagIndex; - - var sourceBase = sourceIndex0 * strides[0] + sourceIndex1 * strides[1]; - var diagBase = diagIndex * diagonalTensor.strides[0]; - - for (int diagProjectionIndex = 0; diagProjectionIndex < sizePerDiagonal; diagProjectionIndex++) - { - diagonalTensor.SetValue(diagBase + diagProjectionIndex * diagProjectionStride, - GetValue(sourceBase + diagProjectionIndex * sourceProjectionStride)); - } - } - - return diagonalTensor; - } - - /// - /// Gets a tensor representing the elements below and including the diagonal, with the rest of the elements zero-ed. - /// - /// A tensor with the values from this tensor at and below the main diagonal and zeros elsewhere. - public Tensor GetTriangle() - { - return GetTriangle(0, upper: false); - } - - /// - /// Gets a tensor representing the elements below and including the specified diagonal, with the rest of the elements zero-ed. - /// - /// Offset of diagonal to set in returned tensor. 0 for the main diagonal, less than zero for diagonals below, greater than zero from diagonals above. - /// A tensor with the values from this tensor at and below the specified diagonal and zeros elsewhere. - public Tensor GetTriangle(int offset) - { - return GetTriangle(offset, upper: false); - } - - /// - /// Gets a tensor representing the elements above and including the diagonal, with the rest of the elements zero-ed. - /// - /// A tensor with the values from this tensor at and above the main diagonal and zeros elsewhere. - public Tensor GetUpperTriangle() - { - return GetTriangle(0, upper: true); - } - - /// - /// Gets a tensor representing the elements above and including the specified diagonal, with the rest of the elements zero-ed. - /// - /// Offset of diagonal to set in returned tensor. 0 for the main diagonal, less than zero for diagonals below, greater than zero from diagonals above. - /// A tensor with the values from this tensor at and above the specified diagonal and zeros elsewhere. - public Tensor GetUpperTriangle(int offset) - { - return GetTriangle(offset, upper: true); - } - - private Tensor GetTriangle(int offset, bool upper) - { - if (Rank < 2) - { - throw new InvalidOperationException(SR.Format(SR.CannotComputeTriangle, nameof(Tensor))); - } - - // Similar to get diagonal except it gets every element below and including the diagonal. - - // TODO: allow specification of axis1 and axis2? - var axisLength0 = dimensions[0]; - var axisLength1 = dimensions[1]; - var diagonalLength = Math.Max(axisLength0, axisLength1); - - var result = CloneEmpty(); - - var projectionSize = Length / (axisLength0 * axisLength1); - var projectionStride = IsReversedStride && Rank > 2 ? strides[2] : 1; - - for (int diagIndex = 0; diagIndex < diagonalLength; diagIndex++) - { - // starting point for the tri - var triIndex0 = offset > 0 ? diagIndex - offset : diagIndex; - var triIndex1 = offset > 0 ? diagIndex : diagIndex + offset; - - // for lower triangle, iterate index0 keeping same index1 - // for upper triangle, iterate index1 keeping same index0 - - if (triIndex0 < 0) - { - if (upper) - { - // out of bounds, ignore this diagIndex. - continue; - } - else - { - // set index to 0 so that we can iterate on the remaining index0 values. - triIndex0 = 0; - } - } - - if (triIndex1 < 0) - { - if (upper) - { - // set index to 0 so that we can iterate on the remaining index1 values. - triIndex1 = 0; - } - else - { - // out of bounds, ignore this diagIndex. - continue; - } - } - - while ((triIndex1 < axisLength1) && (triIndex0 < axisLength0)) - { - var baseIndex = triIndex0 * strides[0] + triIndex1 * result.strides[1]; - - for (int projectionIndex = 0; projectionIndex < projectionSize; projectionIndex++) - { - var index = baseIndex + projectionIndex * projectionStride; - - result.SetValue(index, GetValue(index)); - } - - if (upper) - { - triIndex1++; - } - else - { - triIndex0++; - } - } - } - - return result; - } - - /// - /// Reshapes the current tensor to new dimensions, using the same backing storage if possible. - /// - /// An span of integers that represent the size of each dimension of the Tensor to create. - /// A new tensor that reinterprets this tensor with different dimensions. - public abstract Tensor Reshape(ReadOnlySpan dimensions); - - /// - /// Obtains the value at the specified indices - /// - /// A one-dimensional array of integers that represent the indices specifying the position of the element to get. - /// The value at the specified position in this Tensor. - public virtual T this[params int[] indices] - { - get - { - if (indices is null) - { - throw new ArgumentNullException(nameof(indices)); - } - - var span = new ReadOnlySpan(indices); - return this[span]; - } - - set - { - if (indices is null) - { - throw new ArgumentNullException(nameof(indices)); - } - - var span = new ReadOnlySpan(indices); - this[span] = value; - } - } - - /// - /// Obtains the value at the specified indices - /// - /// A span integers that represent the indices specifying the position of the element to get. - /// The value at the specified position in this Tensor. - public virtual T this[ReadOnlySpan indices] - { - get - { - return GetValue(ArrayUtilities.GetIndex(strides, indices)); - } - - set - { - SetValue(ArrayUtilities.GetIndex(strides, indices), value); - } - } - - /// - /// Gets the value at the specified index, where index is a linearized version of n-dimension indices using strides. - /// - /// An integer index computed as a dot-product of indices. - /// The value at the specified position in this Tensor. - public abstract T GetValue(int index); - - /// - /// Sets the value at the specified index, where index is a linearized version of n-dimension indices using strides. - /// - /// An integer index computed as a dot-product of indices. - /// The new value to set at the specified position in this Tensor. - public abstract void SetValue(int index, T value); - - /// - /// The type that implements enumerators for instances. - /// - public struct Enumerator : IEnumerator - { - private readonly Tensor _tensor; - private int _index; - - internal Enumerator(Tensor tensor) - { - Debug.Assert(tensor != null); - - _tensor = tensor; - _index = 0; - Current = default!; - } - - public T Current { get; private set; } - - object? IEnumerator.Current => Current; - - public bool MoveNext() - { - if (_index < _tensor.Length) - { - Current = _tensor.GetValue(_index); - ++_index; - return true; - } - else - { - Current = default!; - return false; - } - } - - /// - /// Resets the enumerator to the beginning. - /// - public void Reset() - { - _index = 0; - Current = default!; - } - - /// - /// Disposes the enumerator. - /// - public void Dispose() { } - } - - /// - /// Gets an enumerator that enumerates the elements of the . - /// - /// An enumerator for the current . - public Enumerator GetEnumerator() => new Enumerator(this); - - #region statics - /// - /// Performs a value comparison of the content and shape of two tensors. Two tensors are equal if they have the same shape and same value at every set of indices. If not equal a tensor is greater or less than another tensor based on the first non-equal element when enumerating in linear order. - /// - /// - /// - /// - public static int Compare(Tensor left, Tensor right) - { - return StructuralComparisons.StructuralComparer.Compare(left, right); - } - - /// - /// Performs a value equality comparison of the content of two tensors. Two tensors are equal if they have the same shape and same value at every set of indices. - /// - /// - /// - /// - public static bool Equals(Tensor left, Tensor right) - { - return StructuralComparisons.StructuralEqualityComparer.Equals(left, right); - } - #endregion - - #region IEnumerable members - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - #endregion - - #region ICollection members - int ICollection.Count => (int)Length; - - bool ICollection.IsSynchronized => false; - - object ICollection.SyncRoot => this; // backingArray.this? - - void ICollection.CopyTo(Array array, int index) - { - if (array is T[] destinationArray) - { - CopyTo(destinationArray, index); - } - else - { - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - if (array.Rank != 1) - { - throw new ArgumentException(SR.OnlySingleDimensionalArraysSupported, nameof(array)); - } - if (array.Length < index + Length) - { - throw new ArgumentException(SR.NumberGreaterThenAvailableSpace, nameof(array)); - } - - for (int i = 0; i < length; i++) - { - array.SetValue(GetValue(i), index + i); - } - } - } - #endregion - - #region IList members - object? IList.this[int index] - { - get - { - return GetValue(index); - } - set - { - try - { - SetValue(index, (T)value!); - } - catch (InvalidCastException) - { - throw new ArgumentException(SR.Format(SR.ValueIsNotOfType, value, typeof(T))); - } - } - } - - public bool IsFixedSize => true; - - public bool IsReadOnly => false; - - int IList.Add(object? value) - { - throw new InvalidOperationException(); - } - - void IList.Clear() - { - Fill(default!); - } - - bool IList.Contains(object? value) - { - if (IsCompatibleObject(value!)) - { - return Contains((T)value!); - } - return false; - } - - int IList.IndexOf(object? value) - { - if (IsCompatibleObject(value!)) - { - return IndexOf((T)value!); - } - return -1; - } - - void IList.Insert(int index, object? value) - { - throw new InvalidOperationException(); - } - - void IList.Remove(object? value) - { - throw new InvalidOperationException(); - } - - void IList.RemoveAt(int index) - { - throw new InvalidOperationException(); - } - #endregion - - #region IEnumerable members - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - #endregion - - #region ICollection members - int ICollection.Count => (int)Length; - - void ICollection.Add(T item) - { - throw new InvalidOperationException(); - } - - void ICollection.Clear() - { - Fill(default!); - } - - bool ICollection.Contains(T item) - { - return Contains(item); - } - - /// - /// Determines whether an element is in the Tensor<T>. - /// - /// - /// The object to locate in the Tensor<T>. The value can be null for reference types. - /// - /// - /// true if item is found in the Tensor<T>; otherwise, false. - /// - protected virtual bool Contains(T item) - { - return Length != 0 && IndexOf(item) != -1; - } - - void ICollection.CopyTo(T[] array, int arrayIndex) - { - CopyTo(array, arrayIndex); - } - - /// - /// Copies the elements of the Tensor<T> to an Array, starting at a particular Array index. - /// - /// - /// The one-dimensional Array that is the destination of the elements copied from Tensor<T>. The Array must have zero-based indexing. - /// - /// - /// The zero-based index in array at which copying begins. - /// - protected virtual void CopyTo(T[] array, int arrayIndex) - { - if (array is null) - { - throw new ArgumentNullException(nameof(array)); - } - - if (array.Length < arrayIndex + Length) - { - throw new ArgumentException(SR.NumberGreaterThenAvailableSpace, nameof(array)); - } - - for (int i = 0; i < length; i++) - { - array[arrayIndex + i] = GetValue(i); - } - } - - bool ICollection.Remove(T item) - { - throw new InvalidOperationException(); - } - #endregion - - #region IReadOnlyCollection members - - int IReadOnlyCollection.Count => (int)Length; - - #endregion - - #region IList members - T IList.this[int index] - { - get { return GetValue(index); } - set { SetValue(index, value); } - } - - int IList.IndexOf(T item) - { - return IndexOf(item); - } - - /// - /// Determines the index of a specific item in the Tensor<T>. - /// - /// The object to locate in the Tensor<T>. - /// The index of item if found in the tensor; otherwise, -1. - protected virtual int IndexOf(T item) - { - for (int i = 0; i < Length; i++) - { - if (GetValue(i)!.Equals(item)) - { - return i; - } - } - - return -1; - } - - void IList.Insert(int index, T item) - { - throw new InvalidOperationException(); - } - - void IList.RemoveAt(int index) - { - throw new InvalidOperationException(); - } - #endregion - - #region IReadOnlyList members - - T IReadOnlyList.this[int index] => GetValue(index); - - #endregion - - #region IStructuralComparable members - int IStructuralComparable.CompareTo(object? other, IComparer comparer) - { - if (other == null) - { - return 1; - } - - if (other is Tensor) - { - return CompareTo((Tensor)other, comparer); - } - - var otherArray = other as Array; - - if (otherArray != null) - { - return CompareTo(otherArray, comparer); - } - - throw new ArgumentException(SR.Format(SR.CannotCompare, nameof(Tensor), other.GetType()), nameof(other)); - } - - private int CompareTo(Tensor other, IComparer comparer) - { - if (Rank != other.Rank) - { - throw new ArgumentException(SR.Format(SR.CannotCompareWithRank, nameof(Tensor), Rank, nameof(other), other.Rank), nameof(other)); - } - - for (int i = 0; i < dimensions.Length; i++) - { - if (dimensions[i] != other.dimensions[i]) - { - throw new ArgumentException(SR.Format(SR.CannotCompareWithDifferentDimension, nameof(Tensor), i, dimensions[i], other.dimensions[i]), nameof(other)); - } - } - - int result = 0; - - if (IsReversedStride == other.IsReversedStride) - { - for (int i = 0; i < Length; i++) - { - result = comparer.Compare(GetValue(i), other.GetValue(i)); - if (result != 0) - { - break; - } - } - } - else - { - var indices = Rank < ArrayUtilities.StackallocMax ? stackalloc int[Rank] : new int[Rank]; - for (int i = 0; i < Length; i++) - { - ArrayUtilities.GetIndices(strides, IsReversedStride, i, indices); - result = comparer.Compare(this[indices], other[indices]); - if (result != 0) - { - break; - } - } - } - - return result; - } - - private int CompareTo(Array other, IComparer comparer) - { - if (Rank != other.Rank) - { - throw new ArgumentException(SR.Format(SR.CannotCompareWithRank, nameof(Tensor), Rank, nameof(Array), other.Rank), nameof(other)); - } - - for (int i = 0; i < dimensions.Length; i++) - { - var otherDimension = other.GetLength(i); - if (dimensions[i] != otherDimension) - { - throw new ArgumentException(SR.Format(SR.CannotCompareToWithDifferentDimension, nameof(Tensor), nameof(Array), i, dimensions[i], otherDimension), nameof(other)); - } - } - - int result = 0; - var indices = new int[Rank]; - for (int i = 0; i < Length; i++) - { - ArrayUtilities.GetIndices(strides, IsReversedStride, i, indices); - - result = comparer.Compare(GetValue(i), other.GetValue(indices)); - - if (result != 0) - { - break; - } - } - - return result; - } - #endregion - - #region IStructuralEquatable members - bool IStructuralEquatable.Equals(object? other, IEqualityComparer comparer) - { - if (other == null) - { - return false; - } - - if (other is Tensor) - { - return Equals((Tensor)other, comparer); - } - - var otherArray = other as Array; - - if (otherArray != null) - { - return Equals(otherArray, comparer); - } - - throw new ArgumentException(SR.Format(SR.CannotCompare, nameof(Tensor), other.GetType()), nameof(other)); - } - - private bool Equals(Tensor other, IEqualityComparer comparer) - { - if (Rank != other.Rank) - { - throw new ArgumentException(SR.Format(SR.CannotCompareWithRank, nameof(Tensor), Rank, nameof(other), other.Rank), nameof(other)); - } - - for (int i = 0; i < dimensions.Length; i++) - { - if (dimensions[i] != other.dimensions[i]) - { - throw new ArgumentException(SR.Format(SR.CannotCompareWithDifferentDimension, nameof(Tensor), i, dimensions[i], other.dimensions[i]), nameof(other)); - } - } - - if (IsReversedStride == other.IsReversedStride) - { - for (int i = 0; i < Length; i++) - { - if (!comparer.Equals(GetValue(i), other.GetValue(i))) - { - return false; - } - } - } - else - { - var indices = Rank < ArrayUtilities.StackallocMax ? stackalloc int[Rank] : new int[Rank]; - for (int i = 0; i < Length; i++) - { - ArrayUtilities.GetIndices(strides, IsReversedStride, i, indices); - - if (!comparer.Equals(this[indices], other[indices])) - { - return false; - } - } - } - - return true; - } - - private bool Equals(Array other, IEqualityComparer comparer) - { - if (Rank != other.Rank) - { - throw new ArgumentException(SR.Format(SR.CannotCompareWithRank, nameof(Tensor), Rank, nameof(Array), other.Rank), nameof(other)); - } - - for (int i = 0; i < dimensions.Length; i++) - { - var otherDimension = other.GetLength(i); - if (dimensions[i] != otherDimension) - { - throw new ArgumentException(SR.Format(SR.CannotCompareToWithDifferentDimension, nameof(Tensor), nameof(Array), i, dimensions[i], otherDimension), nameof(other)); - } - } - - var indices = new int[Rank]; - for (int i = 0; i < Length; i++) - { - ArrayUtilities.GetIndices(strides, IsReversedStride, i, indices); - - if (!comparer.Equals(GetValue(i), other.GetValue(indices))) - { - return false; - } - } - - return true; - } - int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) - { - int hashCode = 0; - // this ignores shape, which is fine it just means we'll have hash collisions for things - // with the same content and different shape. - for (int i = 0; i < Length; i++) - { - hashCode ^= comparer.GetHashCode(GetValue(i)!); - } - - return hashCode; - } - #endregion - - #region Translations - - /// - /// Creates a copy of this tensor as a DenseTensor<T>. If this tensor is already a DenseTensor<T> calling this method is equivalent to calling Clone(). - /// - /// - public virtual DenseTensor ToDenseTensor() - { - var denseTensor = new DenseTensor(Dimensions, IsReversedStride); - for (int i = 0; i < Length; i++) - { - denseTensor.SetValue(i, GetValue(i)); - } - return denseTensor; - } - - - /// - /// Creates a copy of this tensor as a SparseTensor<T>. If this tensor is already a SparseTensor<T> calling this method is equivalent to calling Clone(). - /// - /// - public virtual SparseTensor ToSparseTensor() - { - var sparseTensor = new SparseTensor(Dimensions, IsReversedStride); - for (int i = 0; i < Length; i++) - { - sparseTensor.SetValue(i, GetValue(i)); - } - return sparseTensor; - } - - /// - /// Creates a copy of this tensor as a CompressedSparseTensor<T>. If this tensor is already a CompressedSparseTensor<T> calling this method is equivalent to calling Clone(). - /// - /// - public virtual CompressedSparseTensor ToCompressedSparseTensor() - { - var compressedSparseTensor = new CompressedSparseTensor(Dimensions, IsReversedStride); - for (int i = 0; i < Length; i++) - { - compressedSparseTensor.SetValue(i, GetValue(i)); - } - return compressedSparseTensor; - } - - #endregion - - public string GetArrayString(bool includeWhitespace = true) - { - var builder = new StringBuilder(); - - var strides = ArrayUtilities.GetStrides(dimensions); - var indices = new int[Rank]; - var innerDimension = Rank - 1; - var innerLength = dimensions[innerDimension]; - - int indent = 0; - for (int outerIndex = 0; outerIndex < Length; outerIndex += innerLength) - { - ArrayUtilities.GetIndices(strides, false, outerIndex, indices); - - while ((indent < innerDimension) && (indices[indent] == 0)) - { - // start up - if (includeWhitespace) - { - Indent(builder, indent); - } - indent++; - builder.Append('{'); - if (includeWhitespace) - { - builder.AppendLine(); - } - } - - for (int innerIndex = 0; innerIndex < innerLength; innerIndex++) - { - indices[innerDimension] = innerIndex; - - if ((innerIndex == 0)) - { - if (includeWhitespace) - { - Indent(builder, indent); - } - builder.Append('{'); - } - else - { - builder.Append(','); - } - builder.Append(this[indices]); - } - builder.Append('}'); - - for (int i = Rank - 2; i >= 0; i--) - { - var lastIndex = dimensions[i] - 1; - if (indices[i] == lastIndex) - { - // close out - --indent; - if (includeWhitespace) - { - builder.AppendLine(); - Indent(builder, indent); - } - builder.Append('}'); - } - else - { - builder.Append(','); - if (includeWhitespace) - { - builder.AppendLine(); - } - break; - } - } - } - - return builder.ToString(); - } - - private static void Indent(StringBuilder builder, int tabs, int spacesPerTab = 4) - { - for (int tab = 0; tab < tabs; tab++) - { - for (int space = 0; space < spacesPerTab; space++) - { - builder.Append(' '); - } - } - } - - private static bool IsCompatibleObject(object value) - { - // Non-null values are fine. Only accept nulls if T is a class or Nullable. - // Note that default(T) is not equal to null for value types except when T is Nullable. - return ((value is T) || (value == null && default(T) == null)); - } - } -} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.cs new file mode 100644 index 00000000000000..a400095b08ad39 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.cs @@ -0,0 +1,824 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + /// Performs primitive tensor operations over spans of memory. + public static partial class TensorPrimitives + { + /// Computes the element-wise result of: + . + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// This method effectively does [i] = [i] + [i]. + public static unsafe void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) => + InvokeSpanSpanIntoSpan(x, y, destination); + + /// Computes the element-wise result of: + . + /// The first tensor, represented as a span. + /// The second tensor, represented as a scalar. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// This method effectively does [i] = [i] + . + public static void Add(ReadOnlySpan x, float y, Span destination) => + InvokeSpanScalarIntoSpan(x, y, destination); + + /// Computes the element-wise result of: - . + /// The first tensor, represented as a span. + /// The second tensor, represented as a scalar. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// This method effectively does [i] = [i] - [i]. + public static void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) => + InvokeSpanSpanIntoSpan(x, y, destination); + + /// Computes the element-wise result of: - . + /// The first tensor, represented as a span. + /// The second tensor, represented as a scalar. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// This method effectively does [i] = [i] - . + public static void Subtract(ReadOnlySpan x, float y, Span destination) => + InvokeSpanScalarIntoSpan(x, y, destination); + + /// Computes the element-wise result of: * . + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// This method effectively does [i] = [i] * . + public static void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) => + InvokeSpanSpanIntoSpan(x, y, destination); + + /// Computes the element-wise result of: * . + /// The first tensor, represented as a span. + /// The second tensor, represented as a scalar. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// + /// This method effectively does [i] = [i] * . + /// This method corresponds to the scal method defined by BLAS1. + /// + public static void Multiply(ReadOnlySpan x, float y, Span destination) => + InvokeSpanScalarIntoSpan(x, y, destination); + + /// Computes the element-wise result of: / . + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// This method effectively does [i] = [i] / . + public static void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) => + InvokeSpanSpanIntoSpan(x, y, destination); + + /// Computes the element-wise result of: / . + /// The first tensor, represented as a span. + /// The second tensor, represented as a scalar. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// This method effectively does [i] = [i] / . + public static void Divide(ReadOnlySpan x, float y, Span destination) => + InvokeSpanScalarIntoSpan(x, y, destination); + + /// Computes the element-wise result of: -. + /// The tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// This method effectively does [i] = -[i]. + public static void Negate(ReadOnlySpan x, Span destination) => + InvokeSpanIntoSpan(x, destination); + + /// Computes the element-wise result of: ( + ) * . + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The third tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// This method effectively does [i] = ([i] + [i]) * [i]. + public static void AddMultiply(ReadOnlySpan x, ReadOnlySpan y, ReadOnlySpan multiplier, Span destination) => + InvokeSpanSpanSpanIntoSpan(x, y, multiplier, destination); + + /// Computes the element-wise result of: ( + ) * . + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The third tensor, represented as a scalar. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// This method effectively does [i] = ([i] + [i]) * . + public static void AddMultiply(ReadOnlySpan x, ReadOnlySpan y, float multiplier, Span destination) => + InvokeSpanSpanScalarIntoSpan(x, y, multiplier, destination); + + /// Computes the element-wise result of: ( + ) * . + /// The first tensor, represented as a span. + /// The second tensor, represented as a scalar. + /// The third tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// This method effectively does [i] = ([i] + ) * [i]. + public static void AddMultiply(ReadOnlySpan x, float y, ReadOnlySpan multiplier, Span destination) => + InvokeSpanScalarSpanIntoSpan(x, y, multiplier, destination); + + /// Computes the element-wise result of: ( * ) + . + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The third tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// This method effectively does [i] = ([i] * [i]) + [i]. + public static void MultiplyAdd(ReadOnlySpan x, ReadOnlySpan y, ReadOnlySpan addend, Span destination) => + InvokeSpanSpanSpanIntoSpan(x, y, addend, destination); + + /// Computes the element-wise result of: ( * ) + . + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The third tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// + /// This method effectively does [i] = ([i] * [i]) + . + /// This method corresponds to the axpy method defined by BLAS1. + /// + public static void MultiplyAdd(ReadOnlySpan x, ReadOnlySpan y, float addend, Span destination) => + InvokeSpanSpanScalarIntoSpan(x, y, addend, destination); + + /// Computes the element-wise result of: ( * ) + . + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The third tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// This method effectively does [i] = ([i] * ) + [i]. + public static void MultiplyAdd(ReadOnlySpan x, float y, ReadOnlySpan addend, Span destination) => + InvokeSpanScalarSpanIntoSpan(x, y, addend, destination); + + /// Computes the element-wise result of: pow(e, ). + /// The tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// This method effectively does [i] = .Exp([i]). + public static void Exp(ReadOnlySpan x, Span destination) + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + for (int i = 0; i < x.Length; i++) + { + destination[i] = MathF.Exp(x[i]); + } + } + + /// Computes the element-wise result of: ln(). + /// The tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// This method effectively does [i] = .Log([i]). + public static void Log(ReadOnlySpan x, Span destination) + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + for (int i = 0; i < x.Length; i++) + { + destination[i] = MathF.Log(x[i]); + } + } + + /// Computes the element-wise result of: cosh(). + /// The tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// This method effectively does [i] = .Cosh([i]). + public static void Cosh(ReadOnlySpan x, Span destination) + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + for (int i = 0; i < x.Length; i++) + { + destination[i] = MathF.Cosh(x[i]); + } + } + + /// Computes the element-wise result of: sinh(). + /// The tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// This method effectively does [i] = .Sinh([i]). + public static void Sinh(ReadOnlySpan x, Span destination) + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + for (int i = 0; i < x.Length; i++) + { + destination[i] = MathF.Sinh(x[i]); + } + } + + /// Computes the element-wise result of: tanh(). + /// The tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// This method effectively does [i] = .Tanh([i]). + public static void Tanh(ReadOnlySpan x, Span destination) + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + for (int i = 0; i < x.Length; i++) + { + destination[i] = MathF.Tanh(x[i]); + } + } + + /// Computes the cosine similarity between two non-zero vectors. + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The cosine similarity between the two vectors. + /// Length of '' must be same as length of ''. + /// '' and '' must not be empty. + public static float CosineSimilarity(ReadOnlySpan x, ReadOnlySpan y) + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + return CosineSimilarityCore(x, y); + } + + /// + /// Compute the distance between two points in Euclidean space. + /// + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The Euclidean distance. + /// Length of '' must be same as length of ''. + /// '' and '' must not be empty. + public static float Distance(ReadOnlySpan x, ReadOnlySpan y) + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + return MathF.Sqrt(Aggregate(0f, x, y)); + } + + /// + /// A mathematical operation that takes two vectors and returns a scalar. + /// + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The dot product. + /// Length of '' must be same as length of ''. + public static float Dot(ReadOnlySpan x, ReadOnlySpan y) // BLAS1: dot + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + return Aggregate(0f, x, y); + } + + /// + /// A mathematical operation that takes a vector and returns the L2 norm. + /// + /// The first tensor, represented as a span. + /// The L2 norm. + public static float L2Normalize(ReadOnlySpan x) // BLAS1: nrm2 + { + return MathF.Sqrt(Aggregate(0f, x)); + } + + /// + /// A function that takes a collection of real numbers and returns a probability distribution. + /// + /// The first tensor, represented as a span. + /// The destination tensor. + /// Destination is too short. + /// '' must not be empty. + public static void SoftMax(ReadOnlySpan x, Span destination) + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + float expSum = 0f; + + for (int i = 0; i < x.Length; i++) + { + expSum += MathF.Pow((float)Math.E, x[i]); + } + + for (int i = 0; i < x.Length; i++) + { + destination[i] = MathF.Exp(x[i]) / expSum; + } + } + + /// + /// A function that takes a real number and returns a value between 0 and 1. + /// + /// The first tensor, represented as a span. + /// The destination tensor. + /// Destination is too short. + /// '' must not be empty. + public static void Sigmoid(ReadOnlySpan x, Span destination) + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + for (int i = 0; i < x.Length; i++) + { + destination[i] = 1f / (1 + MathF.Exp(-x[i])); + } + } + + /// Computes the maximum element in . + /// The tensor, represented as a span. + /// The maximum element in . + /// Length of '' must be greater than zero. + public static float Max(ReadOnlySpan x) + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + + float result = float.NegativeInfinity; + + for (int i = 0; i < x.Length; i++) + { + // This matches the IEEE 754:2019 `maximum` function. + // It propagates NaN inputs back to the caller and + // otherwise returns the greater of the inputs. + // It treats +0 as greater than -0 as per the specification. + + float current = x[i]; + + if (current != result) + { + if (float.IsNaN(current)) + { + return current; + } + + if (result < current) + { + result = current; + } + } + else if (IsNegative(result)) + { + result = current; + } + } + + return result; + } + + /// Computes the minimum element in . + /// The tensor, represented as a span. + /// The minimum element in . + /// Length of '' must be greater than zero. + public static float Min(ReadOnlySpan x) + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + + float result = float.PositiveInfinity; + + for (int i = 0; i < x.Length; i++) + { + // This matches the IEEE 754:2019 `minimum` function + // It propagates NaN inputs back to the caller and + // otherwise returns the lesser of the inputs. + // It treats +0 as greater than -0 as per the specification. + + float current = x[i]; + + if (current != result) + { + if (float.IsNaN(current)) + { + return current; + } + + if (current < result) + { + result = current; + } + } + else if (IsNegative(current)) + { + result = current; + } + } + + return result; + } + + /// Computes the maximum magnitude of any element in . + /// The tensor, represented as a span. + /// The maximum magnitude of any element in . + /// Length of '' must be greater than zero. + public static float MaxMagnitude(ReadOnlySpan x) + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + + float result = float.NegativeInfinity; + float resultMag = float.NegativeInfinity; + + for (int i = 0; i < x.Length; i++) + { + // This matches the IEEE 754:2019 `maximumMagnitude` function. + // It propagates NaN inputs back to the caller and + // otherwise returns the input with a greater magnitude. + // It treats +0 as greater than -0 as per the specification. + + float current = x[i]; + float currentMag = Math.Abs(current); + + if (currentMag != resultMag) + { + if (float.IsNaN(currentMag)) + { + return currentMag; + } + + if (resultMag < currentMag) + { + result = current; + resultMag = currentMag; + } + } + else if (IsNegative(result)) + { + result = current; + resultMag = currentMag; + } + } + + return resultMag; + } + + /// Computes the minimum magnitude of any element in . + /// The tensor, represented as a span. + /// The minimum magnitude of any element in . + /// Length of '' must be greater than zero. + public static float MinMagnitude(ReadOnlySpan x) + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + + float resultMag = float.PositiveInfinity; + + for (int i = 0; i < x.Length; i++) + { + // This matches the IEEE 754:2019 `minimumMagnitude` function. + // It propagates NaN inputs back to the caller and + // otherwise returns the input with a lesser magnitude. + // It treats +0 as greater than -0 as per the specification. + + float current = x[i]; + float currentMag = Math.Abs(current); + + if (currentMag != resultMag) + { + if (float.IsNaN(currentMag)) + { + return currentMag; + } + + if (currentMag < resultMag) + { + resultMag = currentMag; + } + } + else if (IsNegative(current)) + { + resultMag = currentMag; + } + } + + return resultMag; + } + + /// Computes the index of the maximum element in . + /// The tensor, represented as a span. + /// The index of the maximum element in , or -1 if is empty. + public static unsafe int IndexOfMax(ReadOnlySpan x) + { + int result = -1; + + if (!x.IsEmpty) + { + float max = float.NegativeInfinity; + + for (int i = 0; i < x.Length; i++) + { + // This matches the IEEE 754:2019 `maximum` function. + // It propagates NaN inputs back to the caller and + // otherwise returns the greater of the inputs. + // It treats +0 as greater than -0 as per the specification. + + float current = x[i]; + + if (current != max) + { + if (float.IsNaN(current)) + { + return i; + } + + if (max < current) + { + result = i; + max = current; + } + } + else if (IsNegative(max) && !IsNegative(current)) + { + result = i; + max = current; + } + } + } + + return result; + } + + /// Computes the index of the minimum element in . + /// The tensor, represented as a span. + /// The index of the minimum element in , or -1 if is empty. + public static unsafe int IndexOfMin(ReadOnlySpan x) + { + int result = -1; + + if (!x.IsEmpty) + { + float min = float.PositiveInfinity; + + for (int i = 0; i < x.Length; i++) + { + // This matches the IEEE 754:2019 `minimum` function. + // It propagates NaN inputs back to the caller and + // otherwise returns the lesser of the inputs. + // It treats +0 as greater than -0 as per the specification. + + float current = x[i]; + + if (current != min) + { + if (float.IsNaN(current)) + { + return i; + } + + if (current < min) + { + result = i; + min = current; + } + } + else if (IsNegative(current) && !IsNegative(min)) + { + result = i; + min = current; + } + } + } + + return result; + } + + /// Computes the index of the element in with the maximum magnitude. + /// The tensor, represented as a span. + /// The index of the element with the maximum magnitude, or -1 if is empty. + /// This method corresponds to the iamax method defined by BLAS1. + public static unsafe int IndexOfMaxMagnitude(ReadOnlySpan x) + { + int result = -1; + + if (!x.IsEmpty) + { + float max = float.NegativeInfinity; + float maxMag = float.NegativeInfinity; + + for (int i = 0; i < x.Length; i++) + { + // This matches the IEEE 754:2019 `maximumMagnitude` function. + // It propagates NaN inputs back to the caller and + // otherwise returns the input with a greater magnitude. + // It treats +0 as greater than -0 as per the specification. + + float current = x[i]; + float currentMag = Math.Abs(current); + + if (currentMag != maxMag) + { + if (float.IsNaN(currentMag)) + { + return i; + } + + if (maxMag < currentMag) + { + result = i; + max = current; + maxMag = currentMag; + } + } + else if (IsNegative(max) && !IsNegative(current)) + { + result = i; + max = current; + maxMag = currentMag; + } + } + } + + return result; + } + + /// Computes the index of the element in with the minimum magnitude. + /// The tensor, represented as a span. + /// The index of the element with the minimum magnitude, or -1 if is empty. + public static unsafe int IndexOfMinMagnitude(ReadOnlySpan x) + { + int result = -1; + + if (!x.IsEmpty) + { + float min = float.PositiveInfinity; + float minMag = float.PositiveInfinity; + + for (int i = 0; i < x.Length; i++) + { + // This matches the IEEE 754:2019 `minimumMagnitude` function + // It propagates NaN inputs back to the caller and + // otherwise returns the input with a lesser magnitude. + // It treats +0 as greater than -0 as per the specification. + + float current = x[i]; + float currentMag = Math.Abs(current); + + if (currentMag != minMag) + { + if (float.IsNaN(currentMag)) + { + return i; + } + + if (currentMag < minMag) + { + result = i; + min = current; + minMag = currentMag; + } + } + else if (IsNegative(current) && !IsNegative(min)) + { + result = i; + min = current; + minMag = currentMag; + } + } + } + + return result; + } + + /// Computes the sum of all elements in . + /// The tensor, represented as a span. + /// The result of adding all elements in , or zero if is empty. + public static float Sum(ReadOnlySpan x) => + Aggregate(0f, x); + + /// Computes the sum of the squares of every element in . + /// The tensor, represented as a span. + /// The result of adding every element in multiplied by itself, or zero if is empty. + /// This method effectively does .Sum(.Multiply(, )). + public static float SumOfSquares(ReadOnlySpan x) => + Aggregate(0f, x); + + /// Computes the sum of the absolute values of every element in . + /// The tensor, represented as a span. + /// The result of adding the absolute value of every element in , or zero if is empty. + /// + /// This method effectively does .Sum(.Abs()). + /// This method corresponds to the asum method defined by BLAS1. + /// + public static float SumOfMagnitudes(ReadOnlySpan x) => + Aggregate(0f, x); + + /// Computes the product of all elements in . + /// The tensor, represented as a span. + /// The result of multiplying all elements in . + /// Length of '' must be greater than zero. + public static float Product(ReadOnlySpan x) + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + + return Aggregate(1.0f, x); + } + + /// Computes the product of the element-wise result of: + . + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The result of multiplying the element-wise additions of the elements in each tensor. + /// Length of both input spans must be greater than zero. + /// and must have the same length. + /// This method effectively does .Product(.Add(, )). + public static float ProductOfSums(ReadOnlySpan x, ReadOnlySpan y) + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + return Aggregate(1.0f, x, y); + } + + /// Computes the product of the element-wise result of: - . + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The result of multiplying the element-wise subtraction of the elements in the second tensor from the first tensor. + /// Length of both input spans must be greater than zero. + /// and must have the same length. + /// This method effectively does .Product(.Subtract(, )). + public static float ProductOfDifferences(ReadOnlySpan x, ReadOnlySpan y) + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + return Aggregate(1.0f, x, y); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs new file mode 100644 index 00000000000000..4f40aa31494c97 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs @@ -0,0 +1,1263 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; + +namespace System.Numerics.Tensors +{ + public static partial class TensorPrimitives + { + /// + /// Copies to , converting each + /// value to its nearest representable half-precision floating-point value. + /// + /// The source span from which to copy values. + /// The destination span into which the converted values should be written. + /// Destination is too short. + public static void ConvertToHalf(ReadOnlySpan source, Span destination) + { + if (source.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + for (int i = 0; i < source.Length; i++) + { + destination[i] = (Half)source[i]; + } + } + + /// + /// Copies to , converting each half-precision + /// floating-point value to its nearest representable value. + /// + /// The source span from which to copy values. + /// The destination span into which the converted values should be written. + /// Destination is too short. + public static void ConvertToSingle(ReadOnlySpan source, Span destination) + { + if (source.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + for (int i = 0; i < source.Length; i++) + { + destination[i] = (float)source[i]; + } + } + + private static bool IsNegative(float f) => float.IsNegative(f); + + private static float CosineSimilarityCore(ReadOnlySpan x, ReadOnlySpan y) + { + // Compute the same as: + // TensorPrimitives.Dot(x, y) / (Math.Sqrt(TensorPrimitives.SumOfSquares(x)) * Math.Sqrt(TensorPrimitives.SumOfSquares(y))) + // but only looping over each span once. + + float dotProduct = 0f; + float xSumOfSquares = 0f; + float ySumOfSquares = 0f; + + int i = 0; + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated && x.Length >= Vector512.Count) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + + Vector512 dotProductVector = Vector512.Zero; + Vector512 xSumOfSquaresVector = Vector512.Zero; + Vector512 ySumOfSquaresVector = Vector512.Zero; + + // Process vectors, summing their dot products and squares, as long as there's a vector's worth remaining. + int oneVectorFromEnd = x.Length - Vector512.Count; + do + { + Vector512 xVec = Vector512.LoadUnsafe(ref xRef, (uint)i); + Vector512 yVec = Vector512.LoadUnsafe(ref yRef, (uint)i); + + dotProductVector += xVec * yVec; + xSumOfSquaresVector += xVec * xVec; + ySumOfSquaresVector += yVec * yVec; + + i += Vector512.Count; + } + while (i <= oneVectorFromEnd); + + // Sum the vector lanes into the scalar result. + dotProduct += Vector512.Sum(dotProductVector); + xSumOfSquares += Vector512.Sum(xSumOfSquaresVector); + ySumOfSquares += Vector512.Sum(ySumOfSquaresVector); + } + else +#endif + if (Vector256.IsHardwareAccelerated && x.Length >= Vector256.Count) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + + Vector256 dotProductVector = Vector256.Zero; + Vector256 xSumOfSquaresVector = Vector256.Zero; + Vector256 ySumOfSquaresVector = Vector256.Zero; + + // Process vectors, summing their dot products and squares, as long as there's a vector's worth remaining. + int oneVectorFromEnd = x.Length - Vector256.Count; + do + { + Vector256 xVec = Vector256.LoadUnsafe(ref xRef, (uint)i); + Vector256 yVec = Vector256.LoadUnsafe(ref yRef, (uint)i); + + dotProductVector += xVec * yVec; + xSumOfSquaresVector += xVec * xVec; + ySumOfSquaresVector += yVec * yVec; + + i += Vector256.Count; + } + while (i <= oneVectorFromEnd); + + // Sum the vector lanes into the scalar result. + dotProduct += Vector256.Sum(dotProductVector); + xSumOfSquares += Vector256.Sum(xSumOfSquaresVector); + ySumOfSquares += Vector256.Sum(ySumOfSquaresVector); + } + else if (Vector128.IsHardwareAccelerated && x.Length >= Vector128.Count) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + + Vector128 dotProductVector = Vector128.Zero; + Vector128 xSumOfSquaresVector = Vector128.Zero; + Vector128 ySumOfSquaresVector = Vector128.Zero; + + // Process vectors, summing their dot products and squares, as long as there's a vector's worth remaining. + int oneVectorFromEnd = x.Length - Vector128.Count; + do + { + Vector128 xVec = Vector128.LoadUnsafe(ref xRef, (uint)i); + Vector128 yVec = Vector128.LoadUnsafe(ref yRef, (uint)i); + + dotProductVector += xVec * yVec; + xSumOfSquaresVector += xVec * xVec; + ySumOfSquaresVector += yVec * yVec; + + i += Vector128.Count; + } + while (i <= oneVectorFromEnd); + + // Sum the vector lanes into the scalar result. + dotProduct += Vector128.Sum(dotProductVector); + xSumOfSquares += Vector128.Sum(xSumOfSquaresVector); + ySumOfSquares += Vector128.Sum(ySumOfSquaresVector); + } + + // Process any remaining elements past the last vector. + for (; (uint)i < (uint)x.Length; i++) + { + dotProduct += x[i] * y[i]; + xSumOfSquares += x[i] * x[i]; + ySumOfSquares += y[i] * y[i]; + } + + // Sum(X * Y) / (|X| * |Y|) + return dotProduct / (MathF.Sqrt(xSumOfSquares) * MathF.Sqrt(ySumOfSquares)); + } + + private static float Aggregate( + float identityValue, ReadOnlySpan x) + where TLoad : IUnaryOperator + where TAggregate : IBinaryOperator + { + // Initialize the result to the identity value + float result = identityValue; + int i = 0; + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated && x.Length >= Vector512.Count * 2) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + + // Load the first vector as the initial set of results + Vector512 resultVector = TLoad.Invoke(Vector512.LoadUnsafe(ref xRef, 0)); + int oneVectorFromEnd = x.Length - Vector512.Count; + + // Aggregate additional vectors into the result as long as there's at + // least one full vector left to process. + i = Vector512.Count; + do + { + resultVector = TAggregate.Invoke(resultVector, TLoad.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i))); + i += Vector512.Count; + } + while (i <= oneVectorFromEnd); + + // Aggregate the lanes in the vector back into the scalar result + result = TAggregate.Invoke(result, TAggregate.Invoke(resultVector)); + } + else +#endif + if (Vector256.IsHardwareAccelerated && x.Length >= Vector256.Count * 2) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + + // Load the first vector as the initial set of results + Vector256 resultVector = TLoad.Invoke(Vector256.LoadUnsafe(ref xRef, 0)); + int oneVectorFromEnd = x.Length - Vector256.Count; + + // Aggregate additional vectors into the result as long as there's at + // least one full vector left to process. + i = Vector256.Count; + do + { + resultVector = TAggregate.Invoke(resultVector, TLoad.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i))); + i += Vector256.Count; + } + while (i <= oneVectorFromEnd); + + // Aggregate the lanes in the vector back into the scalar result + result = TAggregate.Invoke(result, TAggregate.Invoke(resultVector)); + } + else if (Vector128.IsHardwareAccelerated && x.Length >= Vector128.Count * 2) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + + // Load the first vector as the initial set of results + Vector128 resultVector = TLoad.Invoke(Vector128.LoadUnsafe(ref xRef, 0)); + int oneVectorFromEnd = x.Length - Vector128.Count; + + // Aggregate additional vectors into the result as long as there's at + // least one full vector left to process. + i = Vector128.Count; + do + { + resultVector = TAggregate.Invoke(resultVector, TLoad.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i))); + i += Vector128.Count; + } + while (i <= oneVectorFromEnd); + + // Aggregate the lanes in the vector back into the scalar result + result = TAggregate.Invoke(result, TAggregate.Invoke(resultVector)); + } + + // Aggregate the remaining items in the input span. + for (; (uint)i < (uint)x.Length; i++) + { + result = TAggregate.Invoke(result, TLoad.Invoke(x[i])); + } + + return result; + } + + private static float Aggregate( + float identityValue, ReadOnlySpan x, ReadOnlySpan y) + where TBinary : IBinaryOperator + where TAggregate : IBinaryOperator + { + // Initialize the result to the identity value + float result = identityValue; + int i = 0; + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated && x.Length >= Vector512.Count * 2) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + + // Load the first vector as the initial set of results + Vector512 resultVector = TBinary.Invoke(Vector512.LoadUnsafe(ref xRef, 0), Vector512.LoadUnsafe(ref yRef, 0)); + int oneVectorFromEnd = x.Length - Vector512.Count; + + // Aggregate additional vectors into the result as long as there's at + // least one full vector left to process. + i = Vector512.Count; + do + { + resultVector = TAggregate.Invoke(resultVector, TBinary.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i), Vector512.LoadUnsafe(ref yRef, (uint)i))); + i += Vector512.Count; + } + while (i <= oneVectorFromEnd); + + // Aggregate the lanes in the vector back into the scalar result + result = TAggregate.Invoke(result, TAggregate.Invoke(resultVector)); + } + else +#endif + if (Vector256.IsHardwareAccelerated && x.Length >= Vector256.Count * 2) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + + // Load the first vector as the initial set of results + Vector256 resultVector = TBinary.Invoke(Vector256.LoadUnsafe(ref xRef, 0), Vector256.LoadUnsafe(ref yRef, 0)); + int oneVectorFromEnd = x.Length - Vector256.Count; + + // Aggregate additional vectors into the result as long as there's at + // least one full vector left to process. + i = Vector256.Count; + do + { + resultVector = TAggregate.Invoke(resultVector, TBinary.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i), Vector256.LoadUnsafe(ref yRef, (uint)i))); + i += Vector256.Count; + } + while (i <= oneVectorFromEnd); + + // Aggregate the lanes in the vector back into the scalar result + result = TAggregate.Invoke(result, TAggregate.Invoke(resultVector)); + } + else if (Vector128.IsHardwareAccelerated && x.Length >= Vector128.Count * 2) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + + // Load the first vector as the initial set of results + Vector128 resultVector = TBinary.Invoke(Vector128.LoadUnsafe(ref xRef, 0), Vector128.LoadUnsafe(ref yRef, 0)); + int oneVectorFromEnd = x.Length - Vector128.Count; + + // Aggregate additional vectors into the result as long as there's at + // least one full vector left to process. + i = Vector128.Count; + do + { + resultVector = TAggregate.Invoke(resultVector, TBinary.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i), Vector128.LoadUnsafe(ref yRef, (uint)i))); + i += Vector128.Count; + } + while (i <= oneVectorFromEnd); + + // Aggregate the lanes in the vector back into the scalar result + result = TAggregate.Invoke(result, TAggregate.Invoke(resultVector)); + } + + // Aggregate the remaining items in the input span. + for (; (uint)i < (uint)x.Length; i++) + { + result = TAggregate.Invoke(result, TBinary.Invoke(x[i], y[i])); + } + + return result; + } + + private static unsafe void InvokeSpanIntoSpan( + ReadOnlySpan x, Span destination) + where TUnaryOperator : IUnaryOperator + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float dRef = ref MemoryMarshal.GetReference(destination); + int i = 0, oneVectorFromEnd; + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector512.Count; + if (i <= oneVectorFromEnd) + { + // Loop handling one vector at a time. + do + { + TUnaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + + i += Vector512.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector512.Count); + TUnaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } +#endif + + if (Vector256.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector256.Count; + if (i <= oneVectorFromEnd) + { + // Loop handling one vector at a time. + do + { + TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + + i += Vector256.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector256.Count); + TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } + + if (Vector128.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector128.Count; + if (i <= oneVectorFromEnd) + { + // Loop handling one vector at a time. + do + { + TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + + i += Vector128.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector128.Count); + TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } + + while (i < x.Length) + { + Unsafe.Add(ref dRef, i) = TUnaryOperator.Invoke(Unsafe.Add(ref xRef, i)); + + i++; + } + } + + private static unsafe void InvokeSpanSpanIntoSpan( + ReadOnlySpan x, ReadOnlySpan y, Span destination) + where TBinaryOperator : IBinaryOperator + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float dRef = ref MemoryMarshal.GetReference(destination); + int i = 0, oneVectorFromEnd; + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector512.Count; + if (i <= oneVectorFromEnd) + { + // Loop handling one vector at a time. + do + { + TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i), + Vector512.LoadUnsafe(ref yRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + + i += Vector512.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector512.Count); + TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, lastVectorIndex), + Vector512.LoadUnsafe(ref yRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } +#endif + + if (Vector256.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector256.Count; + if (i <= oneVectorFromEnd) + { + // Loop handling one vector at a time. + do + { + TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i), + Vector256.LoadUnsafe(ref yRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + + i += Vector256.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector256.Count); + TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, lastVectorIndex), + Vector256.LoadUnsafe(ref yRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } + + if (Vector128.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector128.Count; + if (i <= oneVectorFromEnd) + { + // Loop handling one vector at a time. + do + { + TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i), + Vector128.LoadUnsafe(ref yRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + + i += Vector128.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector128.Count); + TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, lastVectorIndex), + Vector128.LoadUnsafe(ref yRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } + + while (i < x.Length) + { + Unsafe.Add(ref dRef, i) = TBinaryOperator.Invoke(Unsafe.Add(ref xRef, i), + Unsafe.Add(ref yRef, i)); + + i++; + } + } + + private static unsafe void InvokeSpanScalarIntoSpan( + ReadOnlySpan x, float y, Span destination) + where TBinaryOperator : IBinaryOperator + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float dRef = ref MemoryMarshal.GetReference(destination); + int i = 0, oneVectorFromEnd; + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector512.Count; + if (i <= oneVectorFromEnd) + { + Vector512 yVec = Vector512.Create(y); + + // Loop handling one vector at a time. + do + { + TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i), + yVec).StoreUnsafe(ref dRef, (uint)i); + + i += Vector512.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector512.Count); + TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, lastVectorIndex), + yVec).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } +#endif + + if (Vector256.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector256.Count; + if (i <= oneVectorFromEnd) + { + Vector256 yVec = Vector256.Create(y); + + // Loop handling one vector at a time. + do + { + TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i), + yVec).StoreUnsafe(ref dRef, (uint)i); + + i += Vector256.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector256.Count); + TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, lastVectorIndex), + yVec).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } + + if (Vector128.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector128.Count; + if (i <= oneVectorFromEnd) + { + Vector128 yVec = Vector128.Create(y); + + // Loop handling one vector at a time. + do + { + TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i), + yVec).StoreUnsafe(ref dRef, (uint)i); + + i += Vector128.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector128.Count); + TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, lastVectorIndex), + yVec).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } + + while (i < x.Length) + { + Unsafe.Add(ref dRef, i) = TBinaryOperator.Invoke(Unsafe.Add(ref xRef, i), + y); + + i++; + } + } + + private static unsafe void InvokeSpanSpanSpanIntoSpan( + ReadOnlySpan x, ReadOnlySpan y, ReadOnlySpan z, Span destination) + where TTernaryOperator : ITernaryOperator + { + if (x.Length != y.Length || x.Length != z.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float zRef = ref MemoryMarshal.GetReference(z); + ref float dRef = ref MemoryMarshal.GetReference(destination); + int i = 0, oneVectorFromEnd; + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector512.Count; + if (i <= oneVectorFromEnd) + { + // Loop handling one vector at a time. + do + { + TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i), + Vector512.LoadUnsafe(ref yRef, (uint)i), + Vector512.LoadUnsafe(ref zRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + + i += Vector512.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector512.Count); + TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, lastVectorIndex), + Vector512.LoadUnsafe(ref yRef, lastVectorIndex), + Vector512.LoadUnsafe(ref zRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } +#endif + + if (Vector256.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector256.Count; + if (i <= oneVectorFromEnd) + { + // Loop handling one vector at a time. + do + { + TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i), + Vector256.LoadUnsafe(ref yRef, (uint)i), + Vector256.LoadUnsafe(ref zRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + + i += Vector256.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector256.Count); + TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, lastVectorIndex), + Vector256.LoadUnsafe(ref yRef, lastVectorIndex), + Vector256.LoadUnsafe(ref zRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } + + if (Vector128.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector128.Count; + if (i <= oneVectorFromEnd) + { + // Loop handling one vector at a time. + do + { + TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i), + Vector128.LoadUnsafe(ref yRef, (uint)i), + Vector128.LoadUnsafe(ref zRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + + i += Vector128.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector128.Count); + TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, lastVectorIndex), + Vector128.LoadUnsafe(ref yRef, lastVectorIndex), + Vector128.LoadUnsafe(ref zRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } + + while (i < x.Length) + { + Unsafe.Add(ref dRef, i) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, i), + Unsafe.Add(ref yRef, i), + Unsafe.Add(ref zRef, i)); + + i++; + } + } + + private static unsafe void InvokeSpanSpanScalarIntoSpan( + ReadOnlySpan x, ReadOnlySpan y, float z, Span destination) + where TTernaryOperator : ITernaryOperator + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float dRef = ref MemoryMarshal.GetReference(destination); + int i = 0, oneVectorFromEnd; + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector512.Count; + if (i <= oneVectorFromEnd) + { + Vector512 zVec = Vector512.Create(z); + + // Loop handling one vector at a time. + do + { + TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i), + Vector512.LoadUnsafe(ref yRef, (uint)i), + zVec).StoreUnsafe(ref dRef, (uint)i); + + i += Vector512.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector512.Count); + TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, lastVectorIndex), + Vector512.LoadUnsafe(ref yRef, lastVectorIndex), + zVec).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } +#endif + + if (Vector256.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector256.Count; + if (i <= oneVectorFromEnd) + { + Vector256 zVec = Vector256.Create(z); + + // Loop handling one vector at a time. + do + { + TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i), + Vector256.LoadUnsafe(ref yRef, (uint)i), + zVec).StoreUnsafe(ref dRef, (uint)i); + + i += Vector256.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector256.Count); + TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, lastVectorIndex), + Vector256.LoadUnsafe(ref yRef, lastVectorIndex), + zVec).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } + + if (Vector128.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector128.Count; + if (i <= oneVectorFromEnd) + { + Vector128 zVec = Vector128.Create(z); + + // Loop handling one vector at a time. + do + { + TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i), + Vector128.LoadUnsafe(ref yRef, (uint)i), + zVec).StoreUnsafe(ref dRef, (uint)i); + + i += Vector128.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector128.Count); + TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, lastVectorIndex), + Vector128.LoadUnsafe(ref yRef, lastVectorIndex), + zVec).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } + + while (i < x.Length) + { + Unsafe.Add(ref dRef, i) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, i), + Unsafe.Add(ref yRef, i), + z); + + i++; + } + } + + private static unsafe void InvokeSpanScalarSpanIntoSpan( + ReadOnlySpan x, float y, ReadOnlySpan z, Span destination) + where TTernaryOperator : ITernaryOperator + { + if (x.Length != z.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float zRef = ref MemoryMarshal.GetReference(z); + ref float dRef = ref MemoryMarshal.GetReference(destination); + int i = 0, oneVectorFromEnd; + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector512.Count; + if (i <= oneVectorFromEnd) + { + Vector512 yVec = Vector512.Create(y); + + // Loop handling one vector at a time. + do + { + TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i), + yVec, + Vector512.LoadUnsafe(ref zRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + + i += Vector512.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector512.Count); + TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, lastVectorIndex), + yVec, + Vector512.LoadUnsafe(ref zRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } +#endif + + if (Vector256.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector256.Count; + if (i <= oneVectorFromEnd) + { + Vector256 yVec = Vector256.Create(y); + + // Loop handling one vector at a time. + do + { + TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i), + yVec, + Vector256.LoadUnsafe(ref zRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + + i += Vector256.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector256.Count); + TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, lastVectorIndex), + yVec, + Vector256.LoadUnsafe(ref zRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } + + if (Vector128.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector128.Count; + if (i <= oneVectorFromEnd) + { + Vector128 yVec = Vector128.Create(y); + + // Loop handling one vector at a time. + do + { + TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i), + yVec, + Vector128.LoadUnsafe(ref zRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + + i += Vector128.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + uint lastVectorIndex = (uint)(x.Length - Vector128.Count); + TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, lastVectorIndex), + yVec, + Vector128.LoadUnsafe(ref zRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + } + + return; + } + } + + while (i < x.Length) + { + Unsafe.Add(ref dRef, i) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, i), + y, + Unsafe.Add(ref zRef, i)); + + i++; + } + } + + private readonly struct AddOperator : IBinaryOperator + { + public static float Invoke(float x, float y) => x + y; + public static Vector128 Invoke(Vector128 x, Vector128 y) => x + y; + public static Vector256 Invoke(Vector256 x, Vector256 y) => x + y; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x, Vector512 y) => x + y; +#endif + + public static float Invoke(Vector128 x) => Vector128.Sum(x); + public static float Invoke(Vector256 x) => Vector256.Sum(x); +#if NET8_0_OR_GREATER + public static float Invoke(Vector512 x) => Vector512.Sum(x); +#endif + } + + private readonly struct SubtractOperator : IBinaryOperator + { + public static float Invoke(float x, float y) => x - y; + public static Vector128 Invoke(Vector128 x, Vector128 y) => x - y; + public static Vector256 Invoke(Vector256 x, Vector256 y) => x - y; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x, Vector512 y) => x - y; +#endif + + public static float Invoke(Vector128 x) => throw new NotSupportedException(); + public static float Invoke(Vector256 x) => throw new NotSupportedException(); +#if NET8_0_OR_GREATER + public static float Invoke(Vector512 x) => throw new NotSupportedException(); +#endif + } + + private readonly struct SubtractSquaredOperator : IBinaryOperator + { + public static float Invoke(float x, float y) + { + float tmp = x - y; + return tmp * tmp; + } + + public static Vector128 Invoke(Vector128 x, Vector128 y) + { + Vector128 tmp = x - y; + return tmp * tmp; + } + + public static Vector256 Invoke(Vector256 x, Vector256 y) + { + Vector256 tmp = x - y; + return tmp * tmp; + } + +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x, Vector512 y) + { + Vector512 tmp = x - y; + return tmp * tmp; + } +#endif + + public static float Invoke(Vector128 x) => throw new NotSupportedException(); + public static float Invoke(Vector256 x) => throw new NotSupportedException(); +#if NET8_0_OR_GREATER + public static float Invoke(Vector512 x) => throw new NotSupportedException(); +#endif + } + + private readonly struct MultiplyOperator : IBinaryOperator + { + public static float Invoke(float x, float y) => x * y; + public static Vector128 Invoke(Vector128 x, Vector128 y) => x * y; + public static Vector256 Invoke(Vector256 x, Vector256 y) => x * y; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x, Vector512 y) => x * y; +#endif + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Invoke(Vector128 x) + { + float f = x[0]; + for (int i = 1; i < Vector128.Count; i++) + { + f *= x[i]; + } + return f; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Invoke(Vector256 x) + { + float f = x[0]; + for (int i = 1; i < Vector256.Count; i++) + { + f *= x[i]; + } + return f; + } + +#if NET8_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Invoke(Vector512 x) + { + float f = x[0]; + for (int i = 1; i < Vector512.Count; i++) + { + f *= x[i]; + } + return f; + } +#endif + } + + private readonly struct DivideOperator : IBinaryOperator + { + public static float Invoke(float x, float y) => x / y; + public static Vector128 Invoke(Vector128 x, Vector128 y) => x / y; + public static Vector256 Invoke(Vector256 x, Vector256 y) => x / y; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x, Vector512 y) => x / y; +#endif + + public static float Invoke(Vector128 x) => throw new NotSupportedException(); + public static float Invoke(Vector256 x) => throw new NotSupportedException(); +#if NET8_0_OR_GREATER + public static float Invoke(Vector512 x) => throw new NotSupportedException(); +#endif + } + + private readonly struct NegateOperator : IUnaryOperator + { + public static float Invoke(float x) => -x; + public static Vector128 Invoke(Vector128 x) => -x; + public static Vector256 Invoke(Vector256 x) => -x; + public static Vector512 Invoke(Vector512 x) => -x; + } + + private readonly struct AddMultiplyOperator : ITernaryOperator + { + public static float Invoke(float x, float y, float z) => (x + y) * z; + public static Vector128 Invoke(Vector128 x, Vector128 y, Vector128 z) => (x + y) * z; + public static Vector256 Invoke(Vector256 x, Vector256 y, Vector256 z) => (x + y) * z; + public static Vector512 Invoke(Vector512 x, Vector512 y, Vector512 z) => (x + y) * z; + } + + private readonly struct MultiplyAddOperator : ITernaryOperator + { + public static float Invoke(float x, float y, float z) => (x * y) + z; + public static Vector128 Invoke(Vector128 x, Vector128 y, Vector128 z) => (x * y) + z; + public static Vector256 Invoke(Vector256 x, Vector256 y, Vector256 z) => (x * y) + z; + public static Vector512 Invoke(Vector512 x, Vector512 y, Vector512 z) => (x * y) + z; + } + + private readonly struct LoadIdentity : IUnaryOperator + { + public static float Invoke(float x) => x; + public static Vector128 Invoke(Vector128 x) => x; + public static Vector256 Invoke(Vector256 x) => x; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x) => x; +#endif + } + + private readonly struct LoadSquared : IUnaryOperator + { + public static float Invoke(float x) => x * x; + public static Vector128 Invoke(Vector128 x) => x * x; + public static Vector256 Invoke(Vector256 x) => x * x; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x) => x * x; +#endif + } + + private readonly struct LoadAbsolute : IUnaryOperator + { + public static float Invoke(float x) => MathF.Abs(x); + + public static Vector128 Invoke(Vector128 x) + { + Vector128 raw = x.AsUInt32(); + Vector128 mask = Vector128.Create((uint)0x7FFFFFFF); + return (raw & mask).AsSingle(); + } + + public static Vector256 Invoke(Vector256 x) + { + Vector256 raw = x.AsUInt32(); + Vector256 mask = Vector256.Create((uint)0x7FFFFFFF); + return (raw & mask).AsSingle(); + } + +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x) + { + Vector512 raw = x.AsUInt32(); + Vector512 mask = Vector512.Create((uint)0x7FFFFFFF); + return (raw & mask).AsSingle(); + } +#endif + } + + private interface IUnaryOperator + { + static abstract float Invoke(float x); + static abstract Vector128 Invoke(Vector128 x); + static abstract Vector256 Invoke(Vector256 x); +#if NET8_0_OR_GREATER + static abstract Vector512 Invoke(Vector512 x); +#endif + } + + private interface IBinaryOperator + { + static abstract float Invoke(float x, float y); + + static abstract Vector128 Invoke(Vector128 x, Vector128 y); + static abstract float Invoke(Vector128 x); + static abstract Vector256 Invoke(Vector256 x, Vector256 y); + static abstract float Invoke(Vector256 x); +#if NET8_0_OR_GREATER + static abstract Vector512 Invoke(Vector512 x, Vector512 y); + static abstract float Invoke(Vector512 x); +#endif + } + + private interface ITernaryOperator + { + static abstract float Invoke(float x, float y, float z); + static abstract Vector128 Invoke(Vector128 x, Vector128 y, Vector128 z); + static abstract Vector256 Invoke(Vector256 x, Vector256 y, Vector256 z); +#if NET8_0_OR_GREATER + static abstract Vector512 Invoke(Vector512 x, Vector512 y, Vector512 z); +#endif + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs new file mode 100644 index 00000000000000..134364708b8e5d --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs @@ -0,0 +1,596 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Numerics.Tensors +{ + public static partial class TensorPrimitives + { + private static unsafe bool IsNegative(float f) => *(int*)&f < 0; + + private static float CosineSimilarityCore(ReadOnlySpan x, ReadOnlySpan y) + { + // Compute the same as: + // TensorPrimitives.Dot(x, y) / (Math.Sqrt(TensorPrimitives.SumOfSquares(x)) * Math.Sqrt(TensorPrimitives.SumOfSquares(y))) + // but only looping over each span once. + + float dotProduct = 0f; + float xSumOfSquares = 0f; + float ySumOfSquares = 0f; + + int i = 0; + + if (Vector.IsHardwareAccelerated && x.Length >= Vector.Count) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + + Vector dotProductVector = Vector.Zero; + Vector xSumOfSquaresVector = Vector.Zero; + Vector ySumOfSquaresVector = Vector.Zero; + + // Process vectors, summing their dot products and squares, as long as there's a vector's worth remaining. + int oneVectorFromEnd = x.Length - Vector.Count; + do + { + Vector xVec = AsVector(ref xRef, i); + Vector yVec = AsVector(ref yRef, i); + + dotProductVector += xVec * yVec; + xSumOfSquaresVector += xVec * xVec; + ySumOfSquaresVector += yVec * yVec; + + i += Vector.Count; + } + while (i <= oneVectorFromEnd); + + // Sum the vector lanes into the scalar result. + for (int e = 0; e < Vector.Count; e++) + { + dotProduct += dotProductVector[e]; + xSumOfSquares += xSumOfSquaresVector[e]; + ySumOfSquares += ySumOfSquaresVector[e]; + } + } + + // Process any remaining elements past the last vector. + for (; (uint)i < (uint)x.Length; i++) + { + dotProduct += x[i] * y[i]; + xSumOfSquares += x[i] * x[i]; + ySumOfSquares += y[i] * y[i]; + } + + // Sum(X * Y) / (|X| * |Y|) + return dotProduct / (MathF.Sqrt(xSumOfSquares) * MathF.Sqrt(ySumOfSquares)); + } + + private static float Aggregate( + float identityValue, ReadOnlySpan x, TLoad load = default, TAggregate aggregate = default) + where TLoad : IUnaryOperator + where TAggregate : IBinaryOperator + { + // Initialize the result to the identity value + float result = identityValue; + int i = 0; + + if (Vector.IsHardwareAccelerated && x.Length >= Vector.Count * 2) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + + // Load the first vector as the initial set of results + Vector resultVector = load.Invoke(AsVector(ref xRef, 0)); + int oneVectorFromEnd = x.Length - Vector.Count; + + // Aggregate additional vectors into the result as long as there's at + // least one full vector left to process. + i = Vector.Count; + do + { + resultVector = aggregate.Invoke(resultVector, load.Invoke(AsVector(ref xRef, i))); + i += Vector.Count; + } + while (i <= oneVectorFromEnd); + + // Aggregate the lanes in the vector back into the scalar result + for (int f = 0; f < Vector.Count; f++) + { + result = aggregate.Invoke(result, resultVector[f]); + } + } + + // Aggregate the remaining items in the input span. + for (; (uint)i < (uint)x.Length; i++) + { + result = aggregate.Invoke(result, load.Invoke(x[i])); + } + + return result; + } + + private static float Aggregate( + float identityValue, ReadOnlySpan x, ReadOnlySpan y, TBinary binary = default, TAggregate aggregate = default) + where TBinary : IBinaryOperator + where TAggregate : IBinaryOperator + { + // Initialize the result to the identity value + float result = identityValue; + int i = 0; + + if (Vector.IsHardwareAccelerated && x.Length >= Vector.Count * 2) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + + // Load the first vector as the initial set of results + Vector resultVector = binary.Invoke(AsVector(ref xRef, 0), AsVector(ref yRef, 0)); + int oneVectorFromEnd = x.Length - Vector.Count; + + // Aggregate additional vectors into the result as long as there's at + // least one full vector left to process. + i = Vector.Count; + do + { + resultVector = aggregate.Invoke(resultVector, binary.Invoke(AsVector(ref xRef, i), AsVector(ref yRef, i))); + i += Vector.Count; + } + while (i <= oneVectorFromEnd); + + // Aggregate the lanes in the vector back into the scalar result + for (int f = 0; f < Vector.Count; f++) + { + result = aggregate.Invoke(result, resultVector[f]); + } + } + + // Aggregate the remaining items in the input span. + for (; (uint)i < (uint)x.Length; i++) + { + result = aggregate.Invoke(result, binary.Invoke(x[i], y[i])); + } + + return result; + } + + private static void InvokeSpanIntoSpan( + ReadOnlySpan x, Span destination, TUnaryOperator op = default) + where TUnaryOperator : IUnaryOperator + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float dRef = ref MemoryMarshal.GetReference(destination); + int i = 0, oneVectorFromEnd; + + if (Vector.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector.Count; + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + AsVector(ref dRef, i) = op.Invoke(AsVector(ref xRef, i)); + + i += Vector.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + int lastVectorIndex = x.Length - Vector.Count; + AsVector(ref dRef, lastVectorIndex) = op.Invoke(AsVector(ref xRef, lastVectorIndex)); + } + + return; + } + } + + // Loop handling one element at a time. + while (i < x.Length) + { + Unsafe.Add(ref dRef, i) = op.Invoke(Unsafe.Add(ref xRef, i)); + + i++; + } + } + + private static void InvokeSpanSpanIntoSpan( + ReadOnlySpan x, ReadOnlySpan y, Span destination, TBinaryOperator op = default) + where TBinaryOperator : IBinaryOperator + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float dRef = ref MemoryMarshal.GetReference(destination); + int i = 0, oneVectorFromEnd; + + if (Vector.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector.Count; + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + AsVector(ref dRef, i) = op.Invoke(AsVector(ref xRef, i), + AsVector(ref yRef, i)); + + i += Vector.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + int lastVectorIndex = x.Length - Vector.Count; + AsVector(ref dRef, lastVectorIndex) = op.Invoke(AsVector(ref xRef, lastVectorIndex), + AsVector(ref yRef, lastVectorIndex)); + } + + return; + } + } + + while (i < x.Length) + { + Unsafe.Add(ref dRef, i) = op.Invoke(Unsafe.Add(ref xRef, i), + Unsafe.Add(ref yRef, i)); + + i++; + } + } + + private static void InvokeSpanScalarIntoSpan( + ReadOnlySpan x, float y, Span destination, TBinaryOperator op = default) + where TBinaryOperator : IBinaryOperator + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float dRef = ref MemoryMarshal.GetReference(destination); + int i = 0, oneVectorFromEnd; + + if (Vector.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector.Count; + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + Vector yVec = new(y); + do + { + AsVector(ref dRef, i) = op.Invoke(AsVector(ref xRef, i), + yVec); + + i += Vector.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + int lastVectorIndex = x.Length - Vector.Count; + AsVector(ref dRef, lastVectorIndex) = op.Invoke(AsVector(ref xRef, lastVectorIndex), + yVec); + } + + return; + } + } + + // Loop handling one element at a time. + while (i < x.Length) + { + Unsafe.Add(ref dRef, i) = op.Invoke(Unsafe.Add(ref xRef, i), + y); + + i++; + } + } + + private static void InvokeSpanSpanSpanIntoSpan( + ReadOnlySpan x, ReadOnlySpan y, ReadOnlySpan z, Span destination, TTernaryOperator op = default) + where TTernaryOperator : ITernaryOperator + { + if (x.Length != y.Length || x.Length != z.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float zRef = ref MemoryMarshal.GetReference(z); + ref float dRef = ref MemoryMarshal.GetReference(destination); + int i = 0, oneVectorFromEnd; + + if (Vector.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector.Count; + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + AsVector(ref dRef, i) = op.Invoke(AsVector(ref xRef, i), + AsVector(ref yRef, i), + AsVector(ref zRef, i)); + + i += Vector.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + int lastVectorIndex = x.Length - Vector.Count; + AsVector(ref dRef, lastVectorIndex) = op.Invoke(AsVector(ref xRef, lastVectorIndex), + AsVector(ref yRef, lastVectorIndex), + AsVector(ref zRef, lastVectorIndex)); + } + + return; + } + } + + // Loop handling one element at a time. + while (i < x.Length) + { + Unsafe.Add(ref dRef, i) = op.Invoke(Unsafe.Add(ref xRef, i), + Unsafe.Add(ref yRef, i), + Unsafe.Add(ref zRef, i)); + + i++; + } + } + + private static void InvokeSpanSpanScalarIntoSpan( + ReadOnlySpan x, ReadOnlySpan y, float z, Span destination, TTernaryOperator op = default) + where TTernaryOperator : ITernaryOperator + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float dRef = ref MemoryMarshal.GetReference(destination); + int i = 0, oneVectorFromEnd; + + if (Vector.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector.Count; + if (oneVectorFromEnd >= 0) + { + Vector zVec = new(z); + + // Loop handling one vector at a time. + do + { + AsVector(ref dRef, i) = op.Invoke(AsVector(ref xRef, i), + AsVector(ref yRef, i), + zVec); + + i += Vector.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + int lastVectorIndex = x.Length - Vector.Count; + AsVector(ref dRef, lastVectorIndex) = op.Invoke(AsVector(ref xRef, lastVectorIndex), + AsVector(ref yRef, lastVectorIndex), + zVec); + } + + return; + } + } + + // Loop handling one element at a time. + while (i < x.Length) + { + Unsafe.Add(ref dRef, i) = op.Invoke(Unsafe.Add(ref xRef, i), + Unsafe.Add(ref yRef, i), + z); + + i++; + } + } + + private static void InvokeSpanScalarSpanIntoSpan( + ReadOnlySpan x, float y, ReadOnlySpan z, Span destination, TTernaryOperator op = default) + where TTernaryOperator : ITernaryOperator + { + if (x.Length != z.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float zRef = ref MemoryMarshal.GetReference(z); + ref float dRef = ref MemoryMarshal.GetReference(destination); + int i = 0, oneVectorFromEnd; + + if (Vector.IsHardwareAccelerated) + { + oneVectorFromEnd = x.Length - Vector.Count; + if (oneVectorFromEnd >= 0) + { + Vector yVec = new(y); + + // Loop handling one vector at a time. + do + { + AsVector(ref dRef, i) = op.Invoke(AsVector(ref xRef, i), + yVec, + AsVector(ref zRef, i)); + + i += Vector.Count; + } + while (i <= oneVectorFromEnd); + + // Handle any remaining elements with a final vector. + if (i != x.Length) + { + int lastVectorIndex = x.Length - Vector.Count; + AsVector(ref dRef, lastVectorIndex) = op.Invoke(AsVector(ref xRef, lastVectorIndex), + yVec, + AsVector(ref zRef, lastVectorIndex)); + } + + return; + } + } + + // Loop handling one element at a time. + while (i < x.Length) + { + Unsafe.Add(ref dRef, i) = op.Invoke(Unsafe.Add(ref xRef, i), + y, + Unsafe.Add(ref zRef, i)); + + i++; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ref Vector AsVector(ref float start, int offset) => + ref Unsafe.As>( + ref Unsafe.Add(ref start, offset)); + + private readonly struct AddOperator : IBinaryOperator + { + public float Invoke(float x, float y) => x + y; + public Vector Invoke(Vector x, Vector y) => x + y; + } + + private readonly struct SubtractOperator : IBinaryOperator + { + public float Invoke(float x, float y) => x - y; + public Vector Invoke(Vector x, Vector y) => x - y; + } + + private readonly struct SubtractSquaredOperator : IBinaryOperator + { + public float Invoke(float x, float y) + { + float tmp = x - y; + return tmp * tmp; + } + + public Vector Invoke(Vector x, Vector y) + { + Vector tmp = x - y; + return tmp * tmp; + } + } + + private readonly struct MultiplyOperator : IBinaryOperator + { + public float Invoke(float x, float y) => x * y; + public Vector Invoke(Vector x, Vector y) => x * y; + } + + private readonly struct DivideOperator : IBinaryOperator + { + public float Invoke(float x, float y) => x / y; + public Vector Invoke(Vector x, Vector y) => x / y; + } + + private readonly struct NegateOperator : IUnaryOperator + { + public float Invoke(float x) => -x; + public Vector Invoke(Vector x) => -x; + } + + private readonly struct AddMultiplyOperator : ITernaryOperator + { + public float Invoke(float x, float y, float z) => (x + y) * z; + public Vector Invoke(Vector x, Vector y, Vector z) => (x + y) * z; + } + + private readonly struct MultiplyAddOperator : ITernaryOperator + { + public float Invoke(float x, float y, float z) => (x * y) + z; + public Vector Invoke(Vector x, Vector y, Vector z) => (x * y) + z; + } + + private readonly struct LoadIdentity : IUnaryOperator + { + public float Invoke(float x) => x; + public Vector Invoke(Vector x) => x; + } + + private readonly struct LoadSquared : IUnaryOperator + { + public float Invoke(float x) => x * x; + public Vector Invoke(Vector x) => x * x; + } + + private readonly struct LoadAbsolute : IUnaryOperator + { + public float Invoke(float x) => MathF.Abs(x); + + public Vector Invoke(Vector x) + { + Vector raw = Vector.AsVectorUInt32(x); + Vector mask = new Vector(0x7FFFFFFF); + return Vector.AsVectorSingle(raw & mask); + } + } + + private interface IUnaryOperator + { + float Invoke(float x); + Vector Invoke(Vector x); + } + + private interface IBinaryOperator + { + float Invoke(float x, float y); + Vector Invoke(Vector x, Vector y); + } + + private interface ITernaryOperator + { + float Invoke(float x, float y, float z); + Vector Invoke(Vector x, Vector y, Vector z); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs b/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs new file mode 100644 index 00000000000000..902b27787e856c --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; + +namespace System +{ + internal static class ThrowHelper + { + [DoesNotReturn] + public static void ThrowArgument_DestinationTooShort() => + throw new ArgumentException(SR.Argument_DestinationTooShort, "destination"); + + [DoesNotReturn] + public static void ThrowArgument_SpansMustHaveSameLength() => + throw new ArgumentException(SR.Argument_SpansMustHaveSameLength); + + [DoesNotReturn] + public static void ThrowArgument_SpansMustBeNonEmpty() => + throw new ArgumentException(SR.Argument_SpansMustBeNonEmpty); + } +} diff --git a/src/libraries/System.Numerics.Tensors/tests/NativeMemory.cs b/src/libraries/System.Numerics.Tensors/tests/NativeMemory.cs deleted file mode 100644 index b5c9ef8c2c2c92..00000000000000 --- a/src/libraries/System.Numerics.Tensors/tests/NativeMemory.cs +++ /dev/null @@ -1,108 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Buffers; -using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; -using System.Threading; - -namespace System.Numerics.Tensors.Tests -{ - public class NativeMemory : MemoryManager - { - private bool disposed = false; - private int refCount = 0; - private IntPtr memory; - private int length; - - public NativeMemory(IntPtr memory, int length) - { - this.memory = memory; - this.length = length; - } - - public unsafe NativeMemory(void* memory, int length) - { - this.memory = (IntPtr)memory; - this.length = length; - } - - ~NativeMemory() - { - Dispose(false); - } - - public static NativeMemory Allocate(int length) - { - // typically this would call into a native method appropriate for the platform - // or the constructors above would be used to wrap the native pointer - IntPtr memory = Marshal.AllocHGlobal(Marshal.SizeOf() * length); - return new NativeMemory(memory, length); - } - - public bool IsDisposed => disposed; - - public unsafe override Span GetSpan() => new Span((void*)memory, length); - - protected bool IsRetained => refCount > 0; - - public override MemoryHandle Pin(int elementIndex = 0) - { - unsafe - { - Retain(); - if ((uint)elementIndex > length) throw new ArgumentOutOfRangeException(nameof(elementIndex)); - void* pointer = Unsafe.Add((void*)memory, elementIndex); - return new MemoryHandle(pointer, default, this); - } - } - - public bool Release() - { - int newRefCount = Interlocked.Decrement(ref refCount); - - if (newRefCount < 0) - { - throw new InvalidOperationException("Unmatched Release/Retain"); - } - - return newRefCount != 0; - } - - public void Retain() - { - if (disposed) - { - throw new ObjectDisposedException(nameof(NativeMemory)); - } - - Interlocked.Increment(ref refCount); - } - - protected override void Dispose(bool disposing) - { - if (disposed) - { - return; - } - - // typically this would call into a native method appropriate for the platform - Marshal.FreeHGlobal(memory); - memory = IntPtr.Zero; - - disposed = true; - } - - protected override bool TryGetArray(out ArraySegment arraySegment) - { - // cannot expose managed array - arraySegment = default; - return false; - } - - public override void Unpin() - { - Release(); - } - } -} diff --git a/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj b/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj index 042e4791b6a3d8..be4a103d7256ce 100644 --- a/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj +++ b/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj @@ -1,41 +1,21 @@ + - true $(NetCoreAppCurrent);$(NetFrameworkMinimum) + true + - - - True - True - TensorArithmetic.tt - - - - True - True - TensorOperations.tt - - - + - - - TextTemplatingFileGenerator - TensorArithmetic.cs - - - TextTemplatingFileGenerator - TensorOperations.cs - - + + + + - - - - + \ No newline at end of file diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorArithmetic.cs b/src/libraries/System.Numerics.Tensors/tests/TensorArithmetic.cs deleted file mode 100644 index 6dae2ec6854252..00000000000000 --- a/src/libraries/System.Numerics.Tensors/tests/TensorArithmetic.cs +++ /dev/null @@ -1,16165 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Numerics.Tensors -{ - internal interface ITensorArithmetic - { - T One { get; } - T Zero { get; } - void Add(Tensor left, Tensor right, Tensor result); - void Add(Tensor tensor, T scalar, Tensor result); - void And(Tensor left, Tensor right, Tensor result); - void And(Tensor tensor, T scalar, Tensor result); - void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result); - void Decrement(Tensor tensor, Tensor result); - void Divide(Tensor left, Tensor right, Tensor result); - void Divide(Tensor tensor, T scalar, Tensor result); - void Equals(Tensor left, Tensor right, Tensor result); - void GreaterThan(Tensor left, Tensor right, Tensor result); - void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result); - void Increment(Tensor tensor, Tensor result); - void LeftShift(Tensor tensor, int value, Tensor result); - void LessThan(Tensor left, Tensor right, Tensor result); - void LessThanOrEqual(Tensor left, Tensor right, Tensor result); - void Modulo(Tensor left, Tensor right, Tensor result); - void Modulo(Tensor tensor, T scalar, Tensor result); - void Multiply(Tensor left, Tensor right, Tensor result); - void Multiply(Tensor tensor, T scalar, Tensor result); - void NotEquals(Tensor left, Tensor right, Tensor result); - void Or(Tensor left, Tensor right, Tensor result); - void Or(Tensor tensor, T scalar, Tensor result); - void RightShift(Tensor tensor, int value, Tensor result); - void Subtract(Tensor left, Tensor right, Tensor result); - void Subtract(Tensor tensor, T scalar, Tensor result); - void UnaryMinus(Tensor tensor, Tensor result); - void UnaryPlus(Tensor tensor, Tensor result); - void Xor(Tensor left, Tensor right, Tensor result); - void Xor(Tensor tensor, T scalar, Tensor result); - } - - internal static class TensorArithmetic - { - public static ITensorArithmetic Instance => TensorArithmetic.GetArithmetic(); - } - - internal static class TensorArithmetic - { - public static ITensorArithmetic GetArithmetic() - { - if (typeof(T) == typeof(bool)) - { - return (ITensorArithmetic)new BoolArithmetic(); - } - else if (typeof(T) == typeof(byte)) - { - return (ITensorArithmetic)new ByteArithmetic(); - } - else if (typeof(T) == typeof(char)) - { - return (ITensorArithmetic)new CharArithmetic(); - } - else if (typeof(T) == typeof(decimal)) - { - return (ITensorArithmetic)new DecimalArithmetic(); - } - else if (typeof(T) == typeof(double)) - { - return (ITensorArithmetic)new DoubleArithmetic(); - } - else if (typeof(T) == typeof(float)) - { - return (ITensorArithmetic)new FloatArithmetic(); - } - else if (typeof(T) == typeof(int)) - { - return (ITensorArithmetic)new IntArithmetic(); - } - else if (typeof(T) == typeof(long)) - { - return (ITensorArithmetic)new LongArithmetic(); - } - else if (typeof(T) == typeof(sbyte)) - { - return (ITensorArithmetic)new SByteArithmetic(); - } - else if (typeof(T) == typeof(short)) - { - return (ITensorArithmetic)new ShortArithmetic(); - } - else if (typeof(T) == typeof(uint)) - { - return (ITensorArithmetic)new UIntArithmetic(); - } - else if (typeof(T) == typeof(ulong)) - { - return (ITensorArithmetic)new ULongArithmetic(); - } - else if (typeof(T) == typeof(ushort)) - { - return (ITensorArithmetic)new UShortArithmetic(); - } - return null; - } - } - - internal class BoolArithmetic : ITensorArithmetic - { - public bool One => true; - public bool Zero => false; - - public void Add(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void Add(Tensor tensor, bool scalar, Tensor result) - { - throw new NotSupportedException(); - } - public void And(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (bool)(left[indices] & right[indices]); - } - - } - public void And(Tensor tensor, bool scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (bool)(tensor[indices] & scalar); - } - - } - public void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - throw new NotSupportedException(); - } - public void Decrement(Tensor tensor, Tensor result) - { - throw new NotSupportedException(); - } - public void Divide(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void Divide(Tensor tensor, bool scalar, Tensor result) - { - throw new NotSupportedException(); - } - public void Equals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] == right[indices]; - } - - } - public void GreaterThan(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void Increment(Tensor tensor, Tensor result) - { - throw new NotSupportedException(); - } - public void LeftShift(Tensor tensor, int value, Tensor result) - { - throw new NotSupportedException(); - } - public void LessThan(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void Modulo(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void Modulo(Tensor tensor, bool scalar, Tensor result) - { - throw new NotSupportedException(); - } - public void Multiply(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void Multiply(Tensor tensor, bool scalar, Tensor result) - { - throw new NotSupportedException(); - } - public void NotEquals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] != right[indices]; - } - - } - public void Or(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (bool)(left[indices] | right[indices]); - } - - } - public void Or(Tensor tensor, bool scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (bool)(tensor[indices] | scalar); - } - - } - public void RightShift(Tensor tensor, int value, Tensor result) - { - throw new NotSupportedException(); - } - public void Subtract(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void Subtract(Tensor tensor, bool scalar, Tensor result) - { - throw new NotSupportedException(); - } - public void UnaryMinus(Tensor tensor, Tensor result) - { - throw new NotSupportedException(); - } - public void UnaryPlus(Tensor tensor, Tensor result) - { - throw new NotSupportedException(); - } - public void Xor(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (bool)(left[indices] ^ right[indices]); - } - - } - public void Xor(Tensor tensor, bool scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (bool)(tensor[indices] ^ scalar); - } - - } - - public void Add(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Add(DenseTensor tensor, bool scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - public void And(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (bool)(leftSpan[i] & rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (bool)(leftSpan[op1Index] & rightSpan[op2Index]); - - } - } - } - public void And(DenseTensor tensor, bool scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (bool)(tensorSpan[i] & scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (bool)(tensorSpan[op1Index] & scalar); - - } - } - } - public void Contract(DenseTensor left, DenseTensor right, int[] leftAxes, int[] rightAxes, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Decrement(DenseTensor tensor, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Divide(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Divide(DenseTensor tensor, bool scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Equals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] == rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] == rightSpan[op2Index]; - - } - } - } - public void GreaterThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void GreaterThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Increment(DenseTensor tensor, DenseTensor result) - { - throw new NotSupportedException(); - } - public void LeftShift(DenseTensor tensor, int value, DenseTensor result) - { - throw new NotSupportedException(); - } - public void LessThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void LessThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Modulo(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Modulo(DenseTensor tensor, bool scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Multiply(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Multiply(DenseTensor tensor, bool scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - public void NotEquals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] != rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] != rightSpan[op2Index]; - - } - } - } - public void Or(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (bool)(leftSpan[i] | rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (bool)(leftSpan[op1Index] | rightSpan[op2Index]); - - } - } - } - public void Or(DenseTensor tensor, bool scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (bool)(tensorSpan[i] | scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (bool)(tensorSpan[op1Index] | scalar); - - } - } - } - public void RightShift(DenseTensor tensor, int value, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Subtract(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Subtract(DenseTensor tensor, bool scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - public void UnaryMinus(DenseTensor tensor, DenseTensor result) - { - throw new NotSupportedException(); - } - public void UnaryPlus(DenseTensor tensor, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Xor(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (bool)(leftSpan[i] ^ rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (bool)(leftSpan[op1Index] ^ rightSpan[op2Index]); - - } - } - } - public void Xor(DenseTensor tensor, bool scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (bool)(tensorSpan[i] ^ scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (bool)(tensorSpan[op1Index] ^ scalar); - - } - } - } - } - internal class ByteArithmetic : ITensorArithmetic - { - public byte One => 1; - public byte Zero => 0; - - public void Add(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(left[indices] + right[indices]); - } - - } - public void Add(Tensor tensor, byte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(tensor[indices] + scalar); - } - - } - public void And(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(left[indices] & right[indices]); - } - - } - public void And(Tensor tensor, byte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(tensor[indices] & scalar); - } - - } - public void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var leftIndices = new int[left.Rank]; - var rightIndices = new int[right.Rank]; - var resultIndices = new int[result.Rank]; - - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - for (int resultIndex = 0; resultIndex < result.Length; resultIndex++) - { - byte sum = (byte)0; - - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, resultIndex, resultIndices); - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - // todo, make this more efficient - ArrayUtilities.GetIndices(left.strides, left.IsReversedStride, leftIndex, leftIndices); - ArrayUtilities.GetIndices(right.strides, right.IsReversedStride, rightIndex, rightIndices); - - sum += (byte)(left[leftIndices] * right[rightIndices]); - } - - result[resultIndices] = sum; - } - } - public void Decrement(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]--; - } - - } - public void Divide(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(left[indices] / right[indices]); - } - - } - public void Divide(Tensor tensor, byte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(tensor[indices] / scalar); - } - - } - public void Equals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] == right[indices]; - } - - } - public void GreaterThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] > right[indices]; - } - - } - public void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] >= right[indices]; - } - - } - public void Increment(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]++; - } - - } - public void LeftShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(tensor[indices] << value); - } - - } - public void LessThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] < right[indices]; - } - - } - public void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] <= right[indices]; - } - - } - public void Modulo(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(left[indices] % right[indices]); - } - - } - public void Modulo(Tensor tensor, byte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(tensor[indices] % scalar); - } - - } - public void Multiply(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(left[indices] * right[indices]); - } - - } - public void Multiply(Tensor tensor, byte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(tensor[indices] * scalar); - } - - } - public void NotEquals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] != right[indices]; - } - - } - public void Or(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(left[indices] | right[indices]); - } - - } - public void Or(Tensor tensor, byte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(tensor[indices] | scalar); - } - - } - public void RightShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(tensor[indices] >> value); - } - - } - public void Subtract(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(left[indices] - right[indices]); - } - - } - public void Subtract(Tensor tensor, byte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(tensor[indices] - scalar); - } - - } - public void UnaryMinus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)-tensor[indices]; - } - - } - public void UnaryPlus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)+tensor[indices]; - } - - } - public void Xor(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(left[indices] ^ right[indices]); - } - - } - public void Xor(Tensor tensor, byte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (byte)(tensor[indices] ^ scalar); - } - - } - - public void Add(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(leftSpan[i] + rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(leftSpan[op1Index] + rightSpan[op2Index]); - - } - } - } - public void Add(DenseTensor tensor, byte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(tensorSpan[i] + scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(tensorSpan[op1Index] + scalar); - - } - } - } - public void And(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(leftSpan[i] & rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(leftSpan[op1Index] & rightSpan[op2Index]); - - } - } - } - public void And(DenseTensor tensor, byte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(tensorSpan[i] & scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(tensorSpan[op1Index] & scalar); - - } - } - } - public void Contract(DenseTensor left, DenseTensor right, int[] leftAxes, int[] rightAxes, DenseTensor result) - { - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - - for (int resultIndex = 0; resultIndex < resultSpan.Length; resultIndex++) - { - byte sum = (byte)0; - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - sum += (byte)(leftSpan[leftIndex] * rightSpan[rightIndex]); - } - - resultSpan[resultIndex] = sum; - } - } - public void Decrement(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]--; - } - } - public void Divide(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(leftSpan[i] / rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(leftSpan[op1Index] / rightSpan[op2Index]); - - } - } - } - public void Divide(DenseTensor tensor, byte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(tensorSpan[i] / scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(tensorSpan[op1Index] / scalar); - - } - } - } - public void Equals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] == rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] == rightSpan[op2Index]; - - } - } - } - public void GreaterThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] > rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] > rightSpan[op2Index]; - - } - } - } - public void GreaterThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] >= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] >= rightSpan[op2Index]; - - } - } - } - public void Increment(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]++; - } - } - public void LeftShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(tensorSpan[i] << value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(tensorSpan[op1Index] << value); - - } - } - } - public void LessThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] < rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] < rightSpan[op2Index]; - - } - } - } - public void LessThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] <= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] <= rightSpan[op2Index]; - - } - } - } - public void Modulo(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(leftSpan[i] % rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(leftSpan[op1Index] % rightSpan[op2Index]); - - } - } - } - public void Modulo(DenseTensor tensor, byte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(tensorSpan[i] % scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(tensorSpan[op1Index] % scalar); - - } - } - } - public void Multiply(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(leftSpan[i] * rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(leftSpan[op1Index] * rightSpan[op2Index]); - - } - } - } - public void Multiply(DenseTensor tensor, byte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(tensorSpan[i] * scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(tensorSpan[op1Index] * scalar); - - } - } - } - public void NotEquals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] != rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] != rightSpan[op2Index]; - - } - } - } - public void Or(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(leftSpan[i] | rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(leftSpan[op1Index] | rightSpan[op2Index]); - - } - } - } - public void Or(DenseTensor tensor, byte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(tensorSpan[i] | scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(tensorSpan[op1Index] | scalar); - - } - } - } - public void RightShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(tensorSpan[i] >> value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(tensorSpan[op1Index] >> value); - - } - } - } - public void Subtract(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(leftSpan[i] - rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(leftSpan[op1Index] - rightSpan[op2Index]); - - } - } - } - public void Subtract(DenseTensor tensor, byte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(tensorSpan[i] - scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(tensorSpan[op1Index] - scalar); - - } - } - } - public void UnaryMinus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)-tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)-tensorSpan[op1Index]; - - } - } - } - public void UnaryPlus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)+tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)+tensorSpan[op1Index]; - - } - } - } - public void Xor(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(leftSpan[i] ^ rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(leftSpan[op1Index] ^ rightSpan[op2Index]); - - } - } - } - public void Xor(DenseTensor tensor, byte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (byte)(tensorSpan[i] ^ scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (byte)(tensorSpan[op1Index] ^ scalar); - - } - } - } - } - internal class CharArithmetic : ITensorArithmetic - { - public char One => (char)1; - public char Zero => (char)0; - - public void Add(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(left[indices] + right[indices]); - } - - } - public void Add(Tensor tensor, char scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(tensor[indices] + scalar); - } - - } - public void And(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(left[indices] & right[indices]); - } - - } - public void And(Tensor tensor, char scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(tensor[indices] & scalar); - } - - } - public void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var leftIndices = new int[left.Rank]; - var rightIndices = new int[right.Rank]; - var resultIndices = new int[result.Rank]; - - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - for (int resultIndex = 0; resultIndex < result.Length; resultIndex++) - { - char sum = (char)0; - - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, resultIndex, resultIndices); - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - // todo, make this more efficient - ArrayUtilities.GetIndices(left.strides, left.IsReversedStride, leftIndex, leftIndices); - ArrayUtilities.GetIndices(right.strides, right.IsReversedStride, rightIndex, rightIndices); - - sum += (char)(left[leftIndices] * right[rightIndices]); - } - - result[resultIndices] = sum; - } - } - public void Decrement(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]--; - } - - } - public void Divide(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(left[indices] / right[indices]); - } - - } - public void Divide(Tensor tensor, char scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(tensor[indices] / scalar); - } - - } - public void Equals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] == right[indices]; - } - - } - public void GreaterThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] > right[indices]; - } - - } - public void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] >= right[indices]; - } - - } - public void Increment(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]++; - } - - } - public void LeftShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(tensor[indices] << value); - } - - } - public void LessThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] < right[indices]; - } - - } - public void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] <= right[indices]; - } - - } - public void Modulo(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(left[indices] % right[indices]); - } - - } - public void Modulo(Tensor tensor, char scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(tensor[indices] % scalar); - } - - } - public void Multiply(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(left[indices] * right[indices]); - } - - } - public void Multiply(Tensor tensor, char scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(tensor[indices] * scalar); - } - - } - public void NotEquals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] != right[indices]; - } - - } - public void Or(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(left[indices] | right[indices]); - } - - } - public void Or(Tensor tensor, char scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(tensor[indices] | scalar); - } - - } - public void RightShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(tensor[indices] >> value); - } - - } - public void Subtract(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(left[indices] - right[indices]); - } - - } - public void Subtract(Tensor tensor, char scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(tensor[indices] - scalar); - } - - } - public void UnaryMinus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)-tensor[indices]; - } - - } - public void UnaryPlus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)+tensor[indices]; - } - - } - public void Xor(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(left[indices] ^ right[indices]); - } - - } - public void Xor(Tensor tensor, char scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (char)(tensor[indices] ^ scalar); - } - - } - - public void Add(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(leftSpan[i] + rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(leftSpan[op1Index] + rightSpan[op2Index]); - - } - } - } - public void Add(DenseTensor tensor, char scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(tensorSpan[i] + scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(tensorSpan[op1Index] + scalar); - - } - } - } - public void And(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(leftSpan[i] & rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(leftSpan[op1Index] & rightSpan[op2Index]); - - } - } - } - public void And(DenseTensor tensor, char scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(tensorSpan[i] & scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(tensorSpan[op1Index] & scalar); - - } - } - } - public void Contract(DenseTensor left, DenseTensor right, int[] leftAxes, int[] rightAxes, DenseTensor result) - { - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - - for (int resultIndex = 0; resultIndex < resultSpan.Length; resultIndex++) - { - char sum = (char)0; - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - sum += (char)(leftSpan[leftIndex] * rightSpan[rightIndex]); - } - - resultSpan[resultIndex] = sum; - } - } - public void Decrement(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]--; - } - } - public void Divide(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(leftSpan[i] / rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(leftSpan[op1Index] / rightSpan[op2Index]); - - } - } - } - public void Divide(DenseTensor tensor, char scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(tensorSpan[i] / scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(tensorSpan[op1Index] / scalar); - - } - } - } - public void Equals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] == rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] == rightSpan[op2Index]; - - } - } - } - public void GreaterThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] > rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] > rightSpan[op2Index]; - - } - } - } - public void GreaterThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] >= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] >= rightSpan[op2Index]; - - } - } - } - public void Increment(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]++; - } - } - public void LeftShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(tensorSpan[i] << value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(tensorSpan[op1Index] << value); - - } - } - } - public void LessThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] < rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] < rightSpan[op2Index]; - - } - } - } - public void LessThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] <= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] <= rightSpan[op2Index]; - - } - } - } - public void Modulo(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(leftSpan[i] % rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(leftSpan[op1Index] % rightSpan[op2Index]); - - } - } - } - public void Modulo(DenseTensor tensor, char scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(tensorSpan[i] % scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(tensorSpan[op1Index] % scalar); - - } - } - } - public void Multiply(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(leftSpan[i] * rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(leftSpan[op1Index] * rightSpan[op2Index]); - - } - } - } - public void Multiply(DenseTensor tensor, char scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(tensorSpan[i] * scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(tensorSpan[op1Index] * scalar); - - } - } - } - public void NotEquals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] != rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] != rightSpan[op2Index]; - - } - } - } - public void Or(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(leftSpan[i] | rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(leftSpan[op1Index] | rightSpan[op2Index]); - - } - } - } - public void Or(DenseTensor tensor, char scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(tensorSpan[i] | scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(tensorSpan[op1Index] | scalar); - - } - } - } - public void RightShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(tensorSpan[i] >> value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(tensorSpan[op1Index] >> value); - - } - } - } - public void Subtract(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(leftSpan[i] - rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(leftSpan[op1Index] - rightSpan[op2Index]); - - } - } - } - public void Subtract(DenseTensor tensor, char scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(tensorSpan[i] - scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(tensorSpan[op1Index] - scalar); - - } - } - } - public void UnaryMinus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)-tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)-tensorSpan[op1Index]; - - } - } - } - public void UnaryPlus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)+tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)+tensorSpan[op1Index]; - - } - } - } - public void Xor(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(leftSpan[i] ^ rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(leftSpan[op1Index] ^ rightSpan[op2Index]); - - } - } - } - public void Xor(DenseTensor tensor, char scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (char)(tensorSpan[i] ^ scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (char)(tensorSpan[op1Index] ^ scalar); - - } - } - } - } - internal class DecimalArithmetic : ITensorArithmetic - { - public decimal One => 1; - public decimal Zero => 0; - - public void Add(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (decimal)(left[indices] + right[indices]); - } - - } - public void Add(Tensor tensor, decimal scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (decimal)(tensor[indices] + scalar); - } - - } - public void And(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void And(Tensor tensor, decimal scalar, Tensor result) - { - throw new NotSupportedException(); - } - public void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var leftIndices = new int[left.Rank]; - var rightIndices = new int[right.Rank]; - var resultIndices = new int[result.Rank]; - - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - for (int resultIndex = 0; resultIndex < result.Length; resultIndex++) - { - decimal sum = (decimal)0; - - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, resultIndex, resultIndices); - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - // todo, make this more efficient - ArrayUtilities.GetIndices(left.strides, left.IsReversedStride, leftIndex, leftIndices); - ArrayUtilities.GetIndices(right.strides, right.IsReversedStride, rightIndex, rightIndices); - - sum += (decimal)(left[leftIndices] * right[rightIndices]); - } - - result[resultIndices] = sum; - } - } - public void Decrement(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]--; - } - - } - public void Divide(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (decimal)(left[indices] / right[indices]); - } - - } - public void Divide(Tensor tensor, decimal scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (decimal)(tensor[indices] / scalar); - } - - } - public void Equals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] == right[indices]; - } - - } - public void GreaterThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] > right[indices]; - } - - } - public void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] >= right[indices]; - } - - } - public void Increment(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]++; - } - - } - public void LeftShift(Tensor tensor, int value, Tensor result) - { - throw new NotSupportedException(); - } - public void LessThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] < right[indices]; - } - - } - public void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] <= right[indices]; - } - - } - public void Modulo(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (decimal)(left[indices] % right[indices]); - } - - } - public void Modulo(Tensor tensor, decimal scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (decimal)(tensor[indices] % scalar); - } - - } - public void Multiply(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (decimal)(left[indices] * right[indices]); - } - - } - public void Multiply(Tensor tensor, decimal scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (decimal)(tensor[indices] * scalar); - } - - } - public void NotEquals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] != right[indices]; - } - - } - public void Or(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void Or(Tensor tensor, decimal scalar, Tensor result) - { - throw new NotSupportedException(); - } - public void RightShift(Tensor tensor, int value, Tensor result) - { - throw new NotSupportedException(); - } - public void Subtract(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (decimal)(left[indices] - right[indices]); - } - - } - public void Subtract(Tensor tensor, decimal scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (decimal)(tensor[indices] - scalar); - } - - } - public void UnaryMinus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (decimal)-tensor[indices]; - } - - } - public void UnaryPlus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (decimal)+tensor[indices]; - } - - } - public void Xor(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void Xor(Tensor tensor, decimal scalar, Tensor result) - { - throw new NotSupportedException(); - } - - public void Add(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (decimal)(leftSpan[i] + rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (decimal)(leftSpan[op1Index] + rightSpan[op2Index]); - - } - } - } - public void Add(DenseTensor tensor, decimal scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (decimal)(tensorSpan[i] + scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (decimal)(tensorSpan[op1Index] + scalar); - - } - } - } - public void And(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void And(DenseTensor tensor, decimal scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Contract(DenseTensor left, DenseTensor right, int[] leftAxes, int[] rightAxes, DenseTensor result) - { - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - - for (int resultIndex = 0; resultIndex < resultSpan.Length; resultIndex++) - { - decimal sum = (decimal)0; - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - sum += (decimal)(leftSpan[leftIndex] * rightSpan[rightIndex]); - } - - resultSpan[resultIndex] = sum; - } - } - public void Decrement(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]--; - } - } - public void Divide(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (decimal)(leftSpan[i] / rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (decimal)(leftSpan[op1Index] / rightSpan[op2Index]); - - } - } - } - public void Divide(DenseTensor tensor, decimal scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (decimal)(tensorSpan[i] / scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (decimal)(tensorSpan[op1Index] / scalar); - - } - } - } - public void Equals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] == rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] == rightSpan[op2Index]; - - } - } - } - public void GreaterThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] > rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] > rightSpan[op2Index]; - - } - } - } - public void GreaterThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] >= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] >= rightSpan[op2Index]; - - } - } - } - public void Increment(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]++; - } - } - public void LeftShift(DenseTensor tensor, int value, DenseTensor result) - { - throw new NotSupportedException(); - } - public void LessThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] < rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] < rightSpan[op2Index]; - - } - } - } - public void LessThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] <= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] <= rightSpan[op2Index]; - - } - } - } - public void Modulo(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (decimal)(leftSpan[i] % rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (decimal)(leftSpan[op1Index] % rightSpan[op2Index]); - - } - } - } - public void Modulo(DenseTensor tensor, decimal scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (decimal)(tensorSpan[i] % scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (decimal)(tensorSpan[op1Index] % scalar); - - } - } - } - public void Multiply(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (decimal)(leftSpan[i] * rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (decimal)(leftSpan[op1Index] * rightSpan[op2Index]); - - } - } - } - public void Multiply(DenseTensor tensor, decimal scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (decimal)(tensorSpan[i] * scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (decimal)(tensorSpan[op1Index] * scalar); - - } - } - } - public void NotEquals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] != rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] != rightSpan[op2Index]; - - } - } - } - public void Or(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Or(DenseTensor tensor, decimal scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - public void RightShift(DenseTensor tensor, int value, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Subtract(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (decimal)(leftSpan[i] - rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (decimal)(leftSpan[op1Index] - rightSpan[op2Index]); - - } - } - } - public void Subtract(DenseTensor tensor, decimal scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (decimal)(tensorSpan[i] - scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (decimal)(tensorSpan[op1Index] - scalar); - - } - } - } - public void UnaryMinus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (decimal)-tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (decimal)-tensorSpan[op1Index]; - - } - } - } - public void UnaryPlus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (decimal)+tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (decimal)+tensorSpan[op1Index]; - - } - } - } - public void Xor(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Xor(DenseTensor tensor, decimal scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - } - internal class DoubleArithmetic : ITensorArithmetic - { - public double One => 1.0; - public double Zero => 0; - - public void Add(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (double)(left[indices] + right[indices]); - } - - } - public void Add(Tensor tensor, double scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (double)(tensor[indices] + scalar); - } - - } - public void And(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void And(Tensor tensor, double scalar, Tensor result) - { - throw new NotSupportedException(); - } - public void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var leftIndices = new int[left.Rank]; - var rightIndices = new int[right.Rank]; - var resultIndices = new int[result.Rank]; - - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - for (int resultIndex = 0; resultIndex < result.Length; resultIndex++) - { - double sum = (double)0; - - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, resultIndex, resultIndices); - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - // todo, make this more efficient - ArrayUtilities.GetIndices(left.strides, left.IsReversedStride, leftIndex, leftIndices); - ArrayUtilities.GetIndices(right.strides, right.IsReversedStride, rightIndex, rightIndices); - - sum += (double)(left[leftIndices] * right[rightIndices]); - } - - result[resultIndices] = sum; - } - } - public void Decrement(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]--; - } - - } - public void Divide(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (double)(left[indices] / right[indices]); - } - - } - public void Divide(Tensor tensor, double scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (double)(tensor[indices] / scalar); - } - - } - public void Equals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] == right[indices]; - } - - } - public void GreaterThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] > right[indices]; - } - - } - public void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] >= right[indices]; - } - - } - public void Increment(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]++; - } - - } - public void LeftShift(Tensor tensor, int value, Tensor result) - { - throw new NotSupportedException(); - } - public void LessThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] < right[indices]; - } - - } - public void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] <= right[indices]; - } - - } - public void Modulo(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (double)(left[indices] % right[indices]); - } - - } - public void Modulo(Tensor tensor, double scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (double)(tensor[indices] % scalar); - } - - } - public void Multiply(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (double)(left[indices] * right[indices]); - } - - } - public void Multiply(Tensor tensor, double scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (double)(tensor[indices] * scalar); - } - - } - public void NotEquals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] != right[indices]; - } - - } - public void Or(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void Or(Tensor tensor, double scalar, Tensor result) - { - throw new NotSupportedException(); - } - public void RightShift(Tensor tensor, int value, Tensor result) - { - throw new NotSupportedException(); - } - public void Subtract(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (double)(left[indices] - right[indices]); - } - - } - public void Subtract(Tensor tensor, double scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (double)(tensor[indices] - scalar); - } - - } - public void UnaryMinus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (double)-tensor[indices]; - } - - } - public void UnaryPlus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (double)+tensor[indices]; - } - - } - public void Xor(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void Xor(Tensor tensor, double scalar, Tensor result) - { - throw new NotSupportedException(); - } - - public void Add(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (double)(leftSpan[i] + rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (double)(leftSpan[op1Index] + rightSpan[op2Index]); - - } - } - } - public void Add(DenseTensor tensor, double scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (double)(tensorSpan[i] + scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (double)(tensorSpan[op1Index] + scalar); - - } - } - } - public void And(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void And(DenseTensor tensor, double scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Contract(DenseTensor left, DenseTensor right, int[] leftAxes, int[] rightAxes, DenseTensor result) - { - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - - for (int resultIndex = 0; resultIndex < resultSpan.Length; resultIndex++) - { - double sum = (double)0; - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - sum += (double)(leftSpan[leftIndex] * rightSpan[rightIndex]); - } - - resultSpan[resultIndex] = sum; - } - } - public void Decrement(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]--; - } - } - public void Divide(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (double)(leftSpan[i] / rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (double)(leftSpan[op1Index] / rightSpan[op2Index]); - - } - } - } - public void Divide(DenseTensor tensor, double scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (double)(tensorSpan[i] / scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (double)(tensorSpan[op1Index] / scalar); - - } - } - } - public void Equals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] == rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] == rightSpan[op2Index]; - - } - } - } - public void GreaterThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] > rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] > rightSpan[op2Index]; - - } - } - } - public void GreaterThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] >= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] >= rightSpan[op2Index]; - - } - } - } - public void Increment(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]++; - } - } - public void LeftShift(DenseTensor tensor, int value, DenseTensor result) - { - throw new NotSupportedException(); - } - public void LessThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] < rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] < rightSpan[op2Index]; - - } - } - } - public void LessThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] <= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] <= rightSpan[op2Index]; - - } - } - } - public void Modulo(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (double)(leftSpan[i] % rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (double)(leftSpan[op1Index] % rightSpan[op2Index]); - - } - } - } - public void Modulo(DenseTensor tensor, double scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (double)(tensorSpan[i] % scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (double)(tensorSpan[op1Index] % scalar); - - } - } - } - public void Multiply(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (double)(leftSpan[i] * rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (double)(leftSpan[op1Index] * rightSpan[op2Index]); - - } - } - } - public void Multiply(DenseTensor tensor, double scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (double)(tensorSpan[i] * scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (double)(tensorSpan[op1Index] * scalar); - - } - } - } - public void NotEquals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] != rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] != rightSpan[op2Index]; - - } - } - } - public void Or(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Or(DenseTensor tensor, double scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - public void RightShift(DenseTensor tensor, int value, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Subtract(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (double)(leftSpan[i] - rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (double)(leftSpan[op1Index] - rightSpan[op2Index]); - - } - } - } - public void Subtract(DenseTensor tensor, double scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (double)(tensorSpan[i] - scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (double)(tensorSpan[op1Index] - scalar); - - } - } - } - public void UnaryMinus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (double)-tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (double)-tensorSpan[op1Index]; - - } - } - } - public void UnaryPlus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (double)+tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (double)+tensorSpan[op1Index]; - - } - } - } - public void Xor(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Xor(DenseTensor tensor, double scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - } - internal class FloatArithmetic : ITensorArithmetic - { - public float One => 1.0f; - public float Zero => 0; - - public void Add(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (float)(left[indices] + right[indices]); - } - - } - public void Add(Tensor tensor, float scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (float)(tensor[indices] + scalar); - } - - } - public void And(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void And(Tensor tensor, float scalar, Tensor result) - { - throw new NotSupportedException(); - } - public void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var leftIndices = new int[left.Rank]; - var rightIndices = new int[right.Rank]; - var resultIndices = new int[result.Rank]; - - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - for (int resultIndex = 0; resultIndex < result.Length; resultIndex++) - { - float sum = (float)0; - - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, resultIndex, resultIndices); - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - // todo, make this more efficient - ArrayUtilities.GetIndices(left.strides, left.IsReversedStride, leftIndex, leftIndices); - ArrayUtilities.GetIndices(right.strides, right.IsReversedStride, rightIndex, rightIndices); - - sum += (float)(left[leftIndices] * right[rightIndices]); - } - - result[resultIndices] = sum; - } - } - public void Decrement(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]--; - } - - } - public void Divide(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (float)(left[indices] / right[indices]); - } - - } - public void Divide(Tensor tensor, float scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (float)(tensor[indices] / scalar); - } - - } - public void Equals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] == right[indices]; - } - - } - public void GreaterThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] > right[indices]; - } - - } - public void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] >= right[indices]; - } - - } - public void Increment(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]++; - } - - } - public void LeftShift(Tensor tensor, int value, Tensor result) - { - throw new NotSupportedException(); - } - public void LessThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] < right[indices]; - } - - } - public void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] <= right[indices]; - } - - } - public void Modulo(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (float)(left[indices] % right[indices]); - } - - } - public void Modulo(Tensor tensor, float scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (float)(tensor[indices] % scalar); - } - - } - public void Multiply(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (float)(left[indices] * right[indices]); - } - - } - public void Multiply(Tensor tensor, float scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (float)(tensor[indices] * scalar); - } - - } - public void NotEquals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] != right[indices]; - } - - } - public void Or(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void Or(Tensor tensor, float scalar, Tensor result) - { - throw new NotSupportedException(); - } - public void RightShift(Tensor tensor, int value, Tensor result) - { - throw new NotSupportedException(); - } - public void Subtract(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (float)(left[indices] - right[indices]); - } - - } - public void Subtract(Tensor tensor, float scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (float)(tensor[indices] - scalar); - } - - } - public void UnaryMinus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (float)-tensor[indices]; - } - - } - public void UnaryPlus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (float)+tensor[indices]; - } - - } - public void Xor(Tensor left, Tensor right, Tensor result) - { - throw new NotSupportedException(); - } - public void Xor(Tensor tensor, float scalar, Tensor result) - { - throw new NotSupportedException(); - } - - public void Add(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (float)(leftSpan[i] + rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (float)(leftSpan[op1Index] + rightSpan[op2Index]); - - } - } - } - public void Add(DenseTensor tensor, float scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (float)(tensorSpan[i] + scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (float)(tensorSpan[op1Index] + scalar); - - } - } - } - public void And(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void And(DenseTensor tensor, float scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Contract(DenseTensor left, DenseTensor right, int[] leftAxes, int[] rightAxes, DenseTensor result) - { - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - - for (int resultIndex = 0; resultIndex < resultSpan.Length; resultIndex++) - { - float sum = (float)0; - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - sum += (float)(leftSpan[leftIndex] * rightSpan[rightIndex]); - } - - resultSpan[resultIndex] = sum; - } - } - public void Decrement(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]--; - } - } - public void Divide(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (float)(leftSpan[i] / rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (float)(leftSpan[op1Index] / rightSpan[op2Index]); - - } - } - } - public void Divide(DenseTensor tensor, float scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (float)(tensorSpan[i] / scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (float)(tensorSpan[op1Index] / scalar); - - } - } - } - public void Equals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] == rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] == rightSpan[op2Index]; - - } - } - } - public void GreaterThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] > rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] > rightSpan[op2Index]; - - } - } - } - public void GreaterThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] >= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] >= rightSpan[op2Index]; - - } - } - } - public void Increment(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]++; - } - } - public void LeftShift(DenseTensor tensor, int value, DenseTensor result) - { - throw new NotSupportedException(); - } - public void LessThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] < rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] < rightSpan[op2Index]; - - } - } - } - public void LessThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] <= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] <= rightSpan[op2Index]; - - } - } - } - public void Modulo(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (float)(leftSpan[i] % rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (float)(leftSpan[op1Index] % rightSpan[op2Index]); - - } - } - } - public void Modulo(DenseTensor tensor, float scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (float)(tensorSpan[i] % scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (float)(tensorSpan[op1Index] % scalar); - - } - } - } - public void Multiply(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (float)(leftSpan[i] * rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (float)(leftSpan[op1Index] * rightSpan[op2Index]); - - } - } - } - public void Multiply(DenseTensor tensor, float scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (float)(tensorSpan[i] * scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (float)(tensorSpan[op1Index] * scalar); - - } - } - } - public void NotEquals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] != rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] != rightSpan[op2Index]; - - } - } - } - public void Or(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Or(DenseTensor tensor, float scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - public void RightShift(DenseTensor tensor, int value, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Subtract(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (float)(leftSpan[i] - rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (float)(leftSpan[op1Index] - rightSpan[op2Index]); - - } - } - } - public void Subtract(DenseTensor tensor, float scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (float)(tensorSpan[i] - scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (float)(tensorSpan[op1Index] - scalar); - - } - } - } - public void UnaryMinus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (float)-tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (float)-tensorSpan[op1Index]; - - } - } - } - public void UnaryPlus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (float)+tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (float)+tensorSpan[op1Index]; - - } - } - } - public void Xor(DenseTensor left, DenseTensor right, DenseTensor result) - { - throw new NotSupportedException(); - } - public void Xor(DenseTensor tensor, float scalar, DenseTensor result) - { - throw new NotSupportedException(); - } - } - internal class IntArithmetic : ITensorArithmetic - { - public int One => 1; - public int Zero => 0; - - public void Add(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(left[indices] + right[indices]); - } - - } - public void Add(Tensor tensor, int scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(tensor[indices] + scalar); - } - - } - public void And(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(left[indices] & right[indices]); - } - - } - public void And(Tensor tensor, int scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(tensor[indices] & scalar); - } - - } - public void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var leftIndices = new int[left.Rank]; - var rightIndices = new int[right.Rank]; - var resultIndices = new int[result.Rank]; - - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - for (int resultIndex = 0; resultIndex < result.Length; resultIndex++) - { - int sum = (int)0; - - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, resultIndex, resultIndices); - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - // todo, make this more efficient - ArrayUtilities.GetIndices(left.strides, left.IsReversedStride, leftIndex, leftIndices); - ArrayUtilities.GetIndices(right.strides, right.IsReversedStride, rightIndex, rightIndices); - - sum += (int)(left[leftIndices] * right[rightIndices]); - } - - result[resultIndices] = sum; - } - } - public void Decrement(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]--; - } - - } - public void Divide(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(left[indices] / right[indices]); - } - - } - public void Divide(Tensor tensor, int scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(tensor[indices] / scalar); - } - - } - public void Equals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] == right[indices]; - } - - } - public void GreaterThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] > right[indices]; - } - - } - public void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] >= right[indices]; - } - - } - public void Increment(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]++; - } - - } - public void LeftShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(tensor[indices] << value); - } - - } - public void LessThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] < right[indices]; - } - - } - public void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] <= right[indices]; - } - - } - public void Modulo(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(left[indices] % right[indices]); - } - - } - public void Modulo(Tensor tensor, int scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(tensor[indices] % scalar); - } - - } - public void Multiply(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(left[indices] * right[indices]); - } - - } - public void Multiply(Tensor tensor, int scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(tensor[indices] * scalar); - } - - } - public void NotEquals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] != right[indices]; - } - - } - public void Or(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(left[indices] | right[indices]); - } - - } - public void Or(Tensor tensor, int scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(tensor[indices] | scalar); - } - - } - public void RightShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(tensor[indices] >> value); - } - - } - public void Subtract(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(left[indices] - right[indices]); - } - - } - public void Subtract(Tensor tensor, int scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(tensor[indices] - scalar); - } - - } - public void UnaryMinus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)-tensor[indices]; - } - - } - public void UnaryPlus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)+tensor[indices]; - } - - } - public void Xor(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(left[indices] ^ right[indices]); - } - - } - public void Xor(Tensor tensor, int scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (int)(tensor[indices] ^ scalar); - } - - } - - public void Add(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(leftSpan[i] + rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(leftSpan[op1Index] + rightSpan[op2Index]); - - } - } - } - public void Add(DenseTensor tensor, int scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(tensorSpan[i] + scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(tensorSpan[op1Index] + scalar); - - } - } - } - public void And(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(leftSpan[i] & rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(leftSpan[op1Index] & rightSpan[op2Index]); - - } - } - } - public void And(DenseTensor tensor, int scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(tensorSpan[i] & scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(tensorSpan[op1Index] & scalar); - - } - } - } - public void Contract(DenseTensor left, DenseTensor right, int[] leftAxes, int[] rightAxes, DenseTensor result) - { - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - - for (int resultIndex = 0; resultIndex < resultSpan.Length; resultIndex++) - { - int sum = (int)0; - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - sum += (int)(leftSpan[leftIndex] * rightSpan[rightIndex]); - } - - resultSpan[resultIndex] = sum; - } - } - public void Decrement(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]--; - } - } - public void Divide(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(leftSpan[i] / rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(leftSpan[op1Index] / rightSpan[op2Index]); - - } - } - } - public void Divide(DenseTensor tensor, int scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(tensorSpan[i] / scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(tensorSpan[op1Index] / scalar); - - } - } - } - public void Equals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] == rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] == rightSpan[op2Index]; - - } - } - } - public void GreaterThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] > rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] > rightSpan[op2Index]; - - } - } - } - public void GreaterThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] >= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] >= rightSpan[op2Index]; - - } - } - } - public void Increment(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]++; - } - } - public void LeftShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(tensorSpan[i] << value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(tensorSpan[op1Index] << value); - - } - } - } - public void LessThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] < rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] < rightSpan[op2Index]; - - } - } - } - public void LessThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] <= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] <= rightSpan[op2Index]; - - } - } - } - public void Modulo(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(leftSpan[i] % rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(leftSpan[op1Index] % rightSpan[op2Index]); - - } - } - } - public void Modulo(DenseTensor tensor, int scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(tensorSpan[i] % scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(tensorSpan[op1Index] % scalar); - - } - } - } - public void Multiply(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(leftSpan[i] * rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(leftSpan[op1Index] * rightSpan[op2Index]); - - } - } - } - public void Multiply(DenseTensor tensor, int scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(tensorSpan[i] * scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(tensorSpan[op1Index] * scalar); - - } - } - } - public void NotEquals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] != rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] != rightSpan[op2Index]; - - } - } - } - public void Or(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(leftSpan[i] | rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(leftSpan[op1Index] | rightSpan[op2Index]); - - } - } - } - public void Or(DenseTensor tensor, int scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(tensorSpan[i] | scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(tensorSpan[op1Index] | scalar); - - } - } - } - public void RightShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(tensorSpan[i] >> value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(tensorSpan[op1Index] >> value); - - } - } - } - public void Subtract(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(leftSpan[i] - rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(leftSpan[op1Index] - rightSpan[op2Index]); - - } - } - } - public void Subtract(DenseTensor tensor, int scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(tensorSpan[i] - scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(tensorSpan[op1Index] - scalar); - - } - } - } - public void UnaryMinus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)-tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)-tensorSpan[op1Index]; - - } - } - } - public void UnaryPlus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)+tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)+tensorSpan[op1Index]; - - } - } - } - public void Xor(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(leftSpan[i] ^ rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(leftSpan[op1Index] ^ rightSpan[op2Index]); - - } - } - } - public void Xor(DenseTensor tensor, int scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (int)(tensorSpan[i] ^ scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (int)(tensorSpan[op1Index] ^ scalar); - - } - } - } - } - internal class LongArithmetic : ITensorArithmetic - { - public long One => 1; - public long Zero => 0; - - public void Add(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(left[indices] + right[indices]); - } - - } - public void Add(Tensor tensor, long scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(tensor[indices] + scalar); - } - - } - public void And(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(left[indices] & right[indices]); - } - - } - public void And(Tensor tensor, long scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(tensor[indices] & scalar); - } - - } - public void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var leftIndices = new int[left.Rank]; - var rightIndices = new int[right.Rank]; - var resultIndices = new int[result.Rank]; - - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - for (int resultIndex = 0; resultIndex < result.Length; resultIndex++) - { - long sum = (long)0; - - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, resultIndex, resultIndices); - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - // todo, make this more efficient - ArrayUtilities.GetIndices(left.strides, left.IsReversedStride, leftIndex, leftIndices); - ArrayUtilities.GetIndices(right.strides, right.IsReversedStride, rightIndex, rightIndices); - - sum += (long)(left[leftIndices] * right[rightIndices]); - } - - result[resultIndices] = sum; - } - } - public void Decrement(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]--; - } - - } - public void Divide(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(left[indices] / right[indices]); - } - - } - public void Divide(Tensor tensor, long scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(tensor[indices] / scalar); - } - - } - public void Equals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] == right[indices]; - } - - } - public void GreaterThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] > right[indices]; - } - - } - public void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] >= right[indices]; - } - - } - public void Increment(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]++; - } - - } - public void LeftShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(tensor[indices] << value); - } - - } - public void LessThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] < right[indices]; - } - - } - public void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] <= right[indices]; - } - - } - public void Modulo(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(left[indices] % right[indices]); - } - - } - public void Modulo(Tensor tensor, long scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(tensor[indices] % scalar); - } - - } - public void Multiply(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(left[indices] * right[indices]); - } - - } - public void Multiply(Tensor tensor, long scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(tensor[indices] * scalar); - } - - } - public void NotEquals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] != right[indices]; - } - - } - public void Or(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(left[indices] | right[indices]); - } - - } - public void Or(Tensor tensor, long scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(tensor[indices] | scalar); - } - - } - public void RightShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(tensor[indices] >> value); - } - - } - public void Subtract(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(left[indices] - right[indices]); - } - - } - public void Subtract(Tensor tensor, long scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(tensor[indices] - scalar); - } - - } - public void UnaryMinus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)-tensor[indices]; - } - - } - public void UnaryPlus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)+tensor[indices]; - } - - } - public void Xor(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(left[indices] ^ right[indices]); - } - - } - public void Xor(Tensor tensor, long scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (long)(tensor[indices] ^ scalar); - } - - } - - public void Add(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(leftSpan[i] + rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(leftSpan[op1Index] + rightSpan[op2Index]); - - } - } - } - public void Add(DenseTensor tensor, long scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(tensorSpan[i] + scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(tensorSpan[op1Index] + scalar); - - } - } - } - public void And(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(leftSpan[i] & rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(leftSpan[op1Index] & rightSpan[op2Index]); - - } - } - } - public void And(DenseTensor tensor, long scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(tensorSpan[i] & scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(tensorSpan[op1Index] & scalar); - - } - } - } - public void Contract(DenseTensor left, DenseTensor right, int[] leftAxes, int[] rightAxes, DenseTensor result) - { - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - - for (int resultIndex = 0; resultIndex < resultSpan.Length; resultIndex++) - { - long sum = (long)0; - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - sum += (long)(leftSpan[leftIndex] * rightSpan[rightIndex]); - } - - resultSpan[resultIndex] = sum; - } - } - public void Decrement(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]--; - } - } - public void Divide(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(leftSpan[i] / rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(leftSpan[op1Index] / rightSpan[op2Index]); - - } - } - } - public void Divide(DenseTensor tensor, long scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(tensorSpan[i] / scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(tensorSpan[op1Index] / scalar); - - } - } - } - public void Equals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] == rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] == rightSpan[op2Index]; - - } - } - } - public void GreaterThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] > rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] > rightSpan[op2Index]; - - } - } - } - public void GreaterThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] >= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] >= rightSpan[op2Index]; - - } - } - } - public void Increment(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]++; - } - } - public void LeftShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(tensorSpan[i] << value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(tensorSpan[op1Index] << value); - - } - } - } - public void LessThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] < rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] < rightSpan[op2Index]; - - } - } - } - public void LessThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] <= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] <= rightSpan[op2Index]; - - } - } - } - public void Modulo(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(leftSpan[i] % rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(leftSpan[op1Index] % rightSpan[op2Index]); - - } - } - } - public void Modulo(DenseTensor tensor, long scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(tensorSpan[i] % scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(tensorSpan[op1Index] % scalar); - - } - } - } - public void Multiply(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(leftSpan[i] * rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(leftSpan[op1Index] * rightSpan[op2Index]); - - } - } - } - public void Multiply(DenseTensor tensor, long scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(tensorSpan[i] * scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(tensorSpan[op1Index] * scalar); - - } - } - } - public void NotEquals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] != rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] != rightSpan[op2Index]; - - } - } - } - public void Or(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(leftSpan[i] | rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(leftSpan[op1Index] | rightSpan[op2Index]); - - } - } - } - public void Or(DenseTensor tensor, long scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(tensorSpan[i] | scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(tensorSpan[op1Index] | scalar); - - } - } - } - public void RightShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(tensorSpan[i] >> value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(tensorSpan[op1Index] >> value); - - } - } - } - public void Subtract(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(leftSpan[i] - rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(leftSpan[op1Index] - rightSpan[op2Index]); - - } - } - } - public void Subtract(DenseTensor tensor, long scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(tensorSpan[i] - scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(tensorSpan[op1Index] - scalar); - - } - } - } - public void UnaryMinus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)-tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)-tensorSpan[op1Index]; - - } - } - } - public void UnaryPlus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)+tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)+tensorSpan[op1Index]; - - } - } - } - public void Xor(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(leftSpan[i] ^ rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(leftSpan[op1Index] ^ rightSpan[op2Index]); - - } - } - } - public void Xor(DenseTensor tensor, long scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (long)(tensorSpan[i] ^ scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (long)(tensorSpan[op1Index] ^ scalar); - - } - } - } - } - internal class SByteArithmetic : ITensorArithmetic - { - public sbyte One => 1; - public sbyte Zero => 0; - - public void Add(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(left[indices] + right[indices]); - } - - } - public void Add(Tensor tensor, sbyte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(tensor[indices] + scalar); - } - - } - public void And(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(left[indices] & right[indices]); - } - - } - public void And(Tensor tensor, sbyte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(tensor[indices] & scalar); - } - - } - public void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var leftIndices = new int[left.Rank]; - var rightIndices = new int[right.Rank]; - var resultIndices = new int[result.Rank]; - - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - for (int resultIndex = 0; resultIndex < result.Length; resultIndex++) - { - sbyte sum = (sbyte)0; - - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, resultIndex, resultIndices); - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - // todo, make this more efficient - ArrayUtilities.GetIndices(left.strides, left.IsReversedStride, leftIndex, leftIndices); - ArrayUtilities.GetIndices(right.strides, right.IsReversedStride, rightIndex, rightIndices); - - sum += (sbyte)(left[leftIndices] * right[rightIndices]); - } - - result[resultIndices] = sum; - } - } - public void Decrement(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]--; - } - - } - public void Divide(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(left[indices] / right[indices]); - } - - } - public void Divide(Tensor tensor, sbyte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(tensor[indices] / scalar); - } - - } - public void Equals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] == right[indices]; - } - - } - public void GreaterThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] > right[indices]; - } - - } - public void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] >= right[indices]; - } - - } - public void Increment(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]++; - } - - } - public void LeftShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(tensor[indices] << value); - } - - } - public void LessThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] < right[indices]; - } - - } - public void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] <= right[indices]; - } - - } - public void Modulo(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(left[indices] % right[indices]); - } - - } - public void Modulo(Tensor tensor, sbyte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(tensor[indices] % scalar); - } - - } - public void Multiply(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(left[indices] * right[indices]); - } - - } - public void Multiply(Tensor tensor, sbyte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(tensor[indices] * scalar); - } - - } - public void NotEquals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] != right[indices]; - } - - } - public void Or(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(left[indices] | right[indices]); - } - - } - public void Or(Tensor tensor, sbyte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(tensor[indices] | scalar); - } - - } - public void RightShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(tensor[indices] >> value); - } - - } - public void Subtract(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(left[indices] - right[indices]); - } - - } - public void Subtract(Tensor tensor, sbyte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(tensor[indices] - scalar); - } - - } - public void UnaryMinus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)-tensor[indices]; - } - - } - public void UnaryPlus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)+tensor[indices]; - } - - } - public void Xor(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(left[indices] ^ right[indices]); - } - - } - public void Xor(Tensor tensor, sbyte scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (sbyte)(tensor[indices] ^ scalar); - } - - } - - public void Add(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(leftSpan[i] + rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(leftSpan[op1Index] + rightSpan[op2Index]); - - } - } - } - public void Add(DenseTensor tensor, sbyte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(tensorSpan[i] + scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(tensorSpan[op1Index] + scalar); - - } - } - } - public void And(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(leftSpan[i] & rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(leftSpan[op1Index] & rightSpan[op2Index]); - - } - } - } - public void And(DenseTensor tensor, sbyte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(tensorSpan[i] & scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(tensorSpan[op1Index] & scalar); - - } - } - } - public void Contract(DenseTensor left, DenseTensor right, int[] leftAxes, int[] rightAxes, DenseTensor result) - { - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - - for (int resultIndex = 0; resultIndex < resultSpan.Length; resultIndex++) - { - sbyte sum = (sbyte)0; - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - sum += (sbyte)(leftSpan[leftIndex] * rightSpan[rightIndex]); - } - - resultSpan[resultIndex] = sum; - } - } - public void Decrement(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]--; - } - } - public void Divide(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(leftSpan[i] / rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(leftSpan[op1Index] / rightSpan[op2Index]); - - } - } - } - public void Divide(DenseTensor tensor, sbyte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(tensorSpan[i] / scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(tensorSpan[op1Index] / scalar); - - } - } - } - public void Equals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] == rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] == rightSpan[op2Index]; - - } - } - } - public void GreaterThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] > rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] > rightSpan[op2Index]; - - } - } - } - public void GreaterThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] >= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] >= rightSpan[op2Index]; - - } - } - } - public void Increment(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]++; - } - } - public void LeftShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(tensorSpan[i] << value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(tensorSpan[op1Index] << value); - - } - } - } - public void LessThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] < rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] < rightSpan[op2Index]; - - } - } - } - public void LessThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] <= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] <= rightSpan[op2Index]; - - } - } - } - public void Modulo(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(leftSpan[i] % rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(leftSpan[op1Index] % rightSpan[op2Index]); - - } - } - } - public void Modulo(DenseTensor tensor, sbyte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(tensorSpan[i] % scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(tensorSpan[op1Index] % scalar); - - } - } - } - public void Multiply(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(leftSpan[i] * rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(leftSpan[op1Index] * rightSpan[op2Index]); - - } - } - } - public void Multiply(DenseTensor tensor, sbyte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(tensorSpan[i] * scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(tensorSpan[op1Index] * scalar); - - } - } - } - public void NotEquals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] != rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] != rightSpan[op2Index]; - - } - } - } - public void Or(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(leftSpan[i] | rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(leftSpan[op1Index] | rightSpan[op2Index]); - - } - } - } - public void Or(DenseTensor tensor, sbyte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(tensorSpan[i] | scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(tensorSpan[op1Index] | scalar); - - } - } - } - public void RightShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(tensorSpan[i] >> value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(tensorSpan[op1Index] >> value); - - } - } - } - public void Subtract(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(leftSpan[i] - rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(leftSpan[op1Index] - rightSpan[op2Index]); - - } - } - } - public void Subtract(DenseTensor tensor, sbyte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(tensorSpan[i] - scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(tensorSpan[op1Index] - scalar); - - } - } - } - public void UnaryMinus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)-tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)-tensorSpan[op1Index]; - - } - } - } - public void UnaryPlus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)+tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)+tensorSpan[op1Index]; - - } - } - } - public void Xor(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(leftSpan[i] ^ rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(leftSpan[op1Index] ^ rightSpan[op2Index]); - - } - } - } - public void Xor(DenseTensor tensor, sbyte scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (sbyte)(tensorSpan[i] ^ scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (sbyte)(tensorSpan[op1Index] ^ scalar); - - } - } - } - } - internal class ShortArithmetic : ITensorArithmetic - { - public short One => 1; - public short Zero => 0; - - public void Add(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(left[indices] + right[indices]); - } - - } - public void Add(Tensor tensor, short scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(tensor[indices] + scalar); - } - - } - public void And(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(left[indices] & right[indices]); - } - - } - public void And(Tensor tensor, short scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(tensor[indices] & scalar); - } - - } - public void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var leftIndices = new int[left.Rank]; - var rightIndices = new int[right.Rank]; - var resultIndices = new int[result.Rank]; - - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - for (int resultIndex = 0; resultIndex < result.Length; resultIndex++) - { - short sum = (short)0; - - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, resultIndex, resultIndices); - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - // todo, make this more efficient - ArrayUtilities.GetIndices(left.strides, left.IsReversedStride, leftIndex, leftIndices); - ArrayUtilities.GetIndices(right.strides, right.IsReversedStride, rightIndex, rightIndices); - - sum += (short)(left[leftIndices] * right[rightIndices]); - } - - result[resultIndices] = sum; - } - } - public void Decrement(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]--; - } - - } - public void Divide(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(left[indices] / right[indices]); - } - - } - public void Divide(Tensor tensor, short scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(tensor[indices] / scalar); - } - - } - public void Equals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] == right[indices]; - } - - } - public void GreaterThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] > right[indices]; - } - - } - public void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] >= right[indices]; - } - - } - public void Increment(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]++; - } - - } - public void LeftShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(tensor[indices] << value); - } - - } - public void LessThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] < right[indices]; - } - - } - public void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] <= right[indices]; - } - - } - public void Modulo(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(left[indices] % right[indices]); - } - - } - public void Modulo(Tensor tensor, short scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(tensor[indices] % scalar); - } - - } - public void Multiply(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(left[indices] * right[indices]); - } - - } - public void Multiply(Tensor tensor, short scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(tensor[indices] * scalar); - } - - } - public void NotEquals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] != right[indices]; - } - - } - public void Or(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(left[indices] | right[indices]); - } - - } - public void Or(Tensor tensor, short scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(tensor[indices] | scalar); - } - - } - public void RightShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(tensor[indices] >> value); - } - - } - public void Subtract(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(left[indices] - right[indices]); - } - - } - public void Subtract(Tensor tensor, short scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(tensor[indices] - scalar); - } - - } - public void UnaryMinus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)-tensor[indices]; - } - - } - public void UnaryPlus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)+tensor[indices]; - } - - } - public void Xor(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(left[indices] ^ right[indices]); - } - - } - public void Xor(Tensor tensor, short scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (short)(tensor[indices] ^ scalar); - } - - } - - public void Add(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(leftSpan[i] + rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(leftSpan[op1Index] + rightSpan[op2Index]); - - } - } - } - public void Add(DenseTensor tensor, short scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(tensorSpan[i] + scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(tensorSpan[op1Index] + scalar); - - } - } - } - public void And(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(leftSpan[i] & rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(leftSpan[op1Index] & rightSpan[op2Index]); - - } - } - } - public void And(DenseTensor tensor, short scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(tensorSpan[i] & scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(tensorSpan[op1Index] & scalar); - - } - } - } - public void Contract(DenseTensor left, DenseTensor right, int[] leftAxes, int[] rightAxes, DenseTensor result) - { - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - - for (int resultIndex = 0; resultIndex < resultSpan.Length; resultIndex++) - { - short sum = (short)0; - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - sum += (short)(leftSpan[leftIndex] * rightSpan[rightIndex]); - } - - resultSpan[resultIndex] = sum; - } - } - public void Decrement(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]--; - } - } - public void Divide(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(leftSpan[i] / rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(leftSpan[op1Index] / rightSpan[op2Index]); - - } - } - } - public void Divide(DenseTensor tensor, short scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(tensorSpan[i] / scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(tensorSpan[op1Index] / scalar); - - } - } - } - public void Equals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] == rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] == rightSpan[op2Index]; - - } - } - } - public void GreaterThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] > rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] > rightSpan[op2Index]; - - } - } - } - public void GreaterThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] >= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] >= rightSpan[op2Index]; - - } - } - } - public void Increment(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]++; - } - } - public void LeftShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(tensorSpan[i] << value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(tensorSpan[op1Index] << value); - - } - } - } - public void LessThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] < rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] < rightSpan[op2Index]; - - } - } - } - public void LessThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] <= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] <= rightSpan[op2Index]; - - } - } - } - public void Modulo(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(leftSpan[i] % rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(leftSpan[op1Index] % rightSpan[op2Index]); - - } - } - } - public void Modulo(DenseTensor tensor, short scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(tensorSpan[i] % scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(tensorSpan[op1Index] % scalar); - - } - } - } - public void Multiply(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(leftSpan[i] * rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(leftSpan[op1Index] * rightSpan[op2Index]); - - } - } - } - public void Multiply(DenseTensor tensor, short scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(tensorSpan[i] * scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(tensorSpan[op1Index] * scalar); - - } - } - } - public void NotEquals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] != rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] != rightSpan[op2Index]; - - } - } - } - public void Or(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(leftSpan[i] | rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(leftSpan[op1Index] | rightSpan[op2Index]); - - } - } - } - public void Or(DenseTensor tensor, short scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(tensorSpan[i] | scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(tensorSpan[op1Index] | scalar); - - } - } - } - public void RightShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(tensorSpan[i] >> value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(tensorSpan[op1Index] >> value); - - } - } - } - public void Subtract(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(leftSpan[i] - rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(leftSpan[op1Index] - rightSpan[op2Index]); - - } - } - } - public void Subtract(DenseTensor tensor, short scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(tensorSpan[i] - scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(tensorSpan[op1Index] - scalar); - - } - } - } - public void UnaryMinus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)-tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)-tensorSpan[op1Index]; - - } - } - } - public void UnaryPlus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)+tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)+tensorSpan[op1Index]; - - } - } - } - public void Xor(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(leftSpan[i] ^ rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(leftSpan[op1Index] ^ rightSpan[op2Index]); - - } - } - } - public void Xor(DenseTensor tensor, short scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (short)(tensorSpan[i] ^ scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (short)(tensorSpan[op1Index] ^ scalar); - - } - } - } - } - internal class UIntArithmetic : ITensorArithmetic - { - public uint One => 1; - public uint Zero => 0; - - public void Add(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(left[indices] + right[indices]); - } - - } - public void Add(Tensor tensor, uint scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(tensor[indices] + scalar); - } - - } - public void And(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(left[indices] & right[indices]); - } - - } - public void And(Tensor tensor, uint scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(tensor[indices] & scalar); - } - - } - public void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var leftIndices = new int[left.Rank]; - var rightIndices = new int[right.Rank]; - var resultIndices = new int[result.Rank]; - - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - for (int resultIndex = 0; resultIndex < result.Length; resultIndex++) - { - uint sum = (uint)0; - - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, resultIndex, resultIndices); - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - // todo, make this more efficient - ArrayUtilities.GetIndices(left.strides, left.IsReversedStride, leftIndex, leftIndices); - ArrayUtilities.GetIndices(right.strides, right.IsReversedStride, rightIndex, rightIndices); - - sum += (uint)(left[leftIndices] * right[rightIndices]); - } - - result[resultIndices] = sum; - } - } - public void Decrement(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]--; - } - - } - public void Divide(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(left[indices] / right[indices]); - } - - } - public void Divide(Tensor tensor, uint scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(tensor[indices] / scalar); - } - - } - public void Equals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] == right[indices]; - } - - } - public void GreaterThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] > right[indices]; - } - - } - public void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] >= right[indices]; - } - - } - public void Increment(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]++; - } - - } - public void LeftShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(tensor[indices] << value); - } - - } - public void LessThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] < right[indices]; - } - - } - public void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] <= right[indices]; - } - - } - public void Modulo(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(left[indices] % right[indices]); - } - - } - public void Modulo(Tensor tensor, uint scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(tensor[indices] % scalar); - } - - } - public void Multiply(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(left[indices] * right[indices]); - } - - } - public void Multiply(Tensor tensor, uint scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(tensor[indices] * scalar); - } - - } - public void NotEquals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] != right[indices]; - } - - } - public void Or(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(left[indices] | right[indices]); - } - - } - public void Or(Tensor tensor, uint scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(tensor[indices] | scalar); - } - - } - public void RightShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(tensor[indices] >> value); - } - - } - public void Subtract(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(left[indices] - right[indices]); - } - - } - public void Subtract(Tensor tensor, uint scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(tensor[indices] - scalar); - } - - } - public void UnaryMinus(Tensor tensor, Tensor result) - { - throw new NotSupportedException(); - } - public void UnaryPlus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)+tensor[indices]; - } - - } - public void Xor(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(left[indices] ^ right[indices]); - } - - } - public void Xor(Tensor tensor, uint scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (uint)(tensor[indices] ^ scalar); - } - - } - - public void Add(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(leftSpan[i] + rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(leftSpan[op1Index] + rightSpan[op2Index]); - - } - } - } - public void Add(DenseTensor tensor, uint scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(tensorSpan[i] + scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(tensorSpan[op1Index] + scalar); - - } - } - } - public void And(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(leftSpan[i] & rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(leftSpan[op1Index] & rightSpan[op2Index]); - - } - } - } - public void And(DenseTensor tensor, uint scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(tensorSpan[i] & scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(tensorSpan[op1Index] & scalar); - - } - } - } - public void Contract(DenseTensor left, DenseTensor right, int[] leftAxes, int[] rightAxes, DenseTensor result) - { - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - - for (int resultIndex = 0; resultIndex < resultSpan.Length; resultIndex++) - { - uint sum = (uint)0; - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - sum += (uint)(leftSpan[leftIndex] * rightSpan[rightIndex]); - } - - resultSpan[resultIndex] = sum; - } - } - public void Decrement(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]--; - } - } - public void Divide(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(leftSpan[i] / rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(leftSpan[op1Index] / rightSpan[op2Index]); - - } - } - } - public void Divide(DenseTensor tensor, uint scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(tensorSpan[i] / scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(tensorSpan[op1Index] / scalar); - - } - } - } - public void Equals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] == rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] == rightSpan[op2Index]; - - } - } - } - public void GreaterThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] > rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] > rightSpan[op2Index]; - - } - } - } - public void GreaterThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] >= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] >= rightSpan[op2Index]; - - } - } - } - public void Increment(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]++; - } - } - public void LeftShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(tensorSpan[i] << value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(tensorSpan[op1Index] << value); - - } - } - } - public void LessThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] < rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] < rightSpan[op2Index]; - - } - } - } - public void LessThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] <= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] <= rightSpan[op2Index]; - - } - } - } - public void Modulo(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(leftSpan[i] % rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(leftSpan[op1Index] % rightSpan[op2Index]); - - } - } - } - public void Modulo(DenseTensor tensor, uint scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(tensorSpan[i] % scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(tensorSpan[op1Index] % scalar); - - } - } - } - public void Multiply(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(leftSpan[i] * rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(leftSpan[op1Index] * rightSpan[op2Index]); - - } - } - } - public void Multiply(DenseTensor tensor, uint scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(tensorSpan[i] * scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(tensorSpan[op1Index] * scalar); - - } - } - } - public void NotEquals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] != rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] != rightSpan[op2Index]; - - } - } - } - public void Or(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(leftSpan[i] | rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(leftSpan[op1Index] | rightSpan[op2Index]); - - } - } - } - public void Or(DenseTensor tensor, uint scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(tensorSpan[i] | scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(tensorSpan[op1Index] | scalar); - - } - } - } - public void RightShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(tensorSpan[i] >> value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(tensorSpan[op1Index] >> value); - - } - } - } - public void Subtract(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(leftSpan[i] - rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(leftSpan[op1Index] - rightSpan[op2Index]); - - } - } - } - public void Subtract(DenseTensor tensor, uint scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(tensorSpan[i] - scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(tensorSpan[op1Index] - scalar); - - } - } - } - public void UnaryMinus(DenseTensor tensor, DenseTensor result) - { - throw new NotSupportedException(); - } - public void UnaryPlus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)+tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)+tensorSpan[op1Index]; - - } - } - } - public void Xor(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(leftSpan[i] ^ rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(leftSpan[op1Index] ^ rightSpan[op2Index]); - - } - } - } - public void Xor(DenseTensor tensor, uint scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (uint)(tensorSpan[i] ^ scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (uint)(tensorSpan[op1Index] ^ scalar); - - } - } - } - } - internal class ULongArithmetic : ITensorArithmetic - { - public ulong One => 1; - public ulong Zero => 0; - - public void Add(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(left[indices] + right[indices]); - } - - } - public void Add(Tensor tensor, ulong scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(tensor[indices] + scalar); - } - - } - public void And(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(left[indices] & right[indices]); - } - - } - public void And(Tensor tensor, ulong scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(tensor[indices] & scalar); - } - - } - public void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var leftIndices = new int[left.Rank]; - var rightIndices = new int[right.Rank]; - var resultIndices = new int[result.Rank]; - - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - for (int resultIndex = 0; resultIndex < result.Length; resultIndex++) - { - ulong sum = (ulong)0; - - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, resultIndex, resultIndices); - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - // todo, make this more efficient - ArrayUtilities.GetIndices(left.strides, left.IsReversedStride, leftIndex, leftIndices); - ArrayUtilities.GetIndices(right.strides, right.IsReversedStride, rightIndex, rightIndices); - - sum += (ulong)(left[leftIndices] * right[rightIndices]); - } - - result[resultIndices] = sum; - } - } - public void Decrement(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]--; - } - - } - public void Divide(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(left[indices] / right[indices]); - } - - } - public void Divide(Tensor tensor, ulong scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(tensor[indices] / scalar); - } - - } - public void Equals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] == right[indices]; - } - - } - public void GreaterThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] > right[indices]; - } - - } - public void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] >= right[indices]; - } - - } - public void Increment(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]++; - } - - } - public void LeftShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(tensor[indices] << value); - } - - } - public void LessThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] < right[indices]; - } - - } - public void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] <= right[indices]; - } - - } - public void Modulo(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(left[indices] % right[indices]); - } - - } - public void Modulo(Tensor tensor, ulong scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(tensor[indices] % scalar); - } - - } - public void Multiply(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(left[indices] * right[indices]); - } - - } - public void Multiply(Tensor tensor, ulong scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(tensor[indices] * scalar); - } - - } - public void NotEquals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] != right[indices]; - } - - } - public void Or(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(left[indices] | right[indices]); - } - - } - public void Or(Tensor tensor, ulong scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(tensor[indices] | scalar); - } - - } - public void RightShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(tensor[indices] >> value); - } - - } - public void Subtract(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(left[indices] - right[indices]); - } - - } - public void Subtract(Tensor tensor, ulong scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(tensor[indices] - scalar); - } - - } - public void UnaryMinus(Tensor tensor, Tensor result) - { - throw new NotSupportedException(); - } - public void UnaryPlus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)+tensor[indices]; - } - - } - public void Xor(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(left[indices] ^ right[indices]); - } - - } - public void Xor(Tensor tensor, ulong scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ulong)(tensor[indices] ^ scalar); - } - - } - - public void Add(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(leftSpan[i] + rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(leftSpan[op1Index] + rightSpan[op2Index]); - - } - } - } - public void Add(DenseTensor tensor, ulong scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(tensorSpan[i] + scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(tensorSpan[op1Index] + scalar); - - } - } - } - public void And(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(leftSpan[i] & rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(leftSpan[op1Index] & rightSpan[op2Index]); - - } - } - } - public void And(DenseTensor tensor, ulong scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(tensorSpan[i] & scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(tensorSpan[op1Index] & scalar); - - } - } - } - public void Contract(DenseTensor left, DenseTensor right, int[] leftAxes, int[] rightAxes, DenseTensor result) - { - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - - for (int resultIndex = 0; resultIndex < resultSpan.Length; resultIndex++) - { - ulong sum = (ulong)0; - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - sum += (ulong)(leftSpan[leftIndex] * rightSpan[rightIndex]); - } - - resultSpan[resultIndex] = sum; - } - } - public void Decrement(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]--; - } - } - public void Divide(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(leftSpan[i] / rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(leftSpan[op1Index] / rightSpan[op2Index]); - - } - } - } - public void Divide(DenseTensor tensor, ulong scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(tensorSpan[i] / scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(tensorSpan[op1Index] / scalar); - - } - } - } - public void Equals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] == rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] == rightSpan[op2Index]; - - } - } - } - public void GreaterThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] > rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] > rightSpan[op2Index]; - - } - } - } - public void GreaterThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] >= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] >= rightSpan[op2Index]; - - } - } - } - public void Increment(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]++; - } - } - public void LeftShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(tensorSpan[i] << value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(tensorSpan[op1Index] << value); - - } - } - } - public void LessThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] < rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] < rightSpan[op2Index]; - - } - } - } - public void LessThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] <= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] <= rightSpan[op2Index]; - - } - } - } - public void Modulo(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(leftSpan[i] % rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(leftSpan[op1Index] % rightSpan[op2Index]); - - } - } - } - public void Modulo(DenseTensor tensor, ulong scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(tensorSpan[i] % scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(tensorSpan[op1Index] % scalar); - - } - } - } - public void Multiply(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(leftSpan[i] * rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(leftSpan[op1Index] * rightSpan[op2Index]); - - } - } - } - public void Multiply(DenseTensor tensor, ulong scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(tensorSpan[i] * scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(tensorSpan[op1Index] * scalar); - - } - } - } - public void NotEquals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] != rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] != rightSpan[op2Index]; - - } - } - } - public void Or(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(leftSpan[i] | rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(leftSpan[op1Index] | rightSpan[op2Index]); - - } - } - } - public void Or(DenseTensor tensor, ulong scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(tensorSpan[i] | scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(tensorSpan[op1Index] | scalar); - - } - } - } - public void RightShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(tensorSpan[i] >> value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(tensorSpan[op1Index] >> value); - - } - } - } - public void Subtract(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(leftSpan[i] - rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(leftSpan[op1Index] - rightSpan[op2Index]); - - } - } - } - public void Subtract(DenseTensor tensor, ulong scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(tensorSpan[i] - scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(tensorSpan[op1Index] - scalar); - - } - } - } - public void UnaryMinus(DenseTensor tensor, DenseTensor result) - { - throw new NotSupportedException(); - } - public void UnaryPlus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)+tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)+tensorSpan[op1Index]; - - } - } - } - public void Xor(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(leftSpan[i] ^ rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(leftSpan[op1Index] ^ rightSpan[op2Index]); - - } - } - } - public void Xor(DenseTensor tensor, ulong scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ulong)(tensorSpan[i] ^ scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ulong)(tensorSpan[op1Index] ^ scalar); - - } - } - } - } - internal class UShortArithmetic : ITensorArithmetic - { - public ushort One => 1; - public ushort Zero => 0; - - public void Add(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(left[indices] + right[indices]); - } - - } - public void Add(Tensor tensor, ushort scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(tensor[indices] + scalar); - } - - } - public void And(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(left[indices] & right[indices]); - } - - } - public void And(Tensor tensor, ushort scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(tensor[indices] & scalar); - } - - } - public void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var leftIndices = new int[left.Rank]; - var rightIndices = new int[right.Rank]; - var resultIndices = new int[result.Rank]; - - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - for (int resultIndex = 0; resultIndex < result.Length; resultIndex++) - { - ushort sum = (ushort)0; - - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, resultIndex, resultIndices); - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - // todo, make this more efficient - ArrayUtilities.GetIndices(left.strides, left.IsReversedStride, leftIndex, leftIndices); - ArrayUtilities.GetIndices(right.strides, right.IsReversedStride, rightIndex, rightIndices); - - sum += (ushort)(left[leftIndices] * right[rightIndices]); - } - - result[resultIndices] = sum; - } - } - public void Decrement(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]--; - } - - } - public void Divide(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(left[indices] / right[indices]); - } - - } - public void Divide(Tensor tensor, ushort scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(tensor[indices] / scalar); - } - - } - public void Equals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] == right[indices]; - } - - } - public void GreaterThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] > right[indices]; - } - - } - public void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] >= right[indices]; - } - - } - public void Increment(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices]++; - } - - } - public void LeftShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(tensor[indices] << value); - } - - } - public void LessThan(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] < right[indices]; - } - - } - public void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] <= right[indices]; - } - - } - public void Modulo(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(left[indices] % right[indices]); - } - - } - public void Modulo(Tensor tensor, ushort scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(tensor[indices] % scalar); - } - - } - public void Multiply(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(left[indices] * right[indices]); - } - - } - public void Multiply(Tensor tensor, ushort scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(tensor[indices] * scalar); - } - - } - public void NotEquals(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = left[indices] != right[indices]; - } - - } - public void Or(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(left[indices] | right[indices]); - } - - } - public void Or(Tensor tensor, ushort scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(tensor[indices] | scalar); - } - - } - public void RightShift(Tensor tensor, int value, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(tensor[indices] >> value); - } - - } - public void Subtract(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(left[indices] - right[indices]); - } - - } - public void Subtract(Tensor tensor, ushort scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(tensor[indices] - scalar); - } - - } - public void UnaryMinus(Tensor tensor, Tensor result) - { - throw new NotSupportedException(); - } - public void UnaryPlus(Tensor tensor, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)+tensor[indices]; - } - - } - public void Xor(Tensor left, Tensor right, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(left[indices] ^ right[indices]); - } - - } - public void Xor(Tensor tensor, ushort scalar, Tensor result) - { - - Span indices = new Span(new int[result.Rank]); - for (int i = 0; i < result.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - result[indices] = (ushort)(tensor[indices] ^ scalar); - } - - } - - public void Add(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(leftSpan[i] + rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(leftSpan[op1Index] + rightSpan[op2Index]); - - } - } - } - public void Add(DenseTensor tensor, ushort scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(tensorSpan[i] + scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(tensorSpan[op1Index] + scalar); - - } - } - } - public void And(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(leftSpan[i] & rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(leftSpan[op1Index] & rightSpan[op2Index]); - - } - } - } - public void And(DenseTensor tensor, ushort scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(tensorSpan[i] & scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(tensorSpan[op1Index] & scalar); - - } - } - } - public void Contract(DenseTensor left, DenseTensor right, int[] leftAxes, int[] rightAxes, DenseTensor result) - { - var summingDimensions = new int[leftAxes.Length]; - for (int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - - for (int resultIndex = 0; resultIndex < resultSpan.Length; resultIndex++) - { - ushort sum = (ushort)0; - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - sum += (ushort)(leftSpan[leftIndex] * rightSpan[rightIndex]); - } - - resultSpan[resultIndex] = sum; - } - } - public void Decrement(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]--; - } - } - public void Divide(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(leftSpan[i] / rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(leftSpan[op1Index] / rightSpan[op2Index]); - - } - } - } - public void Divide(DenseTensor tensor, ushort scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(tensorSpan[i] / scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(tensorSpan[op1Index] / scalar); - - } - } - } - public void Equals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] == rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] == rightSpan[op2Index]; - - } - } - } - public void GreaterThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] > rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] > rightSpan[op2Index]; - - } - } - } - public void GreaterThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] >= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] >= rightSpan[op2Index]; - - } - } - } - public void Increment(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i]++; - } - } - public void LeftShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(tensorSpan[i] << value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(tensorSpan[op1Index] << value); - - } - } - } - public void LessThan(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] < rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] < rightSpan[op2Index]; - - } - } - } - public void LessThanOrEqual(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] <= rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] <= rightSpan[op2Index]; - - } - } - } - public void Modulo(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(leftSpan[i] % rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(leftSpan[op1Index] % rightSpan[op2Index]); - - } - } - } - public void Modulo(DenseTensor tensor, ushort scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(tensorSpan[i] % scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(tensorSpan[op1Index] % scalar); - - } - } - } - public void Multiply(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(leftSpan[i] * rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(leftSpan[op1Index] * rightSpan[op2Index]); - - } - } - } - public void Multiply(DenseTensor tensor, ushort scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(tensorSpan[i] * scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(tensorSpan[op1Index] * scalar); - - } - } - } - public void NotEquals(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = leftSpan[i] != rightSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = leftSpan[op1Index] != rightSpan[op2Index]; - - } - } - } - public void Or(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(leftSpan[i] | rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(leftSpan[op1Index] | rightSpan[op2Index]); - - } - } - } - public void Or(DenseTensor tensor, ushort scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(tensorSpan[i] | scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(tensorSpan[op1Index] | scalar); - - } - } - } - public void RightShift(DenseTensor tensor, int value, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(tensorSpan[i] >> value); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(tensorSpan[op1Index] >> value); - - } - } - } - public void Subtract(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(leftSpan[i] - rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(leftSpan[op1Index] - rightSpan[op2Index]); - - } - } - } - public void Subtract(DenseTensor tensor, ushort scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(tensorSpan[i] - scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(tensorSpan[op1Index] - scalar); - - } - } - } - public void UnaryMinus(DenseTensor tensor, DenseTensor result) - { - throw new NotSupportedException(); - } - public void UnaryPlus(DenseTensor tensor, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)+tensorSpan[i]; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)+tensorSpan[op1Index]; - - } - } - } - public void Xor(DenseTensor left, DenseTensor right, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - if ((result.IsReversedStride == left.IsReversedStride) && (result.IsReversedStride == right.IsReversedStride)) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(leftSpan[i] ^ rightSpan[i]); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref left.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - ref int op2Index = ref right.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - !left.IsReversedStride ? left.strides : - right.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - left.IsReversedStride ? left.strides : - right.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(leftSpan[op1Index] ^ rightSpan[op2Index]); - - } - } - } - public void Xor(DenseTensor tensor, ushort scalar, DenseTensor result) - { - - var resultSpan = result.Buffer.Span; - var tensorSpan = tensor.Buffer.Span; - if (result.IsReversedStride == tensor.IsReversedStride) - { - for (int i = 0; i < resultSpan.Length; i++) - { - resultSpan[i] = (ushort)(tensorSpan[i] ^ scalar); - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref result.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref tensor.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !result.IsReversedStride ? result.strides : - tensor.strides; - var columnMajorStrides = result.IsReversedStride ? result.strides : - tensor.strides; - for (;rowMajorIndex < resultSpan.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - resultSpan[resultIndex] = (ushort)(tensorSpan[op1Index] ^ scalar); - - } - } - } - } -} diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorArithmetic.tt b/src/libraries/System.Numerics.Tensors/tests/TensorArithmetic.tt deleted file mode 100644 index 91efa47c1ab768..00000000000000 --- a/src/libraries/System.Numerics.Tensors/tests/TensorArithmetic.tt +++ /dev/null @@ -1,237 +0,0 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ output extension=".cs" #> -<#@ include file="TensorTemplate.ttinclude" #>// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Numerics.Tensors -{ - internal interface ITensorArithmetic - { - T One { get; } - T Zero { get; } -<# foreach (MethodConfiguration method in methodConfiguration) { #> - <#= method.GetResultMethodSignature("Tensor", "T")#>; -<# } #> - } - - internal static class TensorArithmetic - { - public static ITensorArithmetic Instance => TensorArithmetic.GetArithmetic(); - } - - internal static class TensorArithmetic - { - public static ITensorArithmetic GetArithmetic() - { -<# foreach (TypeConfiguration type in typeConfiguration) { #> - <#=GenerateIfStatementHeader(type)#> - { - return (ITensorArithmetic)new <#=type.ClassPrefix#>Arithmetic(); - } -<# } #> - return null; - } - } - -<# foreach (TypeConfiguration type in typeConfiguration) { #> - internal class <#=type.ClassPrefix#>Arithmetic : ITensorArithmetic<<#=type.TypeName#>> - { - public <#=type.TypeName#> One => <#=type.OneLiteral#>; - public <#=type.TypeName#> Zero => <#=type.ZeroLiteral#>; - -<# foreach (MethodConfiguration method in methodConfiguration) { #> - public <#= method.GetResultMethodSignature("Tensor", type.TypeName)#> - { -<# if ((method.IsNumeric && !type.SupportsNumeric) || (method.IsBitwise && !type.SupportsBitwise) || (type.UnsupportedMethods.Contains(method.MethodName))) { #> - throw new NotSupportedException(); -<# } else if (method.Operator != null) { #> - - Span indices = new Span(new int[result.Rank]); - for(int i = 0; i < <#= method.ResultName #>.Length; i++) - { - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, i, indices); - <#=method.GetElementOperation(type.TypeName, "[indices]")#>; - } - -<# } else if (method.MethodName == "Contract") {#> - var leftIndices = new int[left.Rank]; - var rightIndices = new int[right.Rank]; - var resultIndices = new int[result.Rank]; - - var summingDimensions = new int[leftAxes.Length]; - for(int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - for (int resultIndex = 0; resultIndex < result.Length; resultIndex++) - { - <#=type.TypeName#> sum = (<#=type.TypeName#>)0; - - ArrayUtilities.GetIndices(result.strides, result.IsReversedStride, resultIndex, resultIndices); - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - // todo, make this more efficient - ArrayUtilities.GetIndices(left.strides, left.IsReversedStride, leftIndex, leftIndices); - ArrayUtilities.GetIndices(right.strides, right.IsReversedStride, rightIndex, rightIndices); - - sum += (<#=type.TypeName#>)(left[leftIndices] * right[rightIndices]); - } - - result[resultIndices] = sum; - } -<# } #> - } -<# } #> - -<# foreach (MethodConfiguration method in methodConfiguration) { #> - public <#= method.GetResultMethodSignature("DenseTensor", type.TypeName)#> - { -<# if ((method.IsNumeric && !type.SupportsNumeric) || (method.IsBitwise && !type.SupportsBitwise) || (type.UnsupportedMethods.Contains(method.MethodName))) { #> - throw new NotSupportedException(); -<# } else if (method.Operator != null) { #> - -<# if (method.MethodType == MethodType.UnaryInPlace) { #> - var <#=method.ResultName #>Span = <#=method.ResultName #>.Buffer.Span; - var <#=method.Op1Name #>Span = <#=method.Op1Name #>.Buffer.Span; - for(int i = 0; i < <#=method.ResultName #>Span.Length; i++) - { - <#=method.GetElementOperation(type.TypeName, "Span[i]")#>; - } -<# } else {#> - var <#=method.ResultName #>Span = <#=method.ResultName #>.Buffer.Span; - var <#=method.Op1Name #>Span = <#=method.Op1Name #>.Buffer.Span; -<# if ((method.MethodType == MethodType.Binary) || (method.MethodType == MethodType.Comparison)) {#> - var <#=method.Op2Name #>Span = <#=method.Op2Name #>.Buffer.Span; -<# } #> - if <#= method.GetLinearOperationCheck() #> - { - for(int i = 0; i < <#= method.ResultName #>Span.Length; i++) - { - <#=method.GetElementOperation(type.TypeName, "Span[i]")#>; - } - } - else - { - int rowMajorIndex = 0; - int colMajorIndex = 0; - - ref int resultIndex = ref <#= method.ResultName #>.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - ref int op1Index = ref <#= method.Op1Name #>.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - -<# if ((method.MethodType == MethodType.Binary) || (method.MethodType == MethodType.Comparison)) {#> - ref int op2Index = ref <#= method.Op2Name #>.IsReversedStride ? ref colMajorIndex : ref rowMajorIndex; - - var rowMajorStrides = !<#= method.ResultName #>.IsReversedStride ? <#= method.ResultName #>.strides : - !<#= method.Op1Name #>.IsReversedStride ? <#= method.Op1Name #>.strides : - <#= method.Op2Name #>.strides; - var columnMajorStrides = <#= method.ResultName #>.IsReversedStride ? <#= method.ResultName #>.strides : - <#= method.Op1Name #>.IsReversedStride ? <#= method.Op1Name #>.strides : - <#= method.Op2Name #>.strides; -<# } else {#> - var rowMajorStrides = !<#= method.ResultName #>.IsReversedStride ? <#= method.ResultName #>.strides : - <#= method.Op1Name #>.strides; - var columnMajorStrides = <#= method.ResultName #>.IsReversedStride ? <#= method.ResultName #>.strides : - <#= method.Op1Name #>.strides; -<# } #> - for(;rowMajorIndex < <#= method.ResultName #>Span.Length; rowMajorIndex++) - { - colMajorIndex = ArrayUtilities.TransformIndexByStrides(rowMajorIndex, rowMajorStrides, false, columnMajorStrides); - - <#=method.GetElementOperation(type.TypeName, "Span[resultIndex]", "Span[op1Index]", "Span[op2Index]")#>; - - } - } -<# } #> -<# } else if (method.MethodName == "Contract") {#> - var summingDimensions = new int[leftAxes.Length]; - for(int i = 0; i < leftAxes.Length; i++) - { - summingDimensions[i] = left.dimensions[leftAxes[i]]; - } - - var summingStrides = ArrayUtilities.GetStrides(summingDimensions); - int summingLength = (int)ArrayUtilities.GetProduct(summingDimensions); - - var resultStrides = result.strides; - - // translates from result index to left non-summing dimensions' index portion - // since left non-summing dimensions are given precedence in result, the end is zero-padded - int[] leftNonSummingStrides = new int[result.Rank]; - - // translates from summing index to left summing dimensions' index portion - int[] leftSummingStrides = new int[leftAxes.Length]; - ArrayUtilities.SplitStrides(left.strides, leftAxes, leftNonSummingStrides, 0, leftSummingStrides, 0); - - // translates from result index to right non-summing dimensions' index portion - int[] rightNonSummingStrides = new int[result.Rank]; - // right non-summing dimensions appear after left non-summing dimensions. - int rightNonSummingStridesOffset = (left.Rank - leftAxes.Length); - - // translates from summing index to right summing dimensions' index portion - int[] rightSummingStrides = new int[rightAxes.Length]; - ArrayUtilities.SplitStrides(right.strides, rightAxes, rightNonSummingStrides, rightNonSummingStridesOffset, rightSummingStrides, 0); - - var resultSpan = result.Buffer.Span; - var leftSpan = left.Buffer.Span; - var rightSpan = right.Buffer.Span; - - for (int resultIndex = 0; resultIndex < resultSpan.Length; resultIndex++) - { - <#=type.TypeName#> sum = (<#=type.TypeName#>)0; - - int leftIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, leftNonSummingStrides); - int rightIndexNonSumming = ArrayUtilities.TransformIndexByStrides(resultIndex, resultStrides, result.IsReversedStride, rightNonSummingStrides); - - for (int summingIndex = 0; summingIndex < summingLength; summingIndex++) - { - int leftIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, leftSummingStrides); - int rightIndexSumming = ArrayUtilities.TransformIndexByStrides(summingIndex, summingStrides, false, rightSummingStrides); - - int leftIndex = leftIndexNonSumming + leftIndexSumming; - int rightIndex = rightIndexNonSumming + rightIndexSumming; - - sum += (<#=type.TypeName#>)(leftSpan[leftIndex] * rightSpan[rightIndex]); - } - - resultSpan[resultIndex] = sum; - } -<# } #> - } -<# } #> - } -<# } #> -} diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorExtensions.cs b/src/libraries/System.Numerics.Tensors/tests/TensorExtensions.cs deleted file mode 100644 index 2aa79f0e120589..00000000000000 --- a/src/libraries/System.Numerics.Tensors/tests/TensorExtensions.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Numerics.Tensors -{ - public static partial class TensorExtensions - { - private static int[] s_zeroArray = new[] { 0 }; - private static int[] s_oneArray = new[] { 1 }; - - internal static Tensor MatrixMultiply(this Tensor left, Tensor right) - { - if (left.Rank != 2) - { - throw new InvalidOperationException($"{nameof(MatrixMultiply)} is only valid for a {nameof(Tensor)} of {nameof(left.Rank)} 2."); - } - - if (right.Rank != 2) - { - throw new ArgumentException($"{nameof(Tensor)} {nameof(right)} must have {nameof(left.Rank)} 2.", nameof(right)); - } - - if (left.dimensions[1] != right.dimensions[0]) - { - throw new ArgumentException($"{nameof(Tensor)} {nameof(right)} must have first dimension of {left.dimensions[1]}.", nameof(right)); - } - - return TensorOperations.Contract(left, right, s_oneArray, s_zeroArray); - } - } -} diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorOperations.cs b/src/libraries/System.Numerics.Tensors/tests/TensorOperations.cs deleted file mode 100644 index 009ad006b88c53..00000000000000 --- a/src/libraries/System.Numerics.Tensors/tests/TensorOperations.cs +++ /dev/null @@ -1,738 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Numerics.Tensors -{ - public static partial class TensorOperations - { - internal static void ValidateBinaryArgs(Tensor left, Tensor right) - { - if (left.Rank != right.Rank || left.Length != right.Length) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(right)); - } - - if (left.Rank == 0) - { - throw new ArgumentException($"Cannot operate on Tensor with {nameof(Tensor.Rank)} of 0.", nameof(left)); - } - - for (int i = 0; i < left.Rank; i++) - { - if (left.dimensions[i] != right.dimensions[i]) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(right)); - } - } - } - - internal static void ValidateBinaryArgs(Tensor left, Tensor right, Tensor result) - { - if (left.Rank != right.Rank || left.Length != right.Length) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(right)); - } - - if (left.Rank != result.Rank || left.Length != result.Length) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(result)); - } - - if (left.Rank == 0) - { - throw new ArgumentException($"Cannot operate on Tensor with {nameof(Tensor.Rank)} of 0.", nameof(left)); - } - - for (int i = 0; i < result.Rank; i++) - { - if (left.dimensions[i] != right.dimensions[i]) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(right)); - } - - if (left.dimensions[i] != result.dimensions[i]) - { - throw new ArgumentException("Operands and result must have matching dimensions", nameof(result)); - } - } - } - - internal static void ValidateBinaryArgs(Tensor left, Tensor right, Tensor result) - { - if (left.Rank != right.Rank || left.Length != right.Length) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(right)); - } - - if (left.Rank != result.Rank || left.Length != result.Length) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(result)); - } - - if (left.Rank == 0) - { - throw new ArgumentException($"Cannot operate on Tensor with {nameof(Tensor.Rank)} of 0.", nameof(left)); - } - - for (int i = 0; i < result.Rank; i++) - { - if (left.dimensions[i] != right.dimensions[i]) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(right)); - } - - if (left.dimensions[i] != result.dimensions[i]) - { - throw new ArgumentException("Operands and result must have matching dimensions", nameof(result)); - } - } - } - - internal static void ValidateArgs(Tensor tensor) - { - if (tensor.Rank == 0) - { - throw new ArgumentException($"Cannot operate on Tensor with {nameof(Tensor.Rank)} of 0.", nameof(tensor)); - } - } - - internal static void ValidateArgs(Tensor tensor, Tensor result) - { - if (tensor.Rank != result.Rank || tensor.Length != result.Length) - { - throw new ArgumentException("Operands and result must have matching dimensions", nameof(result)); - } - - if (tensor.Rank == 0) - { - throw new ArgumentException($"Cannot operate on Tensor with {nameof(Tensor.Rank)} of 0.", nameof(tensor)); - } - - for (int i = 0; i < result.Rank; i++) - { - if (tensor.dimensions[i] != result.dimensions[i]) - { - throw new ArgumentException("Operands and result must have matching dimensions", nameof(result)); - } - } - } - - internal static int[] ValidateContractArgs(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes) - { - if (leftAxes == null) - { - throw new ArgumentNullException(nameof(left)); - } - - if (rightAxes == null) - { - throw new ArgumentNullException(nameof(left)); - } - - if (leftAxes.Length != rightAxes.Length) - { - throw new ArgumentException($"{nameof(leftAxes)} and {nameof(rightAxes)} must have the same length, but were {leftAxes.Length} and {rightAxes.Length}, respectively."); - } - - for (int i = 0; i < leftAxes.Length; i++) - { - var leftAxis = leftAxes[i]; - - if (leftAxis >= left.Rank) - { - throw new ArgumentOutOfRangeException($"{nameof(leftAxes)}[{i}] was set to axis index {leftAxis} which exceeds the Rank of {left}."); - } - - var leftDimension = left.dimensions[leftAxis]; - - var rightAxis = rightAxes[i]; - - if (rightAxis >= right.Rank) - { - throw new ArgumentOutOfRangeException($"{nameof(rightAxes)}[{i}] was set to axis index {rightAxis} which exceeds the Rank of {right}."); - } - - var rightDimension = right.dimensions[rightAxis]; - - if (leftDimension != rightDimension) - { - throw new ArgumentOutOfRangeException($"Tensors may only be contracted on axes of the same length, but {nameof(leftAxes)} index {i} was length {leftDimension} and {nameof(rightAxes)} index {i} was length {rightDimension}."); - } - } - - var leftNonSummingDimensions = left.Rank - leftAxes.Length; - var rightNonSummingDimensions = right.Rank - rightAxes.Length; - var resultDimensions = new int[leftNonSummingDimensions + rightNonSummingDimensions]; - int dimensionsIndex = 0; - - Action, int[]> fillDimensions = (tensor, axes) => - { - for (int i = 0; i < tensor.Rank; i++) - { - var skip = false; - foreach (var contractionIndex in axes) - { - if (contractionIndex == i) - { - skip = true; - break; - } - } - - if (!skip) - { - resultDimensions[dimensionsIndex++] = tensor.dimensions[i]; - } - } - }; - - fillDimensions(left, leftAxes); - fillDimensions(right, rightAxes); - - return resultDimensions; - } - - internal static int[] ValidateContractArgs(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var expectedDimensions = ValidateContractArgs(left, right, leftAxes, rightAxes); - - if (result.Rank != expectedDimensions.Length) - { - throw new ArgumentException($"{nameof(result)} should have {expectedDimensions.Length} dimensions but had {result.Rank}."); - } - - for (int i = 0; i < expectedDimensions.Length; i++) - { - if (result.dimensions[i] != expectedDimensions[i]) - { - throw new ArgumentException($"{nameof(result)} dimension {i} should be {expectedDimensions[i]} but was {result.dimensions[i]}."); - } - } - - return expectedDimensions; - } - - internal static void Add(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.Add(left, right, result); - } - - internal static Tensor Add(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.Add(left, right, result); - - return result; - } - - internal static void Add(Tensor tensor, T scalar, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.Add(tensor, scalar, result); - } - - internal static Tensor Add(Tensor tensor, T scalar) - { - ValidateArgs(tensor); - - var result = tensor.CloneEmpty(); - - TensorArithmetic.Instance.Add(tensor, scalar, result); - - return result; - } - - internal static void And(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.And(left, right, result); - } - - internal static Tensor And(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.And(left, right, result); - - return result; - } - - internal static void And(Tensor tensor, T scalar, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.And(tensor, scalar, result); - } - - internal static Tensor And(Tensor tensor, T scalar) - { - ValidateArgs(tensor); - - var result = tensor.CloneEmpty(); - - TensorArithmetic.Instance.And(tensor, scalar, result); - - return result; - } - - internal static void Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - ValidateContractArgs(left, right, leftAxes, rightAxes, result); - - TensorArithmetic.Instance.Contract(left, right, leftAxes, rightAxes, result); - } - - internal static Tensor Contract(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes) - { - var resultDimensions = ValidateContractArgs(left, right, leftAxes, rightAxes); - - var result = left.CloneEmpty(resultDimensions); - - TensorArithmetic.Instance.Contract(left, right, leftAxes, rightAxes, result); - - return result; - } - - internal static void Decrement(Tensor tensor, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.Decrement(tensor, result); - } - - internal static Tensor Decrement(Tensor tensor) - { - ValidateArgs(tensor); - - var result = tensor.Clone(); - - TensorArithmetic.Instance.Decrement(tensor, result); - - return result; - } - - internal static void Divide(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.Divide(left, right, result); - } - - internal static Tensor Divide(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.Divide(left, right, result); - - return result; - } - - internal static void Divide(Tensor tensor, T scalar, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.Divide(tensor, scalar, result); - } - - internal static Tensor Divide(Tensor tensor, T scalar) - { - ValidateArgs(tensor); - - var result = tensor.CloneEmpty(); - - TensorArithmetic.Instance.Divide(tensor, scalar, result); - - return result; - } - - internal static void Equals(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.Equals(left, right, result); - } - - internal static Tensor Equals(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.Equals(left, right, result); - - return result; - } - - internal static void GreaterThan(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.GreaterThan(left, right, result); - } - - internal static Tensor GreaterThan(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.GreaterThan(left, right, result); - - return result; - } - - internal static void GreaterThanOrEqual(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.GreaterThanOrEqual(left, right, result); - } - - internal static Tensor GreaterThanOrEqual(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.GreaterThanOrEqual(left, right, result); - - return result; - } - - internal static void Increment(Tensor tensor, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.Increment(tensor, result); - } - - internal static Tensor Increment(Tensor tensor) - { - ValidateArgs(tensor); - - var result = tensor.Clone(); - - TensorArithmetic.Instance.Increment(tensor, result); - - return result; - } - - internal static void LeftShift(Tensor tensor, int value, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.LeftShift(tensor, value, result); - } - - internal static Tensor LeftShift(Tensor tensor, int value) - { - ValidateArgs(tensor); - - var result = tensor.CloneEmpty(); - - TensorArithmetic.Instance.LeftShift(tensor, value, result); - - return result; - } - - internal static void LessThan(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.LessThan(left, right, result); - } - - internal static Tensor LessThan(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.LessThan(left, right, result); - - return result; - } - - internal static void LessThanOrEqual(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.LessThanOrEqual(left, right, result); - } - - internal static Tensor LessThanOrEqual(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.LessThanOrEqual(left, right, result); - - return result; - } - - internal static void Modulo(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.Modulo(left, right, result); - } - - internal static Tensor Modulo(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.Modulo(left, right, result); - - return result; - } - - internal static void Modulo(Tensor tensor, T scalar, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.Modulo(tensor, scalar, result); - } - - internal static Tensor Modulo(Tensor tensor, T scalar) - { - ValidateArgs(tensor); - - var result = tensor.CloneEmpty(); - - TensorArithmetic.Instance.Modulo(tensor, scalar, result); - - return result; - } - - internal static void Multiply(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.Multiply(left, right, result); - } - - internal static Tensor Multiply(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.Multiply(left, right, result); - - return result; - } - - internal static void Multiply(Tensor tensor, T scalar, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.Multiply(tensor, scalar, result); - } - - internal static Tensor Multiply(Tensor tensor, T scalar) - { - ValidateArgs(tensor); - - var result = tensor.CloneEmpty(); - - TensorArithmetic.Instance.Multiply(tensor, scalar, result); - - return result; - } - - internal static void NotEquals(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.NotEquals(left, right, result); - } - - internal static Tensor NotEquals(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.NotEquals(left, right, result); - - return result; - } - - internal static void Or(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.Or(left, right, result); - } - - internal static Tensor Or(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.Or(left, right, result); - - return result; - } - - internal static void Or(Tensor tensor, T scalar, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.Or(tensor, scalar, result); - } - - internal static Tensor Or(Tensor tensor, T scalar) - { - ValidateArgs(tensor); - - var result = tensor.CloneEmpty(); - - TensorArithmetic.Instance.Or(tensor, scalar, result); - - return result; - } - - internal static void RightShift(Tensor tensor, int value, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.RightShift(tensor, value, result); - } - - internal static Tensor RightShift(Tensor tensor, int value) - { - ValidateArgs(tensor); - - var result = tensor.CloneEmpty(); - - TensorArithmetic.Instance.RightShift(tensor, value, result); - - return result; - } - - internal static void Subtract(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.Subtract(left, right, result); - } - - internal static Tensor Subtract(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.Subtract(left, right, result); - - return result; - } - - internal static void Subtract(Tensor tensor, T scalar, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.Subtract(tensor, scalar, result); - } - - internal static Tensor Subtract(Tensor tensor, T scalar) - { - ValidateArgs(tensor); - - var result = tensor.CloneEmpty(); - - TensorArithmetic.Instance.Subtract(tensor, scalar, result); - - return result; - } - - internal static void UnaryMinus(Tensor tensor, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.UnaryMinus(tensor, result); - } - - internal static Tensor UnaryMinus(Tensor tensor) - { - ValidateArgs(tensor); - - var result = tensor.CloneEmpty(); - - TensorArithmetic.Instance.UnaryMinus(tensor, result); - - return result; - } - - internal static void UnaryPlus(Tensor tensor, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.UnaryPlus(tensor, result); - } - - internal static Tensor UnaryPlus(Tensor tensor) - { - ValidateArgs(tensor); - - var result = tensor.CloneEmpty(); - - TensorArithmetic.Instance.UnaryPlus(tensor, result); - - return result; - } - - internal static void Xor(Tensor left, Tensor right, Tensor result) - { - ValidateBinaryArgs(left, right, result); - - TensorArithmetic.Instance.Xor(left, right, result); - } - - internal static Tensor Xor(Tensor left, Tensor right) - { - ValidateBinaryArgs(left, right); - - var result = left.CloneEmpty(); - - TensorArithmetic.Instance.Xor(left, right, result); - - return result; - } - - internal static void Xor(Tensor tensor, T scalar, Tensor result) - { - ValidateArgs(tensor, result); - - TensorArithmetic.Instance.Xor(tensor, scalar, result); - } - - internal static Tensor Xor(Tensor tensor, T scalar) - { - ValidateArgs(tensor); - - var result = tensor.CloneEmpty(); - - TensorArithmetic.Instance.Xor(tensor, scalar, result); - - return result; - } - - } -} diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorOperations.tt b/src/libraries/System.Numerics.Tensors/tests/TensorOperations.tt deleted file mode 100644 index 6b96c0bb554a5a..00000000000000 --- a/src/libraries/System.Numerics.Tensors/tests/TensorOperations.tt +++ /dev/null @@ -1,239 +0,0 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ output extension=".cs" #> -<#@ include file="TensorTemplate.ttinclude" #>// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Numerics.Tensors -{ - public static partial class TensorOperations - { - internal static void ValidateBinaryArgs(Tensor left, Tensor right) - { - if (left.Rank != right.Rank || left.Length != right.Length) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(right)); - } - - if (left.Rank == 0) - { - throw new ArgumentException($"Cannot operate on Tensor with {nameof(Tensor.Rank)} of 0.", nameof(left)); - } - - for (int i = 0; i < left.Rank; i++) - { - if (left.dimensions[i] != right.dimensions[i]) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(right)); - } - } - } - - internal static void ValidateBinaryArgs(Tensor left, Tensor right, Tensor result) - { - if (left.Rank != right.Rank || left.Length != right.Length) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(right)); - } - - if (left.Rank != result.Rank || left.Length != result.Length) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(result)); - } - - if (left.Rank == 0) - { - throw new ArgumentException($"Cannot operate on Tensor with {nameof(Tensor.Rank)} of 0.", nameof(left)); - } - - for (int i = 0; i < result.Rank; i++) - { - if (left.dimensions[i] != right.dimensions[i]) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(right)); - } - - if (left.dimensions[i] != result.dimensions[i]) - { - throw new ArgumentException("Operands and result must have matching dimensions", nameof(result)); - } - } - } - - internal static void ValidateBinaryArgs(Tensor left, Tensor right, Tensor result) - { - if (left.Rank != right.Rank || left.Length != right.Length) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(right)); - } - - if (left.Rank != result.Rank || left.Length != result.Length) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(result)); - } - - if (left.Rank == 0) - { - throw new ArgumentException($"Cannot operate on Tensor with {nameof(Tensor.Rank)} of 0.", nameof(left)); - } - - for (int i = 0; i < result.Rank; i++) - { - if (left.dimensions[i] != right.dimensions[i]) - { - throw new ArgumentException("Operands must have matching dimensions", nameof(right)); - } - - if (left.dimensions[i] != result.dimensions[i]) - { - throw new ArgumentException("Operands and result must have matching dimensions", nameof(result)); - } - } - } - - internal static void ValidateArgs(Tensor tensor) - { - if (tensor.Rank == 0) - { - throw new ArgumentException($"Cannot operate on Tensor with {nameof(Tensor.Rank)} of 0.", nameof(tensor)); - } - } - - internal static void ValidateArgs(Tensor tensor, Tensor result) - { - if (tensor.Rank != result.Rank || tensor.Length != result.Length) - { - throw new ArgumentException("Operands and result must have matching dimensions", nameof(result)); - } - - if (tensor.Rank == 0) - { - throw new ArgumentException($"Cannot operate on Tensor with {nameof(Tensor.Rank)} of 0.", nameof(tensor)); - } - - for (int i = 0; i < result.Rank; i++) - { - if (tensor.dimensions[i] != result.dimensions[i]) - { - throw new ArgumentException("Operands and result must have matching dimensions", nameof(result)); - } - } - } - - internal static int[] ValidateContractArgs(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes) - { - if (leftAxes == null) - { - throw new ArgumentNullException(nameof(left)); - } - - if (rightAxes == null) - { - throw new ArgumentNullException(nameof(left)); - } - - if (leftAxes.Length != rightAxes.Length) - { - throw new ArgumentException($"{nameof(leftAxes)} and {nameof(rightAxes)} must have the same length, but were {leftAxes.Length} and {rightAxes.Length}, respectively."); - } - - for (int i = 0; i < leftAxes.Length; i++) - { - var leftAxis = leftAxes[i]; - - if (leftAxis >= left.Rank) - { - throw new ArgumentOutOfRangeException($"{nameof(leftAxes)}[{i}] was set to axis index {leftAxis} which exceeds the Rank of {left}."); - } - - var leftDimension = left.dimensions[leftAxis]; - - var rightAxis = rightAxes[i]; - - if (rightAxis >= right.Rank) - { - throw new ArgumentOutOfRangeException($"{nameof(rightAxes)}[{i}] was set to axis index {rightAxis} which exceeds the Rank of {right}."); - } - - var rightDimension = right.dimensions[rightAxis]; - - if (leftDimension != rightDimension) - { - throw new ArgumentOutOfRangeException($"Tensors may only be contracted on axes of the same length, but {nameof(leftAxes)} index {i} was length {leftDimension} and {nameof(rightAxes)} index {i} was length {rightDimension}."); - } - } - - var leftNonSummingDimensions = left.Rank - leftAxes.Length; - var rightNonSummingDimensions = right.Rank - rightAxes.Length; - var resultDimensions = new int[leftNonSummingDimensions + rightNonSummingDimensions]; - int dimensionsIndex = 0; - - Action, int[]> fillDimensions = (tensor, axes) => - { - for (int i = 0; i < tensor.Rank; i++) - { - var skip = false; - foreach (var contractionIndex in axes) - { - if (contractionIndex == i) - { - skip = true; - break; - } - } - - if (!skip) - { - resultDimensions[dimensionsIndex++] = tensor.dimensions[i]; - } - } - }; - - fillDimensions(left, leftAxes); - fillDimensions(right, rightAxes); - - return resultDimensions; - } - - internal static int[] ValidateContractArgs(Tensor left, Tensor right, int[] leftAxes, int[] rightAxes, Tensor result) - { - var expectedDimensions = ValidateContractArgs(left, right, leftAxes, rightAxes); - - if (result.Rank != expectedDimensions.Length) - { - throw new ArgumentException($"{nameof(result)} should have {expectedDimensions.Length} dimensions but had {result.Rank}."); - } - - for (int i = 0; i < expectedDimensions.Length; i++) - { - if (result.dimensions[i] != expectedDimensions[i]) - { - throw new ArgumentException($"{nameof(result)} dimension {i} should be {expectedDimensions[i]} but was {result.dimensions[i]}."); - } - } - - return expectedDimensions; - } - -<# foreach (MethodConfiguration method in methodConfiguration) { #> - internal static <#= method.GetGenericResultMethodSignature("Tensor", "T")#> - { - <#= method.GetValidationMethod(true) #> - - TensorArithmetic.Instance.<#=method.MethodName#>(<#=method.GetCallArguments()#>, <#= method.ResultName #>); - } - - internal static <#= method.GetGenericMethodSignature("Tensor", "T")#> - { - <#= method.GetValidationMethod(false) #> - - var <#= method.ResultName #> = <#=method.InitializeResult("T")#>; - - TensorArithmetic.Instance.<#=method.MethodName#>(<#=method.GetCallArguments()#>, <#= method.ResultName #>); - - return <#= method.ResultName #>; - } - -<# } #> - } -} diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.cs new file mode 100644 index 00000000000000..181d152e6ae979 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.cs @@ -0,0 +1,1484 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using Xunit; + +#pragma warning disable xUnit1025 // reporting duplicate test cases due to not distinguishing 0.0 from -0.0 + +namespace System.Numerics.Tensors.Tests +{ + public static partial class TensorPrimitivesTests + { + private const double Tolerance = 0.0001; + + public static IEnumerable TensorLengths => + from length in Enumerable.Range(1, 128) + select new object[] { length }; + + private static readonly Random s_random = new Random(20230828); + + private static BoundedMemory CreateTensor(int size) => BoundedMemory.Allocate(size); + + private static BoundedMemory CreateAndFillTensor(int size) + { + BoundedMemory tensor = CreateTensor(size); + FillTensor(tensor.Span); + return tensor; + } + + private static void FillTensor(Span tensor) + { + for (int i = 0; i < tensor.Length; i++) + { + tensor[i] = NextSingle(); + } + } + + private static float NextSingle() + { + // For testing purposes, get a mix of negative and positive values. + return (float)((s_random.NextDouble() * 2) - 1); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTwoTensors(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Add(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(x[i] + y[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTwoTensors_ThrowsForMismatchedLengths(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.Add(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTwoTensors_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Add(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTensorAndScalar(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Add(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(x[i] + y, destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTensorAndScalar_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Add(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void SubtractTwoTensors(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Subtract(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(x[i] - y[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void SubtractTwoTensors_ThrowsForMismatchedLengths(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.Subtract(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void SubtractTwoTensors_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Subtract(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void SubtractTensorAndScalar(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Subtract(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(x[i] - y, destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void SubtractTensorAndScalar_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Subtract(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyTwoTensors(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Multiply(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(x[i] * y[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyTwoTensors_ThrowsForMismatchedLengths(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.Multiply(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyTwoTensors_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Multiply(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyTensorAndScalar(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Multiply(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(x[i] * y, destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyTensorAndScalar_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Multiply(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void DivideTwoTensors(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Divide(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(x[i] / y[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void DivideTwoTensors_ThrowsForMismatchedLengths(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.Divide(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void DivideTwoTensors_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void DivideTensorAndScalar(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Divide(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(x[i] / y, destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void DivideTensorAndScalar_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void NegateTensor(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Negate(x, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(-x[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void NegateTensor_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Negate(x, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTwoTensorsAndMultiplyWithThirdTensor(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory multiplier = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.AddMultiply(x, y, multiplier, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal((x[i] + y[i]) * multiplier[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTwoTensorsAndMultiplyWithThirdTensor_ThrowsForMismatchedLengths_x_y(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory multiplier = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTwoTensorsAndMultiplyWithThirdTensor_ThrowsForMismatchedLengths_x_multiplier(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory multiplier = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTwoTensorsAndMultiplyWithThirdTensor_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory multiplier = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTwoTensorsAndMultiplyWithScalar(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + float multiplier = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.AddMultiply(x, y, multiplier, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal((x[i] + y[i]) * multiplier, destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTwoTensorsAndMultiplyWithScalar_ThrowsForMismatchedLengths_x_y(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + float multiplier = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTwoTensorsAndMultiplyWithScalar_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + float multiplier = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTensorAndScalarAndMultiplyWithTensor(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory multiplier = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.AddMultiply(x, y, multiplier, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal((x[i] + y) * multiplier[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTensorAndScalarAndMultiplyWithTensor_ThrowsForMismatchedLengths_x_z(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory multiplier = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void AddTensorAndScalarAndMultiplyWithTensor_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory multiplier = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyTwoTensorsAndAddWithThirdTensor(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory addend = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.MultiplyAdd(x, y, addend, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal((x[i] * y[i]) + addend[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyTwoTensorsAndAddWithThirdTensor_ThrowsForMismatchedLengths_x_y(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory addend = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.MultiplyAdd(x, y, addend, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyTwoTensorsAndAddWithThirdTensor_ThrowsForMismatchedLengths_x_multiplier(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory addend = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.MultiplyAdd(x, y, addend, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyTwoTensorsAndAddWithThirdTensor_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory addend = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(x, y, addend, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyTwoTensorsAndAddWithScalar(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + float addend = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.MultiplyAdd(x, y, addend, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal((x[i] * y[i]) + addend, destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyTwoTensorsAndAddWithScalar_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + float addend = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(x, y, addend, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyTensorAndScalarAndAddWithTensor(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory addend = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.MultiplyAdd(x, y, addend, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal((x[i] * y) + addend[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyTensorAndScalarAndAddWithTensor_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory addend = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(x, y, addend, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void ExpTensor(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Exp(x, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(MathF.Exp(x[i]), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void ExpTensor_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Exp(x, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void LogTensor(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Log(x, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(MathF.Log(x[i]), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void LogTensor_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Log(x, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void CoshTensor(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Cosh(x, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(MathF.Cosh(x[i]), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void CoshTensor_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Cosh(x, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void SinhTensor(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Sinh(x, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(MathF.Sinh(x[i]), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void SinhTensor_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Sinh(x, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void TanhTensor(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Tanh(x, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(MathF.Tanh(x[i]), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void TanhTensor_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Tanh(x, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void CosineSimilarity_ThrowsForMismatchedLengths_x_y(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + + Assert.Throws(() => TensorPrimitives.CosineSimilarity(x, y)); + } + + [Fact] + public static void CosineSimilarity_ThrowsForEmpty_x_y() + { + Assert.Throws(() => TensorPrimitives.CosineSimilarity(ReadOnlySpan.Empty, ReadOnlySpan.Empty)); + Assert.Throws(() => TensorPrimitives.CosineSimilarity(ReadOnlySpan.Empty, CreateTensor(1))); + Assert.Throws(() => TensorPrimitives.CosineSimilarity(CreateTensor(1), ReadOnlySpan.Empty)); + } + + [Theory] + [InlineData(new float[] { 3, 2, 0, 5 }, new float[] { 1, 0, 0, 0 }, 0.48666f)] + [InlineData(new float[] { 1, 1, 1, 1, 1, 0 }, new float[] { 1, 1, 1, 1, 0, 1 }, 0.80f)] + public static void CosineSimilarity_KnownValues(float[] x, float[] y, float expectedResult) + { + Assert.Equal(expectedResult, TensorPrimitives.CosineSimilarity(x, y), Tolerance); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void CosineSimilarity(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + + float dot = 0f, squareX = 0f, squareY = 0f; + for (int i = 0; i < x.Length; i++) + { + dot += x[i] * y[i]; + squareX += x[i] * x[i]; + squareY += y[i] * y[i]; + } + + Assert.Equal(dot / (Math.Sqrt(squareX) * Math.Sqrt(squareY)), TensorPrimitives.CosineSimilarity(x, y), Tolerance); + } + + [Fact] + public static void Distance_ThrowsForEmpty_x_y() + { + Assert.Throws(() => TensorPrimitives.Distance(ReadOnlySpan.Empty, ReadOnlySpan.Empty)); + Assert.Throws(() => TensorPrimitives.Distance(ReadOnlySpan.Empty, CreateTensor(1))); + Assert.Throws(() => TensorPrimitives.Distance(CreateTensor(1), ReadOnlySpan.Empty)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Distance_ThrowsForMismatchedLengths_x_y(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + + Assert.Throws(() => TensorPrimitives.Distance(x, y)); + } + + [Theory] + [InlineData(new float[] { 3, 2 }, new float[] { 4, 1 }, 1.4142f)] + [InlineData(new float[] { 0, 4 }, new float[] { 6, 2 }, 6.3245f)] + [InlineData(new float[] { 1, 2, 3 }, new float[] { 4, 5, 6 }, 5.1961f)] + [InlineData(new float[] { 5, 1, 6, 10 }, new float[] { 7, 2, 8, 4 }, 6.7082f)] + public static void Distance_KnownValues(float[] x, float[] y, float expectedResult) + { + Assert.Equal(expectedResult, TensorPrimitives.Distance(x, y), Tolerance); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Distance(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + + float distance = 0f; + for (int i = 0; i < x.Length; i++) + { + distance += (x[i] - y[i]) * (x[i] - y[i]); + } + + Assert.Equal(Math.Sqrt(distance), TensorPrimitives.Distance(x, y), Tolerance); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Dot_ThrowsForMismatchedLengths_x_y(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + + Assert.Throws(() => TensorPrimitives.Dot(x, y)); + } + + [Theory] + [InlineData(new float[] { 1, 3, -5 }, new float[] { 4, -2, -1 }, 3)] + [InlineData(new float[] { 1, 2, 3 }, new float[] { 4, 5, 6 }, 32)] + [InlineData(new float[] { 1, 2, 3, 10, 8 }, new float[] { 4, 5, 6, -2, 7 }, 68)] + [InlineData(new float[] { }, new float[] { }, 0)] + public static void Dot_KnownValues(float[] x, float[] y, float expectedResult) + { + Assert.Equal(expectedResult, TensorPrimitives.Dot(x, y), Tolerance); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Dot(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + + float dot = 0f; + for (int i = 0; i < x.Length; i++) + { + dot += x[i] * y[i]; + } + + Assert.Equal(dot, TensorPrimitives.Dot(x, y), Tolerance); + } + + [Theory] + [InlineData(new float[] { 1, 2, 3 }, 3.7416575f)] + [InlineData(new float[] { 3, 4 }, 5)] + [InlineData(new float[] { 3 }, 3)] + [InlineData(new float[] { 3, 4, 1, 2 }, 5.477226)] + [InlineData(new float[] { }, 0f)] + public static void L2Normalize_KnownValues(float[] x, float expectedResult) + { + Assert.Equal(expectedResult, TensorPrimitives.L2Normalize(x), Tolerance); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void L2Normalize(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + float sumOfSquares = 0f; + for (int i = 0; i < x.Length; i++) + { + sumOfSquares += x[i] * x[i]; + } + + Assert.Equal(Math.Sqrt(sumOfSquares), TensorPrimitives.L2Normalize(x), Tolerance); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void SoftMax_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.SoftMax(x, destination)); + } + + [Theory] + [InlineData(new float[] { 3, 1, .2f }, new float[] { 0.8360188f, 0.11314284f, 0.05083836f })] + [InlineData(new float[] { 3, 4, 1 }, new float[] { 0.2594f, 0.705384f, 0.0351f })] + [InlineData(new float[] { 5, 3 }, new float[] { 0.8807f, 0.1192f })] + [InlineData(new float[] { 4, 2, 1, 9 }, new float[] { 0.0066f, 9.04658e-4f, 3.32805e-4f, 0.9920f})] + public static void SoftMax(float[] x, float[] expectedResult) + { + using BoundedMemory dest = CreateTensor(x.Length); + TensorPrimitives.SoftMax(x, dest); + + for (int i = 0; i < x.Length; i++) + { + Assert.Equal(expectedResult[i], dest[i], Tolerance); + } + } + + [Fact] + public static void SoftMax_DestinationLongerThanSource() + { + float[] x = [3, 1, .2f]; + float[] expectedResult = [0.8360188f, 0.11314284f, 0.05083836f]; + using BoundedMemory dest = CreateTensor(x.Length + 1); + TensorPrimitives.SoftMax(x, dest); + + for (int i = 0; i < x.Length; i++) + { + Assert.Equal(expectedResult[i], dest[i], Tolerance); + } + } + + [Fact] + public static void SoftMax_ThrowsForEmptyInput() + { + AssertExtensions.Throws(() => TensorPrimitives.SoftMax(ReadOnlySpan.Empty, CreateTensor(1))); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Sigmoid_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Sigmoid(x, destination)); + } + + [Theory] + [InlineData(new float[] { -5, -4.5f, -4 }, new float[] { 0.0066f, 0.0109f, 0.0179f })] + [InlineData(new float[] { 4.5f, 5 }, new float[] { 0.9890f, 0.9933f })] + [InlineData(new float[] { 0, -3, 3, .5f }, new float[] { 0.5f, 0.0474f, 0.9525f, 0.6224f })] + public static void Sigmoid(float[] x, float[] expectedResult) + { + using BoundedMemory dest = CreateTensor(x.Length); + TensorPrimitives.Sigmoid(x, dest); + + for (int i = 0; i < x.Length; i++) + { + Assert.Equal(expectedResult[i], dest[i], Tolerance); + } + } + + [Fact] + public static void Sigmoid_DestinationLongerThanSource() + { + float[] x = [-5, -4.5f, -4]; + float[] expectedResult = [0.0066f, 0.0109f, 0.0179f]; + using BoundedMemory dest = CreateTensor(x.Length + 1); + + TensorPrimitives.Sigmoid(x, dest); + + float originalLast = dest[dest.Length - 1]; + for (int i = 0; i < x.Length; i++) + { + Assert.Equal(expectedResult[i], dest[i], Tolerance); + } + Assert.Equal(originalLast, dest[dest.Length - 1]); + } + + [Fact] + public static void Sigmoid_ThrowsForEmptyInput() + { + AssertExtensions.Throws(() => TensorPrimitives.Sigmoid(ReadOnlySpan.Empty, CreateTensor(1))); + } + + [Fact] + public static void IndexOfMax_ReturnsNegative1OnEmpty() + { + Assert.Equal(-1, TensorPrimitives.IndexOfMax(ReadOnlySpan.Empty)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void IndexOfMax(int tensorLength) + { + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + x[expected] = Enumerable.Max(MemoryMarshal.ToEnumerable(x.Memory)) + 1; + Assert.Equal(expected, TensorPrimitives.IndexOfMax(x)); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void IndexOfMax_FirstNaNReturned(int tensorLength) + { + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + x[expected] = float.NaN; + x[tensorLength - 1] = float.NaN; + Assert.Equal(expected, TensorPrimitives.IndexOfMax(x)); + } + } + + [Fact] + public static void IndexOfMax_Negative0LesserThanPositive0() + { + Assert.Equal(1, TensorPrimitives.IndexOfMax([-0f, +0f])); + Assert.Equal(0, TensorPrimitives.IndexOfMax([-0f, -0f, -0f, -0f])); + Assert.Equal(4, TensorPrimitives.IndexOfMax([-0f, -0f, -0f, -0f, +0f, +0f, +0f])); + Assert.Equal(0, TensorPrimitives.IndexOfMax([+0f, -0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMax([-1, -0f])); + Assert.Equal(2, TensorPrimitives.IndexOfMax([-1, -0f, 1])); + } + + [Fact] + public static void IndexOfMin_ReturnsNegative1OnEmpty() + { + Assert.Equal(-1, TensorPrimitives.IndexOfMin(ReadOnlySpan.Empty)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void IndexOfMin(int tensorLength) + { + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + x[expected] = Enumerable.Min(MemoryMarshal.ToEnumerable(x.Memory)) - 1; + Assert.Equal(expected, TensorPrimitives.IndexOfMin(x)); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void IndexOfMin_FirstNaNReturned(int tensorLength) + { + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + x[expected] = float.NaN; + x[tensorLength - 1] = float.NaN; + Assert.Equal(expected, TensorPrimitives.IndexOfMin(x)); + } + } + + [Fact] + public static void IndexOfMin_Negative0LesserThanPositive0() + { + Assert.Equal(0, TensorPrimitives.IndexOfMin([-0f, +0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMin([+0f, -0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMin([+0f, -0f, -0f, -0f, -0f])); + Assert.Equal(0, TensorPrimitives.IndexOfMin([-1, -0f])); + Assert.Equal(0, TensorPrimitives.IndexOfMin([-1, -0f, 1])); + } + + [Fact] + public static void IndexOfMaxMagnitude_ReturnsNegative1OnEmpty() + { + Assert.Equal(-1, TensorPrimitives.IndexOfMaxMagnitude(ReadOnlySpan.Empty)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void IndexOfMaxMagnitude(int tensorLength) + { + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + x[expected] = Enumerable.Max(MemoryMarshal.ToEnumerable(x.Memory), Math.Abs) + 1; + Assert.Equal(expected, TensorPrimitives.IndexOfMaxMagnitude(x)); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void IndexOfMaxMagnitude_FirstNaNReturned(int tensorLength) + { + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + x[expected] = float.NaN; + x[tensorLength - 1] = float.NaN; + Assert.Equal(expected, TensorPrimitives.IndexOfMaxMagnitude(x)); + } + } + + [Fact] + public static void IndexOfMaxMagnitude_Negative0LesserThanPositive0() + { + Assert.Equal(0, TensorPrimitives.IndexOfMaxMagnitude([-0f, -0f, -0f, -0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMaxMagnitude([-0f, +0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMaxMagnitude([-0f, +0f, +0f, +0f])); + Assert.Equal(0, TensorPrimitives.IndexOfMaxMagnitude([+0f, -0f])); + Assert.Equal(0, TensorPrimitives.IndexOfMaxMagnitude([-1, -0f])); + Assert.Equal(2, TensorPrimitives.IndexOfMaxMagnitude([-1, -0f, 1])); + } + + [Fact] + public static void IndexOfMinMagnitude_ReturnsNegative1OnEmpty() + { + Assert.Equal(-1, TensorPrimitives.IndexOfMinMagnitude(ReadOnlySpan.Empty)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void IndexOfMinMagnitude(int tensorLength) + { + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + using BoundedMemory x = CreateTensor(tensorLength); + for (int i = 0; i < x.Length; i++) + { + x[i] = i % 2 == 0 ? 42 : -42; + } + + x[expected] = -41; + + Assert.Equal(expected, TensorPrimitives.IndexOfMinMagnitude(x)); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void IndexOfMinMagnitude_FirstNaNReturned(int tensorLength) + { + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + x[expected] = float.NaN; + x[tensorLength - 1] = float.NaN; + Assert.Equal(expected, TensorPrimitives.IndexOfMinMagnitude(x)); + } + } + + [Fact] + public static void IndexOfMinMagnitude_Negative0LesserThanPositive0() + { + Assert.Equal(0, TensorPrimitives.IndexOfMinMagnitude([-0f, -0f, -0f, -0f])); + Assert.Equal(0, TensorPrimitives.IndexOfMinMagnitude([-0f, +0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMinMagnitude([+0f, -0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMinMagnitude([+0f, -0f, -0f, -0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMinMagnitude([-1, -0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMinMagnitude([-1, -0f, 1])); + } + + [Fact] + public static void Max_ThrowsForEmpty() + { + Assert.Throws(() => TensorPrimitives.Max(ReadOnlySpan.Empty)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Max(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + Assert.Equal(Enumerable.Max(MemoryMarshal.ToEnumerable(x.Memory)), TensorPrimitives.Max(x)); + + float max = float.NegativeInfinity; + foreach (float f in x.Span) + { + max = Math.Max(max, f); + } + Assert.Equal(max, TensorPrimitives.Max(x)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Max_NanReturned(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + x[expected] = float.NaN; + Assert.Equal(float.NaN, TensorPrimitives.Max(x)); + } + } + + [Fact] + public static void Max_Negative0LesserThanPositive0() + { + Assert.Equal(+0f, TensorPrimitives.Max([-0f, +0f])); + Assert.Equal(+0f, TensorPrimitives.Max([+0f, -0f])); + Assert.Equal(-0f, TensorPrimitives.Max([-1, -0f])); + Assert.Equal(1, TensorPrimitives.Max([-1, -0f, 1])); + } + + [Fact] + public static void MaxMagnitude_ThrowsForEmpty() + { + Assert.Throws(() => TensorPrimitives.MaxMagnitude(ReadOnlySpan.Empty)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MaxMagnitude(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + Assert.Equal(Enumerable.Max(MemoryMarshal.ToEnumerable(x.Memory), MathF.Abs), TensorPrimitives.MaxMagnitude(x)); + + float max = 0; + foreach (float f in x.Span) + { + max = Math.Max(max, MathF.Abs(f)); + } + Assert.Equal(max, TensorPrimitives.MaxMagnitude(x)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MaxMagnitude_NanReturned(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + x[expected] = float.NaN; + Assert.Equal(float.NaN, TensorPrimitives.MaxMagnitude(x)); + } + } + + [Fact] + public static void MaxMagnitude_Negative0LesserThanPositive0() + { + Assert.Equal(+0f, TensorPrimitives.MaxMagnitude([-0f, +0f])); + Assert.Equal(+0f, TensorPrimitives.MaxMagnitude([+0f, -0f])); + Assert.Equal(1, TensorPrimitives.MaxMagnitude([-1, -0f])); + Assert.Equal(1, TensorPrimitives.MaxMagnitude([-1, -0f, 1])); + Assert.Equal(0f, TensorPrimitives.MaxMagnitude([-0f, -0f, -0f, -0f, -0f, 0f])); + Assert.Equal(1, TensorPrimitives.MaxMagnitude([-0f, -0f, -0f, -0f, -1, -0f, 0f, 1])); + } + + [Fact] + public static void Min_ThrowsForEmpty() + { + Assert.Throws(() => TensorPrimitives.Min(ReadOnlySpan.Empty)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Min(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + Assert.Equal(Enumerable.Min(MemoryMarshal.ToEnumerable(x.Memory)), TensorPrimitives.Min(x)); + + float min = float.PositiveInfinity; + foreach (float f in x.Span) + { + min = Math.Min(min, f); + } + Assert.Equal(min, TensorPrimitives.Min(x)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Min_NanReturned(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + x[expected] = float.NaN; + Assert.Equal(float.NaN, TensorPrimitives.Min(x)); + } + } + + [Fact] + public static void Min_Negative0LesserThanPositive0() + { + Assert.Equal(-0f, TensorPrimitives.Min([-0f, +0f])); + Assert.Equal(-0f, TensorPrimitives.Min([+0f, -0f])); + Assert.Equal(-1, TensorPrimitives.Min([-1, -0f])); + Assert.Equal(-1, TensorPrimitives.Min([-1, -0f, 1])); + } + + [Fact] + public static void MinMagnitude_ThrowsForEmpty() + { + Assert.Throws(() => TensorPrimitives.MinMagnitude(ReadOnlySpan.Empty)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MinMagnitude(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + Assert.Equal(Enumerable.Min(MemoryMarshal.ToEnumerable(x.Memory), MathF.Abs), TensorPrimitives.MinMagnitude(x)); + + float min = float.PositiveInfinity; + foreach (float f in x.Span) + { + min = Math.Min(min, MathF.Abs(f)); + } + Assert.Equal(min, TensorPrimitives.MinMagnitude(x)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MinMagnitude_NanReturned(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + x[expected] = float.NaN; + Assert.Equal(float.NaN, TensorPrimitives.MinMagnitude(x)); + } + } + + [Fact] + public static void MinMagnitude_Negative0LesserThanPositive0() + { + Assert.Equal(0, TensorPrimitives.MinMagnitude([-0f, +0f])); + Assert.Equal(0, TensorPrimitives.MinMagnitude([+0f, -0f])); + Assert.Equal(0, TensorPrimitives.MinMagnitude([-1, -0f])); + Assert.Equal(0, TensorPrimitives.MinMagnitude([-1, -0f, 1])); + } + + [Fact] + public static void Product_ThrowsForEmpty() + { + Assert.Throws(() => TensorPrimitives.Product(ReadOnlySpan.Empty)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Product(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + float f = x[0]; + for (int i = 1; i < x.Length; i++) + { + f *= x[i]; + } + + Assert.Equal(f, TensorPrimitives.Product(x), Tolerance); + } + + [Fact] + public static void Product_KnownValues() + { + Assert.Equal(1, TensorPrimitives.Product([1])); + Assert.Equal(-2, TensorPrimitives.Product([1, -2])); + Assert.Equal(-6, TensorPrimitives.Product([1, -2, 3])); + Assert.Equal(24, TensorPrimitives.Product([1, -2, 3, -4])); + Assert.Equal(120, TensorPrimitives.Product([1, -2, 3, -4, 5])); + Assert.Equal(-720, TensorPrimitives.Product([1, -2, 3, -4, 5, -6])); + Assert.Equal(0, TensorPrimitives.Product([1, -2, 3, -4, 5, -6, 0])); + Assert.Equal(0, TensorPrimitives.Product([0, 1, -2, 3, -4, 5, -6])); + Assert.Equal(0, TensorPrimitives.Product([1, -2, 3, 0, -4, 5, -6])); + Assert.Equal(float.NaN, TensorPrimitives.Product([1, -2, 3, float.NaN, -4, 5, -6])); + } + + [Fact] + public static void ProductOfDifferences_ThrowsForEmptyAndMismatchedLengths() + { + Assert.Throws(() => TensorPrimitives.ProductOfDifferences(ReadOnlySpan.Empty, ReadOnlySpan.Empty)); + Assert.Throws(() => TensorPrimitives.ProductOfDifferences(ReadOnlySpan.Empty, CreateTensor(1))); + Assert.Throws(() => TensorPrimitives.ProductOfDifferences(CreateTensor(1), ReadOnlySpan.Empty)); + Assert.Throws(() => TensorPrimitives.ProductOfDifferences(CreateTensor(44), CreateTensor(43))); + Assert.Throws(() => TensorPrimitives.ProductOfDifferences(CreateTensor(43), CreateTensor(44))); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void ProductOfDifferences(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + + float f = x[0] - y[0]; + for (int i = 1; i < x.Length; i++) + { + f *= x[i] - y[i]; + } + Assert.Equal(f, TensorPrimitives.ProductOfDifferences(x, y), Tolerance); + } + + [Fact] + public static void ProductOfDifferences_KnownValues() + { + Assert.Equal(0, TensorPrimitives.ProductOfDifferences([0], [0])); + Assert.Equal(0, TensorPrimitives.ProductOfDifferences([1], [1])); + Assert.Equal(1, TensorPrimitives.ProductOfDifferences([1], [0])); + Assert.Equal(-1, TensorPrimitives.ProductOfDifferences([0], [1])); + Assert.Equal(-1, TensorPrimitives.ProductOfDifferences([1, 2, 3, 4, 5], [2, 3, 4, 5, 6])); + Assert.Equal(120, TensorPrimitives.ProductOfDifferences([1, 2, 3, 4, 5], [0, 0, 0, 0, 0])); + Assert.Equal(-120, TensorPrimitives.ProductOfDifferences([0, 0, 0, 0, 0], [1, 2, 3, 4, 5])); + Assert.Equal(float.NaN, TensorPrimitives.ProductOfDifferences([1, 2, float.NaN, 4, 5], [0, 0, 0, 0, 0])); + } + + [Fact] + public static void ProductOfSums_ThrowsForEmptyAndMismatchedLengths() + { + Assert.Throws(() => TensorPrimitives.ProductOfSums(ReadOnlySpan.Empty, ReadOnlySpan.Empty)); + Assert.Throws(() => TensorPrimitives.ProductOfSums(ReadOnlySpan.Empty, CreateTensor(1))); + Assert.Throws(() => TensorPrimitives.ProductOfSums(CreateTensor(1), ReadOnlySpan.Empty)); + Assert.Throws(() => TensorPrimitives.ProductOfSums(CreateTensor(44), CreateTensor(43))); + Assert.Throws(() => TensorPrimitives.ProductOfSums(CreateTensor(43), CreateTensor(44))); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void ProductOfSums(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + + float f = x[0] + y[0]; + for (int i = 1; i < x.Length; i++) + { + f *= x[i] + y[i]; + } + Assert.Equal(f, TensorPrimitives.ProductOfSums(x, y), Tolerance); + } + + [Fact] + public static void ProductOfSums_KnownValues() + { + Assert.Equal(0, TensorPrimitives.ProductOfSums([0], [0])); + Assert.Equal(1, TensorPrimitives.ProductOfSums([0], [1])); + Assert.Equal(1, TensorPrimitives.ProductOfSums([1], [0])); + Assert.Equal(2, TensorPrimitives.ProductOfSums([1], [1])); + Assert.Equal(10395, TensorPrimitives.ProductOfSums([1, 2, 3, 4, 5], [2, 3, 4, 5, 6])); + Assert.Equal(120, TensorPrimitives.ProductOfSums([1, 2, 3, 4, 5], [0, 0, 0, 0, 0])); + Assert.Equal(120, TensorPrimitives.ProductOfSums([0, 0, 0, 0, 0], [1, 2, 3, 4, 5])); + Assert.Equal(float.NaN, TensorPrimitives.ProductOfSums([1, 2, float.NaN, 4, 5], [0, 0, 0, 0, 0])); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Sum(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + Assert.Equal(Enumerable.Sum(MemoryMarshal.ToEnumerable(x.Memory)), TensorPrimitives.Sum(x), Tolerance); + + float sum = 0; + foreach (float f in x.Span) + { + sum += f; + } + Assert.Equal(sum, TensorPrimitives.Sum(x), Tolerance); + } + + [Fact] + public static void Sum_KnownValues() + { + Assert.Equal(0, TensorPrimitives.Sum([0])); + Assert.Equal(1, TensorPrimitives.Sum([0, 1])); + Assert.Equal(6, TensorPrimitives.Sum([1, 2, 3])); + Assert.Equal(0, TensorPrimitives.Sum([-3, 0, 3])); + Assert.Equal(float.NaN, TensorPrimitives.Sum([-3, float.NaN, 3])); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void SumOfSquares(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + Assert.Equal(Enumerable.Sum(MemoryMarshal.ToEnumerable(x.Memory), v => v * v), TensorPrimitives.SumOfSquares(x), Tolerance); + + float sum = 0; + foreach (float f in x.Span) + { + sum += f * f; + } + Assert.Equal(sum, TensorPrimitives.SumOfSquares(x), Tolerance); + } + + [Fact] + public static void SumOfSquares_KnownValues() + { + Assert.Equal(0, TensorPrimitives.SumOfSquares([0])); + Assert.Equal(1, TensorPrimitives.SumOfSquares([0, 1])); + Assert.Equal(14, TensorPrimitives.SumOfSquares([1, 2, 3])); + Assert.Equal(18, TensorPrimitives.SumOfSquares([-3, 0, 3])); + Assert.Equal(float.NaN, TensorPrimitives.SumOfSquares([-3, float.NaN, 3])); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void SumOfMagnitudes(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + Assert.Equal(Enumerable.Sum(MemoryMarshal.ToEnumerable(x.Memory), MathF.Abs), TensorPrimitives.SumOfMagnitudes(x), Tolerance); + + float sum = 0; + foreach (float f in x.Span) + { + sum += MathF.Abs(f); + } + Assert.Equal(sum, TensorPrimitives.SumOfMagnitudes(x), Tolerance); + } + + [Fact] + public static void SumOfMagnitudes_KnownValues() + { + Assert.Equal(0, TensorPrimitives.SumOfMagnitudes([0])); + Assert.Equal(1, TensorPrimitives.SumOfMagnitudes([0, 1])); + Assert.Equal(6, TensorPrimitives.SumOfMagnitudes([1, 2, 3])); + Assert.Equal(6, TensorPrimitives.SumOfMagnitudes([-3, 0, 3])); + Assert.Equal(float.NaN, TensorPrimitives.SumOfMagnitudes([-3, float.NaN, 3])); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.netcore.cs b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.netcore.cs new file mode 100644 index 00000000000000..113f26048d352c --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.netcore.cs @@ -0,0 +1,91 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers; +using Xunit; + +namespace System.Numerics.Tensors.Tests +{ + public static partial class TensorPrimitivesTests + { + [Theory] + [InlineData(0)] + [MemberData(nameof(TensorLengths))] + public static void ConvertToHalf(int tensorLength) + { + using BoundedMemory source = CreateAndFillTensor(tensorLength); + foreach (int destLength in new[] { source.Length, source.Length + 1 }) + { + Half[] destination = new Half[destLength]; + + TensorPrimitives.ConvertToHalf(source, destination); + + for (int i = 0; i < source.Length; i++) + { + Assert.Equal((Half)source[i], destination[i]); + } + + if (destination.Length > source.Length) + { + for (int i = source.Length; i < destination.Length; i++) + { + Assert.Equal(Half.Zero, destination[i]); + } + } + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void ConvertToHalf_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory source = CreateAndFillTensor(tensorLength); + Half[] destination = new Half[source.Length - 1]; + + AssertExtensions.Throws("destination", () => TensorPrimitives.ConvertToHalf(source, destination)); + } + + [Theory] + [InlineData(0)] + [MemberData(nameof(TensorLengths))] + public static void ConvertToSingle(int tensorLength) + { + Half[] source = new Half[tensorLength]; + for (int i = 0; i < source.Length; i++) + { + source[i] = (Half)s_random.NextSingle(); + } + + foreach (int destLength in new[] { source.Length, source.Length + 1 }) + { + using BoundedMemory destination = CreateTensor(destLength); + destination.Span.Fill(0f); + + TensorPrimitives.ConvertToSingle(source, destination); + + for (int i = 0; i < source.Length; i++) + { + Assert.Equal((float)source[i], destination[i]); + } + + if (destination.Length > source.Length) + { + for (int i = source.Length; i < destination.Length; i++) + { + Assert.Equal(0f, destination[i]); + } + } + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void ConvertToSingle_ThrowsForTooShortDestination(int tensorLength) + { + Half[] source = new Half[tensorLength]; + using BoundedMemory destination = CreateTensor(source.Length - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.ConvertToSingle(source, destination)); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorTemplate.ttinclude b/src/libraries/System.Numerics.Tensors/tests/TensorTemplate.ttinclude deleted file mode 100644 index 9448791a5db6c4..00000000000000 --- a/src/libraries/System.Numerics.Tensors/tests/TensorTemplate.ttinclude +++ /dev/null @@ -1,328 +0,0 @@ -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -<#+ - public class TypeConfiguration - { - public TypeConfiguration(string typeName, string classPrefix = null, string oneLiteral = "1", string zeroLiteral = "0", bool supportsNumeric = true, bool supportsBitwise = true, IEnumerable unsupportedMethods = null) - { - TypeName = typeName; - ClassPrefix = classPrefix ?? char.ToUpper(typeName[0]) + typeName.Substring(1); - OneLiteral = oneLiteral; - ZeroLiteral = zeroLiteral; - SupportsNumeric = supportsNumeric; - SupportsBitwise = supportsBitwise; - UnsupportedMethods = new HashSet(unsupportedMethods ?? Enumerable.Empty()); - } - - public string TypeName { get; } - public string ClassPrefix { get; } - public string OneLiteral { get; } - public string ZeroLiteral { get; } - - public bool SupportsNumeric { get; } - public bool SupportsBitwise { get; } - public ISet UnsupportedMethods { get; } - } - - public string GenerateIfStatementHeader(TypeConfiguration type) - { - string keyword = (type == typeConfiguration[0]) ? "if" : "else if"; - return $"{keyword} (typeof(T) == typeof({type.TypeName}))"; - } - - public TypeConfiguration[] typeConfiguration = new [] - { - new TypeConfiguration("bool", oneLiteral:"true", zeroLiteral:"false", supportsNumeric: false, unsupportedMethods: new[] {"LeftShift", "RightShift"}), - new TypeConfiguration("byte"), - new TypeConfiguration("char", oneLiteral:"(char)1", zeroLiteral:"(char)0"), - new TypeConfiguration("decimal", supportsBitwise: false), - new TypeConfiguration("double", oneLiteral:"1.0", supportsBitwise: false), - new TypeConfiguration("float", oneLiteral:"1.0f", supportsBitwise: false), - new TypeConfiguration("int"), - new TypeConfiguration("long"), - new TypeConfiguration("sbyte", classPrefix:"SByte"), - new TypeConfiguration("short"), - new TypeConfiguration("uint", classPrefix:"UInt", unsupportedMethods: new[] {"UnaryMinus"}), - new TypeConfiguration("ulong", classPrefix:"ULong", unsupportedMethods: new[] {"UnaryMinus"}), - new TypeConfiguration("ushort", classPrefix:"UShort", unsupportedMethods: new[] {"UnaryMinus"}) - }; - - public enum MethodType - { - Unary, - UnaryInPlace, - BinaryScalar, - BinaryInt, - Binary, - Comparison, - Contraction - } - - public class MethodConfiguration - { - public MethodConfiguration(string methodName, MethodType methodType, string op = null, bool isNumeric = false, bool isBitwise = false) - { - MethodName = methodName; - MethodType = methodType; - Operator = op; - IsNumeric = isNumeric; - IsBitwise = isBitwise; - } - - public string ResultName => "result"; - - public string Op1Name - { - get - { - switch (MethodType) - { - case MethodType.Unary: - case MethodType.UnaryInPlace: - case MethodType.BinaryScalar: - case MethodType.BinaryInt: - return "tensor"; - case MethodType.Binary: - case MethodType.Comparison: - case MethodType.Contraction: - return "left"; - default: - throw new ArgumentException(); - }; - } - } - - public string Op2Name - { - get - { - switch (MethodType) - { - case MethodType.BinaryScalar: - return "scalar"; - case MethodType.BinaryInt: - return "value"; - case MethodType.Binary: - case MethodType.Comparison: - case MethodType.Contraction: - return "right"; - case MethodType.Unary: - case MethodType.UnaryInPlace: - default: - throw new ArgumentException(); - }; - } - } - - public string MethodName { get; } - public MethodType MethodType { get; } - public string Operator { get; } - - public string GetGenericMethodSignature(string tensorType, string genericType) - { - var resultType = GetResultType(tensorType, genericType); - var arguments = GetMethodArguments(tensorType, genericType); - - return $"{resultType} {MethodName}<{genericType}>({arguments})"; - } - - public string GetGenericResultMethodSignature(string tensorType, string genericType) - { - var resultType = GetResultType(tensorType, genericType); - var arguments = GetMethodArguments(tensorType, genericType); - - return $"void {MethodName}<{genericType}>({arguments}, {resultType} {ResultName})"; - } - - public string GetResultMethodSignature(string tensorType, string genericType) - { - var resultType = GetResultType(tensorType, genericType); - var arguments = GetMethodArguments(tensorType, genericType); - - return $"void {MethodName}({arguments}, {resultType} {ResultName})"; - } - - public string GetMethodArguments(string tensorType, string genericType) - { - switch (MethodType) - { - case MethodType.Unary: - case MethodType.UnaryInPlace: - return $"{tensorType}<{genericType}> {Op1Name}"; - case MethodType.BinaryScalar: - return $"{tensorType}<{genericType}> {Op1Name}, {genericType} {Op2Name}"; - case MethodType.BinaryInt: - return $"{tensorType}<{genericType}> {Op1Name}, int {Op2Name}"; - case MethodType.Binary: - case MethodType.Comparison: - return $"{tensorType}<{genericType}> {Op1Name}, {tensorType}<{genericType}> {Op2Name}"; - case MethodType.Contraction: - return $"{tensorType}<{genericType}> {Op1Name}, {tensorType}<{genericType}> {Op2Name}, int[] leftAxes, int[] rightAxes"; - default: - throw new ArgumentException(); - } - } - - public string GetCallArguments() - { - switch (MethodType) - { - case MethodType.Unary: - case MethodType.UnaryInPlace: - return $"{Op1Name}"; - case MethodType.BinaryScalar: - case MethodType.BinaryInt: - case MethodType.Binary: - case MethodType.Comparison: - return $"{Op1Name}, {Op2Name}"; - case MethodType.Contraction: - return "left, right, leftAxes, rightAxes"; - default: - throw new ArgumentException(); - } - } - - public string GetValidationMethod(bool includeResult) - { - var suffix = includeResult ? ", result" : ""; - switch (MethodType) - { - case MethodType.Unary: - case MethodType.UnaryInPlace: - case MethodType.BinaryScalar: - case MethodType.BinaryInt: - return $"ValidateArgs({Op1Name}{suffix});"; - case MethodType.Binary: - case MethodType.Comparison: - return $"ValidateBinaryArgs({Op1Name}, {Op2Name}{suffix});"; - case MethodType.Contraction: - return $"var resultDimensions = ValidateContractArgs({Op1Name}, {Op2Name}, leftAxes, rightAxes{suffix});"; - default: - throw new ArgumentException(); - } - } - - public string GetResultType(string tensorType, string typeName) - { - switch (MethodType) - { - case MethodType.Unary: - case MethodType.UnaryInPlace: - case MethodType.BinaryScalar: - case MethodType.BinaryInt: - case MethodType.Binary: - case MethodType.Contraction: - return $"{tensorType}<{typeName}>"; - case MethodType.Comparison: - return $"{tensorType}"; - default: - throw new ArgumentException(); - } - } - - public string GetLinearOperationCheck() - { - switch (MethodType) - { - case MethodType.Unary: - case MethodType.BinaryScalar: - case MethodType.BinaryInt: - return $"({ResultName}.IsReversedStride == {Op1Name}.IsReversedStride)"; - case MethodType.Binary: - case MethodType.Comparison: - return $"(({ResultName}.IsReversedStride == {Op1Name}.IsReversedStride) && ({ResultName}.IsReversedStride == {Op2Name}.IsReversedStride))"; - case MethodType.UnaryInPlace: - default: - throw new ArgumentException(); - } - } - - - public string GetElementOperation(string typeName, string access) - { - return GetElementOperation(typeName, access, access, access); - } - - public string GetElementOperation(string typeName, string resultAccess, string leftAccess, string rightAccess) - { - switch (MethodType) - { - case MethodType.Unary: - return $"{ResultName}{resultAccess} = ({typeName}){Operator}{Op1Name}{leftAccess}"; - case MethodType.UnaryInPlace: - return $"{ResultName}{resultAccess}{Operator}"; - case MethodType.BinaryScalar: - case MethodType.BinaryInt: - return $"{ResultName}{resultAccess} = ({typeName})({Op1Name}{leftAccess} {Operator} {Op2Name})"; - case MethodType.Binary: - return $"{ResultName}{resultAccess} = ({typeName})({Op1Name}{leftAccess} {Operator} {Op2Name}{rightAccess})"; - case MethodType.Comparison: - return $"{ResultName}{resultAccess} = {Op1Name}{leftAccess} {Operator} {Op2Name}{rightAccess}"; - default: - throw new ArgumentException(); - - } - } - - public string InitializeResult(string typeName) - { - switch (MethodType) - { - case MethodType.UnaryInPlace: - return $"{Op1Name}.Clone()"; - case MethodType.Unary: - case MethodType.BinaryScalar: - case MethodType.BinaryInt: - case MethodType.Binary: - return $"{Op1Name}.CloneEmpty()"; - case MethodType.Comparison: - return $"{Op1Name}.CloneEmpty()"; - case MethodType.Contraction: - return $"{Op1Name}.CloneEmpty(resultDimensions)"; - default: - throw new ArgumentException(); - } - } - - public bool IsNumeric { get; } - public bool IsBitwise { get; } - } - - - public MethodConfiguration[] methodConfiguration = new [] - { - new MethodConfiguration("Add", MethodType.Binary, "+", isNumeric:true), - new MethodConfiguration("Add", MethodType.BinaryScalar, "+", isNumeric:true), - new MethodConfiguration("UnaryPlus", MethodType.Unary, "+", isNumeric:true), - new MethodConfiguration("Subtract", MethodType.Binary, "-", isNumeric:true), - new MethodConfiguration("Subtract", MethodType.BinaryScalar, "-", isNumeric:true), - new MethodConfiguration("UnaryMinus", MethodType.Unary, "-", isNumeric:true), - new MethodConfiguration("Increment", MethodType.UnaryInPlace, "++", isNumeric:true), - new MethodConfiguration("Decrement", MethodType.UnaryInPlace, "--", isNumeric:true), - new MethodConfiguration("Multiply", MethodType.Binary, "*", isNumeric:true), // element-wise product, not matrix product - new MethodConfiguration("Multiply", MethodType.BinaryScalar, "*", isNumeric:true), - new MethodConfiguration("Divide", MethodType.Binary, "/", isNumeric:true), - new MethodConfiguration("Divide", MethodType.BinaryScalar, "/", isNumeric:true), - new MethodConfiguration("Modulo", MethodType.Binary, "%", isNumeric:true), - new MethodConfiguration("Modulo", MethodType.BinaryScalar, "%", isNumeric:true), - new MethodConfiguration("And", MethodType.Binary, "&", isBitwise: true), - new MethodConfiguration("And", MethodType.BinaryScalar, "&", isBitwise: true), - new MethodConfiguration("Or", MethodType.Binary, "|", isBitwise: true), - new MethodConfiguration("Or", MethodType.BinaryScalar, "|", isBitwise: true), - new MethodConfiguration("Xor", MethodType.Binary, "^", isBitwise: true), - new MethodConfiguration("Xor", MethodType.BinaryScalar, "^", isBitwise: true), - new MethodConfiguration("LeftShift", MethodType.BinaryInt, "<<", isBitwise: true), - new MethodConfiguration("RightShift", MethodType.BinaryInt, ">>", isBitwise: true), - - // Note all of these are element-wise operations not testing the operation on the entire Tensor - new MethodConfiguration("Equals", MethodType.Comparison, "=="), - new MethodConfiguration("NotEquals", MethodType.Comparison, "!="), - new MethodConfiguration("GreaterThanOrEqual", MethodType.Comparison, ">=", isNumeric:true), - new MethodConfiguration("LessThanOrEqual", MethodType.Comparison, "<=", isNumeric:true), - new MethodConfiguration("GreaterThan", MethodType.Comparison, ">", isNumeric:true), - new MethodConfiguration("LessThan", MethodType.Comparison, "<", isNumeric:true), - - new MethodConfiguration("Contract", MethodType.Contraction, isNumeric:true), - }.OrderBy(m => m.MethodName).ToArray(); -#> diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs deleted file mode 100644 index 27c7ba75e4e259..00000000000000 --- a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs +++ /dev/null @@ -1,2486 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using Xunit; - -namespace System.Numerics.Tensors.Tests -{ - public class TensorTests : TensorTestsBase - { - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void ConstructTensorFromArrayRank1(TensorConstructor tensorConstructor) - { - var tensor = tensorConstructor.CreateFromArray(new[] { 0, 1, 2 }); - - Assert.Equal(tensorConstructor.IsReversedStride, tensor.IsReversedStride); - Assert.Equal(0, tensor[0]); - Assert.Equal(1, tensor[1]); - Assert.Equal(2, tensor[2]); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void ConstructTensorFromArrayRank2(TensorConstructor tensorConstructor) - { - var tensor = tensorConstructor.CreateFromArray(new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - Assert.Equal(tensorConstructor.IsReversedStride, tensor.IsReversedStride); - Assert.Equal(0, tensor[0, 0]); - Assert.Equal(1, tensor[0, 1]); - Assert.Equal(2, tensor[0, 2]); - Assert.Equal(3, tensor[1, 0]); - Assert.Equal(4, tensor[1, 1]); - Assert.Equal(5, tensor[1, 2]); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void ConstructTensorFromArrayRank3(TensorConstructor tensorConstructor) - { - var tensor = tensorConstructor.CreateFromArray(new[, ,] - { - { - {0, 1, 2}, - {3, 4, 5} - }, - { - {6, 7 ,8 }, - {9, 10 ,11 }, - }, - { - {12, 13 ,14 }, - {15, 16 ,17 }, - }, - { - {18, 19 ,20 }, - {21, 22 ,23 }, - } - }); - - Assert.Equal(tensorConstructor.IsReversedStride, tensor.IsReversedStride); - - Assert.Equal(0, tensor[0, 0, 0]); - Assert.Equal(1, tensor[0, 0, 1]); - Assert.Equal(2, tensor[0, 0, 2]); - Assert.Equal(3, tensor[0, 1, 0]); - Assert.Equal(4, tensor[0, 1, 1]); - Assert.Equal(5, tensor[0, 1, 2]); - - Assert.Equal(6, tensor[1, 0, 0]); - Assert.Equal(7, tensor[1, 0, 1]); - Assert.Equal(8, tensor[1, 0, 2]); - Assert.Equal(9, tensor[1, 1, 0]); - Assert.Equal(10, tensor[1, 1, 1]); - Assert.Equal(11, tensor[1, 1, 2]); - - Assert.Equal(12, tensor[2, 0, 0]); - Assert.Equal(13, tensor[2, 0, 1]); - Assert.Equal(14, tensor[2, 0, 2]); - Assert.Equal(15, tensor[2, 1, 0]); - Assert.Equal(16, tensor[2, 1, 1]); - Assert.Equal(17, tensor[2, 1, 2]); - - Assert.Equal(18, tensor[3, 0, 0]); - Assert.Equal(19, tensor[3, 0, 1]); - Assert.Equal(20, tensor[3, 0, 2]); - Assert.Equal(21, tensor[3, 1, 0]); - Assert.Equal(22, tensor[3, 1, 1]); - Assert.Equal(23, tensor[3, 1, 2]); - } - - [Fact] - public void ConstructDenseTensorFromPointer() - { - using (var nativeMemory = NativeMemoryFromArray(Enumerable.Range(0, 24).ToArray())) - { - var dimensions = new[] { 4, 2, 3 }; - var tensor = new DenseTensor(nativeMemory.Memory, dimensions, false); - - Assert.Equal(0, tensor[0, 0, 0]); - Assert.Equal(1, tensor[0, 0, 1]); - Assert.Equal(2, tensor[0, 0, 2]); - Assert.Equal(3, tensor[0, 1, 0]); - Assert.Equal(4, tensor[0, 1, 1]); - Assert.Equal(5, tensor[0, 1, 2]); - - Assert.Equal(6, tensor[1, 0, 0]); - Assert.Equal(7, tensor[1, 0, 1]); - Assert.Equal(8, tensor[1, 0, 2]); - Assert.Equal(9, tensor[1, 1, 0]); - Assert.Equal(10, tensor[1, 1, 1]); - Assert.Equal(11, tensor[1, 1, 2]); - - Assert.Equal(12, tensor[2, 0, 0]); - Assert.Equal(13, tensor[2, 0, 1]); - Assert.Equal(14, tensor[2, 0, 2]); - Assert.Equal(15, tensor[2, 1, 0]); - Assert.Equal(16, tensor[2, 1, 1]); - Assert.Equal(17, tensor[2, 1, 2]); - - Assert.Equal(18, tensor[3, 0, 0]); - Assert.Equal(19, tensor[3, 0, 1]); - Assert.Equal(20, tensor[3, 0, 2]); - Assert.Equal(21, tensor[3, 1, 0]); - Assert.Equal(22, tensor[3, 1, 1]); - Assert.Equal(23, tensor[3, 1, 2]); - } - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void ConstructSparseTensor(TensorConstructor tensorConstructor) - { - var tensor = tensorConstructor.CreateFromArray(new[,] - { - {0, 0, 0, 0}, - {5, 8, 0, 0}, - {0, 0, 3, 0}, - {0, 6, 0, 0} - }); - - Assert.Equal(tensorConstructor.IsReversedStride, tensor.IsReversedStride); - - - Assert.Equal(0, tensor[0, 0]); - Assert.Equal(0, tensor[0, 1]); - Assert.Equal(0, tensor[0, 2]); - Assert.Equal(0, tensor[0, 3]); - - - Assert.Equal(5, tensor[1, 0]); - Assert.Equal(8, tensor[1, 1]); - Assert.Equal(0, tensor[1, 2]); - Assert.Equal(0, tensor[1, 3]); - - - Assert.Equal(0, tensor[2, 0]); - Assert.Equal(0, tensor[2, 1]); - Assert.Equal(3, tensor[2, 2]); - Assert.Equal(0, tensor[2, 3]); - - - Assert.Equal(0, tensor[3, 0]); - Assert.Equal(6, tensor[3, 1]); - Assert.Equal(0, tensor[3, 2]); - Assert.Equal(0, tensor[3, 3]); - - if (tensorConstructor.TensorType == TensorType.CompressedSparse) - { - var compressedSparseTensor = (CompressedSparseTensor)tensor; - - Assert.Equal(4, compressedSparseTensor.NonZeroCount); - - int[] expectedValues, expectedCompressedCounts, expectedIndices; - - if (compressedSparseTensor.IsReversedStride) - { - // csc - expectedValues = new[] { 5, 8, 6, 3 }; - expectedCompressedCounts = new[] { 0, 1, 3, 4, 4 }; - expectedIndices = new[] { 1, 1, 3, 2 }; - } - else - { - // csr - expectedValues = new[] { 5, 8, 3, 6 }; - expectedCompressedCounts = new[] { 0, 0, 2, 3, 4 }; - expectedIndices = new[] { 0, 1, 2, 1 }; - } - Assert.Equal(expectedValues, compressedSparseTensor.Values.Slice(0, compressedSparseTensor.NonZeroCount).ToArray()); - Assert.Equal(expectedCompressedCounts, compressedSparseTensor.CompressedCounts.ToArray()); - Assert.Equal(expectedIndices, compressedSparseTensor.Indices.Slice(0, compressedSparseTensor.NonZeroCount).ToArray()); - } - } - - [Theory()] - [InlineData(false)] - [InlineData(true)] - public void ConstructCompressedSparseTensorFromPointers(bool isReversedStride) - { - int[] values, compressedCounts, indices; - if (isReversedStride) - { - // csc - values = new[] { 5, 8, 6, 3 }; - compressedCounts = new[] { 0, 1, 3, 4, 4 }; - indices = new[] { 1, 1, 3, 2 }; - } - else - { - // csr - values = new[] { 5, 8, 3, 6 }; - compressedCounts = new[] { 0, 0, 2, 3, 4 }; - indices = new[] { 0, 1, 2, 1 }; - } - int[] dimensions = new[] { 4, 4 }; - - using (var valuesMemory = NativeMemoryFromArray(values)) - using (var compressedCountsMemory = NativeMemoryFromArray(compressedCounts)) - using (var indicesMemory = NativeMemoryFromArray(indices)) - { - var tensor = new CompressedSparseTensor(valuesMemory.Memory, - compressedCountsMemory.Memory, - indicesMemory.Memory, - values.Length, - dimensions, - isReversedStride); - - Assert.Equal(0, tensor[0, 0]); - Assert.Equal(0, tensor[0, 1]); - Assert.Equal(0, tensor[0, 2]); - Assert.Equal(0, tensor[0, 3]); - - - Assert.Equal(5, tensor[1, 0]); - Assert.Equal(8, tensor[1, 1]); - Assert.Equal(0, tensor[1, 2]); - Assert.Equal(0, tensor[1, 3]); - - - Assert.Equal(0, tensor[2, 0]); - Assert.Equal(0, tensor[2, 1]); - Assert.Equal(3, tensor[2, 2]); - Assert.Equal(0, tensor[2, 3]); - - - Assert.Equal(0, tensor[3, 0]); - Assert.Equal(6, tensor[3, 1]); - Assert.Equal(0, tensor[3, 2]); - Assert.Equal(0, tensor[3, 3]); - } - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void ConstructFromDimensions(TensorConstructor tensorConstructor) - { - var tensor = tensorConstructor.CreateFromDimensions(new[] { 2, 3, 4 }); - Assert.Equal(3, tensor.Rank); - Assert.Equal(3, tensor.Dimensions.Length); - Assert.Equal(2, tensor.Dimensions[0]); - Assert.Equal(3, tensor.Dimensions[1]); - Assert.Equal(4, tensor.Dimensions[2]); - Assert.Equal(24, tensor.Length); - Assert.Equal(tensorConstructor.IsReversedStride, tensor.IsReversedStride); - - //Assert.Throws("dimensions", () => tensorConstructor.CreateFromDimensions(dimensions: null)); - Assert.Throws("dimensions", () => tensorConstructor.CreateFromDimensions(dimensions: new int[0])); - - Assert.Throws("dimensions", () => tensorConstructor.CreateFromDimensions(dimensions: new[] { 1, 0 })); - Assert.Throws("dimensions", () => tensorConstructor.CreateFromDimensions(dimensions: new[] { 1, -1 })); - - // ensure dimensions are immutable - var dimensions = new[] { 1, 2, 3 }; - tensor = tensorConstructor.CreateFromDimensions(dimensions: dimensions); - dimensions[0] = dimensions[1] = dimensions[2] = 0; - Assert.Equal(1, tensor.Dimensions[0]); - Assert.Equal(2, tensor.Dimensions[1]); - Assert.Equal(3, tensor.Dimensions[2]); - } - - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNonZeroLowerBoundArraySupported))] - [MemberData(nameof(GetSingleTensorConstructors))] - public void ConstructTensorFromArrayRank3WithLowerBounds(TensorConstructor tensorConstructor) - { - var dimensions = new[] { 2, 3, 4 }; - var lowerBounds = new[] { 0, 5, 200 }; - var arrayWithLowerBounds = Array.CreateInstance(typeof(int), dimensions, lowerBounds); - - int value = 0; - for (int x = lowerBounds[0]; x < lowerBounds[0] + dimensions[0]; x++) - { - for (int y = lowerBounds[1]; y < lowerBounds[1] + dimensions[1]; y++) - { - for (int z = lowerBounds[2]; z < lowerBounds[2] + dimensions[2]; z++) - { - arrayWithLowerBounds.SetValue(value++, x, y, z); - } - } - } - - var tensor = tensorConstructor.CreateFromArray(arrayWithLowerBounds); - - var expected = tensorConstructor.CreateFromArray(new[, ,] - { - { - { 0, 1, 2, 3 }, - { 4, 5, 6, 7 }, - { 8, 9, 10, 11 } - }, - { - { 12, 13, 14, 15 }, - { 16, 17, 18, 19 }, - { 20, 21, 22, 23 } - } - } - ); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(expected, tensor)); - Assert.Equal(tensorConstructor.IsReversedStride, tensor.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetDualTensorConstructors))] - public void StructurallyEqualTensor(TensorConstructor leftConstructor, TensorConstructor rightConstructor) - { - var arr = new[, ,] - { - { - {0, 1, 2}, - {3, 4, 5} - }, - { - {6, 7 ,8 }, - {9, 10 ,11 }, - }, - { - {12, 13 ,14 }, - {15, 16 ,17 }, - }, - { - {18, 19 ,20 }, - {21, 22 ,23 }, - } - }; - var tensor = leftConstructor.CreateFromArray(arr); - var tensor2 = rightConstructor.CreateFromArray(arr); - - Assert.Equal(0, StructuralComparisons.StructuralComparer.Compare(tensor, tensor2)); - Assert.Equal(0, StructuralComparisons.StructuralComparer.Compare(tensor2, tensor)); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tensor, tensor2)); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tensor2, tensor)); - // Issue: should Tensors with different layout be structurally equal? - if (leftConstructor.IsReversedStride == leftConstructor.IsReversedStride) - { - Assert.Equal(StructuralComparisons.StructuralEqualityComparer.GetHashCode(tensor), StructuralComparisons.StructuralEqualityComparer.GetHashCode(tensor2)); - } - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void StructurallyEqualArray(TensorConstructor tensorConstructor) - { - var arr = new[, ,] - { - { - {0, 1, 2}, - {3, 4, 5} - }, - { - {6, 7 ,8 }, - {9, 10 ,11 }, - }, - { - {12, 13 ,14 }, - {15, 16 ,17 }, - }, - { - {18, 19 ,20 }, - {21, 22 ,23 }, - } - }; - var tensor = tensorConstructor.CreateFromArray(arr); - - Assert.Equal(0, StructuralComparisons.StructuralComparer.Compare(tensor, arr)); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tensor, arr)); - - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void GetDiagonalSquare(TensorConstructor tensorConstructor) - { - var arr = new[,] - { - { 1, 2, 4 }, - { 8, 3, 9 }, - { 1, 7, 5 }, - }; - - var tensor = tensorConstructor.CreateFromArray(arr); - var diag = tensor.GetDiagonal(); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(diag, new[] { 1, 3, 5 })); - diag = tensor.GetDiagonal(1); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(diag, new[] { 2, 9 })); - diag = tensor.GetDiagonal(2); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(diag, new[] { 4 })); - Assert.Throws("offset", () => tensor.GetDiagonal(3)); - - diag = tensor.GetDiagonal(-1); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(diag, new[] { 8, 7 })); - diag = tensor.GetDiagonal(-2); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(diag, new[] { 1 })); - Assert.Throws("offset", () => tensor.GetDiagonal(-3)); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void GetDiagonalRectangle(TensorConstructor tensorConstructor) - { - var arr = new[,] - { - { 1, 2, 4, 3, 7 }, - { 8, 3, 9, 2, 6 }, - { 1, 7, 5, 2, 9 } - }; - - var tensor = tensorConstructor.CreateFromArray(arr); - var diag = tensor.GetDiagonal(); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(diag, new[] { 1, 3, 5 })); - diag = tensor.GetDiagonal(1); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(diag, new[] { 2, 9, 2 })); - diag = tensor.GetDiagonal(2); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(diag, new[] { 4, 2, 9 })); - diag = tensor.GetDiagonal(3); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(diag, new[] { 3, 6 })); - diag = tensor.GetDiagonal(4); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(diag, new[] { 7 })); - Assert.Throws("offset", () => tensor.GetDiagonal(5)); - - diag = tensor.GetDiagonal(-1); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(diag, new[] { 8, 7 })); - diag = tensor.GetDiagonal(-2); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(diag, new[] { 1 })); - Assert.Throws("offset", () => tensor.GetDiagonal(-3)); - Assert.Throws("offset", () => tensor.GetDiagonal(-4)); - Assert.Throws("offset", () => tensor.GetDiagonal(-5)); - } - - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void GetDiagonalCube(TensorConstructor tensorConstructor) - { - var arr = new[, ,] - { - { - { 1, 2, 4 }, - { 8, 3, 9 }, - { 1, 7, 5 }, - }, - { - { 4, 5, 7 }, - { 1, 6, 2 }, - { 3, 0, 8 }, - }, - { - { 5, 6, 1 }, - { 2, 2, 3 }, - { 4, 9, 4 }, - }, - - }; - - var tensor = tensorConstructor.CreateFromArray(arr); - var diag = tensor.GetDiagonal(); - var expected = new[,] - { - { 1, 2, 4 }, - { 1, 6, 2 }, - { 4, 9, 4 } - }; - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(diag, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, diag.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void GetTriangleSquare(TensorConstructor tensorConstructor) - { - var arr = new[,] - { - { 1, 2, 4 }, - { 8, 3, 9 }, - { 1, 7, 5 }, - }; - - var tensor = tensorConstructor.CreateFromArray(arr); - var tri = tensor.GetTriangle(0); - Assert.Equal(tensorConstructor.IsReversedStride, tri.IsReversedStride); - - var expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 0, 0 }, - { 8, 3, 0 }, - { 1, 7, 5 }, - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetTriangle(1); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 0 }, - { 8, 3, 9 }, - { 1, 7, 5 }, - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetTriangle(2); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 4 }, - { 8, 3, 9 }, - { 1, 7, 5 }, - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - tri = tensor.GetTriangle(3); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - tri = tensor.GetTriangle(200); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - tri = tensor.GetTriangle(-1); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 0, 0 }, - { 8, 0, 0 }, - { 1, 7, 0 }, - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetTriangle(-2); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 0, 0 }, - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - }); - tri = tensor.GetTriangle(-3); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - // same as -3, should it be an exception? - tri = tensor.GetTriangle(-4); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetTriangle(-300); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void GetTriangleRectangle(TensorConstructor tensorConstructor) - { - var arr = new[,] - { - { 1, 2, 4, 3, 7 }, - { 8, 3, 9, 2, 6 }, - { 1, 7, 5, 2, 9 } - }; - - var tensor = tensorConstructor.CreateFromArray(arr); - var tri = tensor.GetTriangle(0); - var expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 0, 0, 0, 0 }, - { 8, 3, 0, 0, 0 }, - { 1, 7, 5, 0, 0 } - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, tri.IsReversedStride); - - tri = tensor.GetTriangle(1); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 0, 0, 0 }, - { 8, 3, 9, 0, 0 }, - { 1, 7, 5, 2, 0 } - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetTriangle(2); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 4, 0, 0 }, - { 8, 3, 9, 2, 0 }, - { 1, 7, 5, 2, 9 } - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetTriangle(3); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 4, 3, 0 }, - { 8, 3, 9, 2, 6 }, - { 1, 7, 5, 2, 9 } - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - tri = tensor.GetTriangle(4); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 4, 3, 7 }, - { 8, 3, 9, 2, 6 }, - { 1, 7, 5, 2, 9 } - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - // same as 4, should it be an exception? - tri = tensor.GetTriangle(5); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetTriangle(1000); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - tri = tensor.GetTriangle(-1); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 0, 0, 0, 0 }, - { 8, 0, 0, 0, 0 }, - { 1, 7, 0, 0, 0 } - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 0 } - }); - tri = tensor.GetTriangle(-2); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 } - }); - tri = tensor.GetTriangle(-3); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - tri = tensor.GetTriangle(-4); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetTriangle(-5); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetTriangle(-100); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void GetTriangleCube(TensorConstructor tensorConstructor) - { - var arr = new[, ,] - { - { - { 1, 2, 4 }, - { 8, 3, 9 }, - { 1, 7, 5 }, - }, - { - { 4, 5, 7 }, - { 1, 6, 2 }, - { 3, 0, 8 }, - }, - { - { 5, 6, 1 }, - { 2, 2, 3 }, - { 4, 9, 4 }, - }, - - }; - - var tensor = tensorConstructor.CreateFromArray(arr); - var tri = tensor.GetTriangle(0); - var expected = tensorConstructor.CreateFromArray(new[, ,] - { - { - { 1, 2, 4 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - }, - { - { 4, 5, 7 }, - { 1, 6, 2 }, - { 0, 0, 0 }, - }, - { - { 5, 6, 1 }, - { 2, 2, 3 }, - { 4, 9, 4 }, - }, - - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, tri.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void GetUpperTriangleSquare(TensorConstructor tensorConstructor) - { - var arr = new[,] - { - { 1, 2, 4 }, - { 8, 3, 9 }, - { 1, 7, 5 }, - }; - - var tensor = tensorConstructor.CreateFromArray(arr); - var tri = tensor.GetUpperTriangle(0); - - var expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 4 }, - { 0, 3, 9 }, - { 0, 0, 5 }, - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, tri.IsReversedStride); - - tri = tensor.GetUpperTriangle(1); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 2, 4 }, - { 0, 0, 9 }, - { 0, 0, 0 }, - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetUpperTriangle(2); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 0, 4 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - tri = tensor.GetUpperTriangle(3); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - tri = tensor.GetUpperTriangle(4); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetUpperTriangle(42); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - tri = tensor.GetUpperTriangle(-1); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 4 }, - { 8, 3, 9 }, - { 0, 7, 5 }, - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetUpperTriangle(-2); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 4 }, - { 8, 3, 9 }, - { 1, 7, 5 }, - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - tri = tensor.GetUpperTriangle(-3); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetUpperTriangle(-300); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void GetUpperTriangleRectangle(TensorConstructor tensorConstructor) - { - var arr = new[,] - { - { 1, 2, 4, 3, 7 }, - { 8, 3, 9, 2, 6 }, - { 1, 7, 5, 2, 9 } - }; - - var tensor = tensorConstructor.CreateFromArray(arr); - var tri = tensor.GetUpperTriangle(0); - var expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 4, 3, 7 }, - { 0, 3, 9, 2, 6 }, - { 0, 0, 5, 2, 9 } - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, tri.IsReversedStride); - tri = tensor.GetUpperTriangle(1); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 2, 4, 3, 7 }, - { 0, 0, 9, 2, 6 }, - { 0, 0, 0, 2, 9 } - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetUpperTriangle(2); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 0, 4, 3, 7 }, - { 0, 0, 0, 2, 6 }, - { 0, 0, 0, 0, 9 } - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetUpperTriangle(3); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 0, 0, 3, 7 }, - { 0, 0, 0, 0, 6 }, - { 0, 0, 0, 0, 0 } - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - tri = tensor.GetUpperTriangle(4); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 0, 0, 0, 7 }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 } - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - expected = tensorConstructor.CreateFromArray(new[,] - { - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 } - }); - tri = tensor.GetUpperTriangle(5); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetUpperTriangle(6); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetUpperTriangle(1000); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - tri = tensor.GetUpperTriangle(-1); - expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 4, 3, 7 }, - { 8, 3, 9, 2, 6 }, - { 0, 7, 5, 2, 9 } - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - expected = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 4, 3, 7 }, - { 8, 3, 9, 2, 6 }, - { 1, 7, 5, 2, 9 } - }); - tri = tensor.GetUpperTriangle(-2); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - - tri = tensor.GetUpperTriangle(-3); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetUpperTriangle(-4); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - tri = tensor.GetUpperTriangle(-100); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void GetUpperTriangleCube(TensorConstructor tensorConstructor) - { - var arr = new[, ,] - { - { - { 1, 2, 4 }, - { 8, 3, 9 }, - { 1, 7, 5 }, - }, - { - { 4, 5, 7 }, - { 1, 6, 2 }, - { 3, 0, 8 }, - }, - { - { 5, 6, 1 }, - { 2, 2, 3 }, - { 4, 9, 4 }, - }, - - }; - - var tensor = tensorConstructor.CreateFromArray(arr); - var tri = tensor.GetUpperTriangle(0); - var expected = tensorConstructor.CreateFromArray(new[, ,] - { - { - { 1, 2, 4 }, - { 8, 3, 9 }, - { 1, 7, 5 }, - }, - { - { 0, 0, 0 }, - { 1, 6, 2 }, - { 3, 0, 8 }, - }, - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 4, 9, 4 }, - }, - - }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tri, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, tri.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void Reshape(TensorConstructor tensorConstructor) - { - var arr = new[,] - { - { 1, 2, 3 }, - { 4, 5, 6 } - }; - - var tensor = tensorConstructor.CreateFromArray(arr); - var actual = tensor.Reshape(new[] { 3, 2 }); - - var expected = tensorConstructor.IsReversedStride ? - new[,] - { - { 1, 5 }, - { 4, 3 }, - { 2, 6 } - } : - new[,] - { - { 1, 2 }, - { 3, 4 }, - { 5, 6 } - }; - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Fact] - public void Identity() - { - var actual = Tensor.CreateIdentity(3); - - var expected = new[,] - { - {1.0, 0, 0 }, - {0, 1.0, 0 }, - {0, 0, 1.0 } - }; - - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - } - - [Theory] - [MemberData(nameof(GetSingleTensorConstructors))] - public void CreateWithDiagonal(TensorConstructor tensorConstructor) - { - var diagonal = tensorConstructor.CreateFromArray(new[] { 1, 2, 3, 4, 5 }); - var actual = Tensor.CreateFromDiagonal(diagonal); - - var expected = new[,] - { - {1, 0, 0, 0, 0 }, - {0, 2, 0, 0, 0 }, - {0, 0, 3, 0, 0 }, - {0, 0, 0, 4, 0 }, - {0, 0, 0, 0, 5 } - }; - - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - } - - [Theory] - [MemberData(nameof(GetSingleTensorConstructors))] - public void CreateWithDiagonal3D(TensorConstructor tensorConstructor) - { - var diagonal = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 3, 4, 5 }, - { 1, 2, 3, 4, 5 }, - { 1, 2, 3, 4, 5 } - }); - var actual = Tensor.CreateFromDiagonal(diagonal); - var expected = new[, ,] - { - { - {1, 2, 3, 4, 5 }, - {0, 0, 0, 0, 0 }, - {0, 0, 0, 0, 0 } - }, - { - {0, 0, 0, 0, 0 }, - {1, 2, 3, 4, 5 }, - {0, 0, 0, 0, 0 } - }, - { - {0, 0, 0, 0, 0 }, - {0, 0, 0, 0, 0 }, - {1, 2, 3, 4, 5 } - } - }; - - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - } - - [Theory] - [MemberData(nameof(GetSingleTensorConstructors))] - public void CreateWithDiagonalAndOffset(TensorConstructor tensorConstructor) - { - var diagonal = tensorConstructor.CreateFromArray(new[] { 1, 2, 3, 4 }); - var actual = Tensor.CreateFromDiagonal(diagonal, 1); - - var expected = new[,] - { - {0, 1, 0, 0, 0 }, - {0, 0, 2, 0, 0 }, - {0, 0, 0, 3, 0 }, - {0, 0, 0, 0, 4 }, - {0, 0, 0, 0, 0 } - }; - - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - - diagonal = tensorConstructor.CreateFromArray(new[] { 1, 2, 3, 4 }); - actual = Tensor.CreateFromDiagonal(diagonal, -1); - - expected = new[,] - { - {0, 0, 0, 0, 0 }, - {1, 0, 0, 0, 0 }, - {0, 2, 0, 0, 0 }, - {0, 0, 3, 0, 0 }, - {0, 0, 0, 4, 0 } - }; - - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - - diagonal = tensorConstructor.CreateFromArray(new[] { 1 }); - actual = Tensor.CreateFromDiagonal(diagonal, -4); - expected = new[,] - { - {0, 0, 0, 0, 0 }, - {0, 0, 0, 0, 0 }, - {0, 0, 0, 0, 0 }, - {0, 0, 0, 0, 0 }, - {1, 0, 0, 0, 0 } - }; - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - - diagonal = tensorConstructor.CreateFromArray(new[] { 1 }); - actual = Tensor.CreateFromDiagonal(diagonal, 4); - expected = new[,] - { - {0, 0, 0, 0, 1 }, - {0, 0, 0, 0, 0 }, - {0, 0, 0, 0, 0 }, - {0, 0, 0, 0, 0 }, - {0, 0, 0, 0, 0 } - }; - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - } - - [Theory] - [MemberData(nameof(GetSingleTensorConstructors))] - public void CreateWithDiagonalAndOffset3D(TensorConstructor tensorConstructor) - { - var diagonal = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 3 }, - { 1, 2, 3 }, - { 1, 2, 3 } - }); - var actual = Tensor.CreateFromDiagonal(diagonal, 1); - - var expected = new[, ,] - { - { - { 0, 0, 0 }, - { 1, 2, 3 }, - { 0, 0, 0 }, - { 0, 0, 0 } - }, - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 2, 3 }, - { 0, 0, 0 } - }, - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 2, 3 } - }, - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 } - } - }; - - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - - diagonal = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 3 }, - { 1, 2, 3 }, - { 1, 2, 3 } - }); - actual = Tensor.CreateFromDiagonal(diagonal, -1); - - expected = new[, ,] - { - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 } - }, - { - { 1, 2, 3 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 } - }, - { - { 0, 0, 0 }, - { 1, 2, 3 }, - { 0, 0, 0 }, - { 0, 0, 0 } - }, - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 2, 3 }, - { 0, 0, 0 } - } - }; - - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - - diagonal = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 3 } - }); - actual = Tensor.CreateFromDiagonal(diagonal, 3); - - expected = new[, ,] - { - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1, 2, 3 }, - }, - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 } - }, - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 } - }, - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 } - } - }; - - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - - diagonal = tensorConstructor.CreateFromArray(new[,] - { - { 1, 2, 3 } - }); - actual = Tensor.CreateFromDiagonal(diagonal, -3); - - expected = new[, ,] - { - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - }, - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 } - }, - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 } - }, - { - { 1, 2, 3 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 } - } - }; - - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - } - - [Theory()] - [MemberData(nameof(GetDualTensorConstructors))] - public void Add(TensorConstructor leftConstructor, TensorConstructor rightConstructor) - { - var left = leftConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - var right = rightConstructor.CreateFromArray( - new[,] - { - { 6, 7 ,8 }, - { 9, 10 ,11 }, - }); - - var expected = leftConstructor.CreateFromArray( - new[,] - { - { 6, 8, 10 }, - { 12, 14, 16 }, - }); - - var actual = TensorOperations.Add(left, right); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(leftConstructor.IsReversedStride, actual.IsReversedStride); - - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void AddScalar(TensorConstructor tensorConstructor) - { - var tensor = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var expected = tensorConstructor.CreateFromArray( - new[,] - { - { 1, 2, 3 }, - { 4, 5, 6 }, - }); - - var actual = TensorOperations.Add(tensor, 1); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void UnaryPlus(TensorConstructor tensorConstructor) - { - var tensor = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var expected = tensor; - - var actual = TensorOperations.UnaryPlus(tensor); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.False(ReferenceEquals(actual, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - - [Theory()] - [MemberData(nameof(GetDualTensorConstructors))] - public void Subtract(TensorConstructor leftConstructor, TensorConstructor rightConstructor) - { - var left = leftConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - var right = rightConstructor.CreateFromArray( - new[,] - { - { 6, 7 ,8 }, - { 9, 10 ,11 }, - }); - - var expected = leftConstructor.CreateFromArray( - new[,] - { - { -6, -6, -6 }, - { -6, -6, -6}, - }); - - var actual = TensorOperations.Subtract(left, right); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(leftConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void SubtractScalar(TensorConstructor tensorConstructor) - { - var tensor = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - var expected = tensorConstructor.CreateFromArray( - new[,] - { - { -1, 0, 1 }, - { 2, 3, 4 }, - }); - - var actual = TensorOperations.Subtract(tensor, 1); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void UnaryMinus(TensorConstructor tensorConstructor) - { - var tensor = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var expected = tensorConstructor.CreateFromArray( - new[,] - { - {0, -1, -2}, - {-3, -4, -5} - }); - - var actual = TensorOperations.UnaryMinus(tensor); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.False(ReferenceEquals(actual, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void PrefixIncrement(TensorConstructor tensorConstructor) - { - Tensor tensor = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var expectedResult = tensorConstructor.CreateFromArray( - new[,] - { - {1, 2, 3}, - {4, 5, 6} - }); - - var expectedTensor = expectedResult; - - tensor = TensorOperations.Increment(tensor); - var actual = tensor; - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expectedResult)); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tensor, expectedTensor)); - Assert.True(ReferenceEquals(tensor, actual)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void PostfixIncrement(TensorConstructor tensorConstructor) - { - Tensor tensor = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - // returns original value - var expectedResult = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - // increments operand - var expectedTensor = tensorConstructor.CreateFromArray( - new[,] - { - {1, 2, 3}, - {4, 5, 6} - }); - - var actual = tensor; - tensor = TensorOperations.Increment(tensor); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expectedResult)); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tensor, expectedTensor)); - Assert.False(ReferenceEquals(tensor, actual)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void PrefixDecrement(TensorConstructor tensorConstructor) - { - Tensor tensor = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var expectedResult = tensorConstructor.CreateFromArray( - new[,] - { - {-1, 0, 1}, - {2, 3, 4} - }); - - var expectedTensor = expectedResult; - - tensor = TensorOperations.Decrement(tensor); - var actual = tensor; - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expectedResult)); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tensor, expectedTensor)); - Assert.True(ReferenceEquals(tensor, actual)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void PostfixDecrement(TensorConstructor tensorConstructor) - { - Tensor tensor = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - // returns original value - var expectedResult = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - // decrements operand - var expectedTensor = tensorConstructor.CreateFromArray( - new[,] - { - {-1, 0, 1}, - {2, 3, 4} - }); - - var actual = tensor; - tensor = TensorOperations.Decrement(tensor); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expectedResult)); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(tensor, expectedTensor)); - Assert.False(ReferenceEquals(tensor, actual)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetDualTensorConstructors))] - public void Multiply(TensorConstructor leftConstructor, TensorConstructor rightConstructor) - { - var left = leftConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - var right = rightConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var expected = leftConstructor.CreateFromArray( - new[,] - { - {0, 1, 4}, - {9, 16, 25} - }); - - var actual = TensorOperations.Multiply(left, right); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(leftConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void MultiplyScalar(TensorConstructor tensorConstructor) - { - var tensor = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var expected = tensorConstructor.CreateFromArray( - new[,] - { - {0, 2, 4}, - {6, 8, 10} - }); - - var actual = TensorOperations.Multiply(tensor, 2); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetDualTensorConstructors))] - public void Divide(TensorConstructor dividendConstructor, TensorConstructor divisorConstructor) - { - var dividend = dividendConstructor.CreateFromArray( - new[,] - { - {0, 1, 4}, - {9, 16, 25} - }); - - var divisor = divisorConstructor.CreateFromArray( - new[,] - { - {1, 1, 2}, - {3, 4, 5} - }); - - var expected = divisorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var actual = TensorOperations.Divide(dividend, divisor); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(dividendConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void DivideScalar(TensorConstructor tensorConstructor) - { - var tensor = tensorConstructor.CreateFromArray( - new[,] - { - {0, 2, 4}, - {6, 8, 10} - }); - - var expected = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var actual = TensorOperations.Divide(tensor, 2); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetDualTensorConstructors))] - public void Modulo(TensorConstructor dividendConstructor, TensorConstructor divisorConstructor) - { - var dividend = dividendConstructor.CreateFromArray( - new[,] - { - {0, 3, 8}, - {11, 14, 17} - }); - - var divisor = divisorConstructor.CreateFromArray( - new[,] - { - {1, 2, 3}, - {4, 5, 6} - }); - - var expected = dividendConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var actual = TensorOperations.Modulo(dividend, divisor); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(dividendConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void ModuloScalar(TensorConstructor tensorConstructor) - { - var tensor = tensorConstructor.CreateFromArray( - new[,] - { - {0, 3, 4}, - {7, 8, 9} - }); - - var expected = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 0}, - {1, 0, 1} - }); - - var actual = TensorOperations.Modulo(tensor, 2); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetDualTensorConstructors))] - public void And(TensorConstructor leftConstructor, TensorConstructor rightConstructor) - { - var left = leftConstructor.CreateFromArray( - new[,] - { - {0, 1, 3}, - {7, 15, 31} - }); - - var right = rightConstructor.CreateFromArray( - new[,] - { - {1, 1, 3}, - {2, 4, 8} - }); - - var expected = leftConstructor.CreateFromArray( - new[,] - { - {0, 1, 3}, - {2, 4, 8} - }); - - var actual = TensorOperations.And(left, right); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(leftConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void AndScalar(TensorConstructor tensorConstructor) - { - var left = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 3}, - {5, 15, 31} - }); - - var expected = tensorConstructor.CreateFromArray( - new[,] - { - {0, 0, 0}, - {4, 4, 20} - }); - - var actual = TensorOperations.And(left, 20); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetDualTensorConstructors))] - public void Or(TensorConstructor leftConstructor, TensorConstructor rightConstructor) - { - var left = leftConstructor.CreateFromArray( - new[,] - { - {0, 1, 3}, - {7, 14, 31} - }); - - var right = rightConstructor.CreateFromArray( - new[,] - { - {1, 2, 4}, - {2, 4, 8} - }); - - var expected = leftConstructor.CreateFromArray( - new[,] - { - {1, 3, 7}, - {7, 14, 31} - }); - - var actual = TensorOperations.Or(left, right); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(leftConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void OrScalar(TensorConstructor tensorConstructor) - { - var left = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var expected = tensorConstructor.CreateFromArray( - new[,] - { - {1, 1, 3}, - {3, 5, 5} - }); - - var actual = TensorOperations.Or(left, 1); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetDualTensorConstructors))] - public void Xor(TensorConstructor leftConstructor, TensorConstructor rightConstructor) - { - var left = leftConstructor.CreateFromArray( - new[,] - { - {0, 1, 3}, - {7, 14, 31} - }); - - var right = rightConstructor.CreateFromArray( - new[,] - { - {1, 2, 4}, - {2, 4, 8} - }); - - var expected = leftConstructor.CreateFromArray( - new[,] - { - {1, 3, 7}, - {5, 10, 23} - }); - - var actual = TensorOperations.Xor(left, right); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(leftConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void XorScalar(TensorConstructor tensorConstructor) - { - var left = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var expected = tensorConstructor.CreateFromArray( - new[,] - { - {1, 0, 3}, - {2, 5, 4} - }); - - var actual = TensorOperations.Xor(left, 1); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void LeftShift(TensorConstructor tensorConstructor) - { - var left = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var expected = tensorConstructor.CreateFromArray( - new[,] - { - {0, 2, 4}, - {6, 8, 10} - }); - - var actual = TensorOperations.LeftShift(left, 1); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetSingleTensorConstructors))] - public void RightShift(TensorConstructor tensorConstructor) - { - var left = tensorConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var expected = tensorConstructor.CreateFromArray( - new[,] - { - {0, 0, 1}, - {1, 2, 2} - }); - - var actual = TensorOperations.RightShift(left, 1); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(tensorConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetDualTensorConstructors))] - public void ElementWiseEquals(TensorConstructor leftConstructor, TensorConstructor rightConstructor) - { - var left = leftConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - var right = rightConstructor.CreateFromArray( - new[,] - { - {0, 1, -2}, - {2, 3, 5} - }); - - var expected = new[,] - { - {true, true, false }, - {false, false, true} - }.ToTensor(); - - var actual = TensorOperations.Equals(left, right); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(leftConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory()] - [MemberData(nameof(GetDualTensorConstructors))] - public void ElementWiseNotEquals(TensorConstructor leftConstructor, TensorConstructor rightConstructor) - { - var left = leftConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - var right = rightConstructor.CreateFromArray( - new[,] - { - {0, 1, -2}, - {2, 3, 5} - }); - - var expected = new[,] - { - {false, false, true}, - {true, true, false} - }.ToTensor(); - - var actual = TensorOperations.NotEquals(left, right); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.Equal(leftConstructor.IsReversedStride, actual.IsReversedStride); - } - - [Theory] - [MemberData(nameof(GetDualTensorConstructors))] - public void MatrixMultiply(TensorConstructor leftConstructor, TensorConstructor rightConstructor) - { - var left = leftConstructor.CreateFromArray( - new[,] - { - {0, 1, 2}, - {3, 4, 5} - }); - - var right = rightConstructor.CreateFromArray( - new[,] - { - {0, 1, 2, 3, 4}, - {5, 6, 7, 8, 9}, - {10, 11, 12, 13, 14} - }); - - var expected = leftConstructor.CreateFromArray( - new[,] - { - {0*0 + 1*5 + 2*10, 0*1 + 1*6 + 2*11, 0*2 + 1*7 + 2*12, 0*3 + 1*8 + 2*13, 0*4 + 1*9 + 2*14}, - {3*0 + 4*5 + 5*10, 3*1 + 4*6 + 5*11, 3*2 + 4*7 + 5*12, 3*3 + 4*8 + 5*13, 3*4 + 4*9 + 5*14} - }); - - var actual = left.MatrixMultiply(right); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - } - - - [Theory] - [MemberData(nameof(GetDualTensorConstructors))] - public void Contract(TensorConstructor leftConstructor, TensorConstructor rightConstructor) - { - var left = leftConstructor.CreateFromArray( - new[, ,] - { - { - {0, 1}, - {2, 3} - }, - { - {4, 5}, - {6, 7} - }, - { - {8, 9}, - {10, 11} - } - }); - - var right = rightConstructor.CreateFromArray( - new[, ,] - { - { - {0, 1}, - {2, 3}, - {4, 5} - }, - { - {6, 7}, - {8, 9}, - {10, 11} - }, - { - {12, 13}, - {14, 15}, - {16, 17} - }, - { - {18, 19}, - {20, 21}, - {22, 23} - } - }); - - // contract a 3*2*2 with a 4*3*2 tensor, summing on (3*2)*2 and 4*(3*2) to produce a 2*4 tensor - var expected = leftConstructor.CreateFromArray( - new[,] - { - {110, 290, 470, 650}, - {125, 341, 557, 773}, - }); - var actual = TensorOperations.Contract(left, right, new[] { 0, 1 }, new[] { 1, 2 }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - - // contract a 3*2*2 with a 4*3*2 tensor, summing on (3)*2*(2) and 4*(3*2) to produce a 2*4 tensor - expected = leftConstructor.CreateFromArray( - new[,] - { - {101, 263, 425, 587}, - {131, 365, 599, 833}, - }); - actual = TensorOperations.Contract(left, right, new[] { 0, 2 }, new[] { 1, 2 }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - } - - - [Theory] - [MemberData(nameof(GetDualTensorConstructors))] - public void ContractWithSingleLengthDimension(TensorConstructor leftConstructor, TensorConstructor rightConstructor) - { - var left = leftConstructor.CreateFromArray( - new[,] - { - {1, 2, 3}, - {4, 5, 6}, - }); - - var right = rightConstructor.CreateFromArray( - new[,] - { - { 1, 2 }, - { 3, 4 }, - { 5, 6 } - }); - - var expected = leftConstructor.CreateFromArray( - new[,] - { - { 22, 28 }, - { 49, 64 } - }); - - // contract a 2*3 with a 3*2 tensor, summing on 2*(3) and (3)*2 to produce a 2*2 tensor - var actual = TensorOperations.Contract(left, right, new[] { 1 }, new[] { 0 }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - - // contract a 1*2*3*1 with a 3*2 tensor, summing on 1*2*(3)*1 and (3)*2 to produce a 1*2*1*2 tensor - var reshapedLeft = left.Reshape(new int[] { 1, 2, 3, 1 }); - var reshapedExpected = expected.Reshape(new int[] { 1, 2, 1, 2 }); - actual = TensorOperations.Contract(reshapedLeft, right, new[] { 2 }, new[] { 0 }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, reshapedExpected)); - - } - - [Theory] - [MemberData(nameof(GetDualTensorConstructors))] - public void ContractMismatchedDimensions(TensorConstructor leftConstructor, TensorConstructor rightConstructor) - { - var left = leftConstructor.CreateFromArray( - new[] { 0, 1, 2, 3 }); - - var right = rightConstructor.CreateFromArray( - new[,] - { - { 0 }, - { 1 }, - { 2 } - }); - - var expected = leftConstructor.CreateFromArray( - new[,] - { - {0,0,0}, - {0,1,2}, - {0,2,4}, - {0,3,6}, - }); - - Assert.Throws(() => TensorOperations.Contract(left, right, new int[] { }, new[] { 1 })); - - // reshape to include dimension of length 1. - var leftReshaped = left.Reshape(new[] { 1, (int)left.Length }); - - var actual = TensorOperations.Contract(leftReshaped, right, new[] { 0 }, new[] { 1 }); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - } - - [Theory] - [MemberData(nameof(GetSingleTensorConstructors))] - public void GetArrayString(TensorConstructor constructor) - { - var tensor = constructor.CreateFromArray( - new[, ,] - { - { - {0, 1}, - {2, 3}, - {4, 5} - }, - { - {6, 7}, - {8, 9}, - {10, 11} - }, - { - {12, 13}, - {14, 15}, - {16, 17} - }, - { - {18, 19}, - {20, 21}, - {22, 23} - } - }); - - var expected = -@"{ - { - {0,1}, - {2,3}, - {4,5} - }, - { - {6,7}, - {8,9}, - {10,11} - }, - { - {12,13}, - {14,15}, - {16,17} - }, - { - {18,19}, - {20,21}, - {22,23} - } -}"; - - Assert.Equal(expected, tensor.GetArrayString(), ignoreLineEndingDifferences: !LineEndingsHelper.IsNewLineConsistent); - - var expectedNoSpace = expected.Replace(LineEndingsHelper.CompiledNewline, "").Replace(" ", ""); - Assert.Equal(expectedNoSpace, tensor.GetArrayString(false)); - } - - [Theory] - [MemberData(nameof(GetTensorAndResultConstructor))] - public void ToOtherTensor(TensorConstructor sourceConstructor, TensorConstructor resultConstructor) - { - var array = new[, ,] - { - { - {0, 1, 0, 0 }, - {0, 0, 0, 9 }, - {2, 0, 5, 0 } - }, - { - {3, 0, 0, 6 }, - {0, 0, 0, 0 }, - {0, 0, 4, 0 } - }, - { - {0, 2, 0, 0 }, - {8, 0, 0, 0 }, - {0, 0, 12, 0 } - }, - { - {5, 5, 5, 0 }, - {0, 0, 0, 15 }, - {0, 0, 42, 0 } - }, - { - {1, 0, 0, 4 }, - {0, 2, 0, 0 }, - {0, 0, 3, 0 } - } - }; - - var source = sourceConstructor.CreateFromArray(array); - - Tensor expected = resultConstructor.CreateFromArray(array); - - Tensor actual; - - switch (resultConstructor.TensorType) - { - case TensorType.Dense: - actual = source.ToDenseTensor(); - break; - case TensorType.Sparse: - var actualSparse = source.ToSparseTensor(); - actual = actualSparse; - var expectedSparse = expected as SparseTensor; - Assert.Equal(expectedSparse.NonZeroCount, actualSparse.NonZeroCount); - break; - case TensorType.CompressedSparse: - var actualCompressedSparse = source.ToCompressedSparseTensor(); - actual = actualCompressedSparse; - var expectedCompressedSparse = expected as CompressedSparseTensor; - Assert.Equal(expectedCompressedSparse.NonZeroCount, actualCompressedSparse.NonZeroCount); - if (sourceConstructor.TensorType != TensorType.Dense) - { - // expect packed values when going from sparse -> sparse - Assert.Equal(actualCompressedSparse.NonZeroCount, actualCompressedSparse.Values.Length); - } - break; - default: - throw new ArgumentException(nameof(resultConstructor.TensorType)); - } - - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, expected)); - Assert.True(StructuralComparisons.StructuralEqualityComparer.Equals(actual, source)); - } - - [Theory] - [MemberData(nameof(GetSingleTensorConstructors))] - public void TestICollectionMembers(TensorConstructor constructor) - { - var arr = new[,] - { - { 1, 2, 3 }, - { 4, 5, 6 } - }; - - var tensor = constructor.CreateFromArray(arr); - ICollection tensorCollection = tensor; - - Assert.Equal(6, tensorCollection.Count); - - Assert.False(tensorCollection.IsSynchronized); - - Assert.True(ReferenceEquals(tensorCollection, tensorCollection.SyncRoot)); - - var actual = Array.CreateInstance(typeof(int), tensor.Length); - tensorCollection.CopyTo(actual, 0); - var expected = constructor.IsReversedStride ? - new[] { 1, 4, 2, 5, 3, 6 } : - new[] { 1, 2, 3, 4, 5, 6 }; - Assert.Equal(expected, actual); - - actual = Array.CreateInstance(typeof(int), tensor.Length + 2); - tensorCollection.CopyTo(actual, 2); - expected = constructor.IsReversedStride ? - new[] { 0, 0, 1, 4, 2, 5, 3, 6 } : - new[] { 0, 0, 1, 2, 3, 4, 5, 6 }; - Assert.Equal(expected, actual); - - Assert.Throws(() => tensorCollection.CopyTo(null, 0)); - Assert.Throws(() => tensorCollection.CopyTo(new int[3, 4], 0)); - Assert.Throws(() => tensorCollection.CopyTo(new int[5], 0)); - Assert.Throws(() => tensorCollection.CopyTo(new int[6], 1)); - } - - [Theory] - [MemberData(nameof(GetSingleTensorConstructors))] - public void TestIListMembers(TensorConstructor constructor) - { - var arr = new[,] - { - { 1, 2, 3 }, - { 4, 5, 6 } - }; - - var tensor = constructor.CreateFromArray(arr); - IList tensorList = tensor; - - int expectedIndexValue = constructor.IsReversedStride ? 4 : 2; - Assert.Equal(expectedIndexValue, tensorList[1]); - - tensorList[1] = 7; - Assert.Equal(7, tensorList[1]); - var expected = constructor.IsReversedStride ? - new[] { 1, 7, 2, 5, 3, 6 } : - new[] { 1, 7, 3, 4, 5, 6 }; - Assert.Equal(expected, tensor); - - Assert.True(tensorList.IsFixedSize); - Assert.False(tensorList.IsReadOnly); - - Assert.Throws(() => (tensorList).Add(8)); - - Assert.True(tensorList.Contains(5)); - Assert.True(tensorList.Contains(6)); - Assert.False(tensorList.Contains(0)); - Assert.False(tensorList.Contains(42)); - Assert.False(tensorList.Contains("foo")); - - Assert.Equal(constructor.IsReversedStride ? 3 : 4, tensorList.IndexOf(5)); - Assert.Equal(5, tensorList.IndexOf(6)); - Assert.Equal(-1, tensorList.IndexOf(0)); - Assert.Equal(-1, tensorList.IndexOf(42)); - - Assert.Throws(() => (tensorList).Insert(2, 5)); - Assert.Throws(() => (tensorList).Remove(1)); - Assert.Throws(() => (tensorList).RemoveAt(0)); - - tensorList.Clear(); - Assert.Equal(new[] { 0, 0, 0, 0, 0, 0 }, tensor); - } - - [Theory] - [MemberData(nameof(GetSingleTensorConstructors))] - public void TestICollectionTMembers(TensorConstructor constructor) - { - var arr = new[,] - { - { 1, 2, 3 }, - { 4, 5, 6 } - }; - - var tensor = constructor.CreateFromArray(arr); - ICollection tensorCollection = tensor; - - Assert.Equal(6, tensorCollection.Count); - Assert.False(tensorCollection.IsReadOnly); - - Assert.Throws(() => tensorCollection.Add(8)); - Assert.Throws(() => tensorCollection.Remove(1)); - - Assert.True(tensorCollection.Contains(5)); - Assert.True(tensorCollection.Contains(6)); - Assert.False(tensorCollection.Contains(0)); - Assert.False(tensorCollection.Contains(42)); - - var actual = new int[tensor.Length]; - tensorCollection.CopyTo(actual, 0); - var expected = constructor.IsReversedStride ? - new[] { 1, 4, 2, 5, 3, 6 } : - new[] { 1, 2, 3, 4, 5, 6 }; - Assert.Equal(expected, actual); - - actual = new int[tensor.Length + 2]; - tensorCollection.CopyTo(actual, 2); - expected = constructor.IsReversedStride ? - new[] { 0, 0, 1, 4, 2, 5, 3, 6 } : - new[] { 0, 0, 1, 2, 3, 4, 5, 6 }; - Assert.Equal(expected, actual); - - Assert.Throws(() => tensorCollection.CopyTo(null, 0)); - Assert.Throws(() => tensorCollection.CopyTo(new int[5], 0)); - Assert.Throws(() => tensorCollection.CopyTo(new int[6], 1)); - - tensorCollection.Clear(); - Assert.Equal(new[] { 0, 0, 0, 0, 0, 0 }, tensor); - } - - [Theory] - [MemberData(nameof(GetSingleTensorConstructors))] - public void TestIListTMembers(TensorConstructor constructor) - { - var arr = new[,] - { - { 1, 2, 3 }, - { 4, 5, 6 } - }; - - var tensor = constructor.CreateFromArray(arr); - IList tensorList = tensor; - - int expectedIndexValue = constructor.IsReversedStride ? 4 : 2; - Assert.Equal(expectedIndexValue, tensorList[1]); - - tensorList[1] = 7; - Assert.Equal(7, tensorList[1]); - var expected = constructor.IsReversedStride ? - new[] { 1, 7, 2, 5, 3, 6 } : - new[] { 1, 7, 3, 4, 5, 6 }; - Assert.Equal(expected, tensor); - - Assert.Equal(constructor.IsReversedStride ? 3 : 4, tensorList.IndexOf(5)); - Assert.Equal(5, tensorList.IndexOf(6)); - Assert.Equal(-1, tensorList.IndexOf(0)); - Assert.Equal(-1, tensorList.IndexOf(42)); - - Assert.Throws(() => (tensorList).Insert(2, 5)); - Assert.Throws(() => (tensorList).RemoveAt(0)); - } - - [Theory] - [MemberData(nameof(GetSingleTensorConstructors))] - public void TestIReadOnlyTMembers(TensorConstructor constructor) - { - var arr = new[,] - { - { 1, 2, 3 }, - { 4, 5, 6 } - }; - - var tensor = constructor.CreateFromArray(arr); - - IReadOnlyCollection tensorCollection = tensor; - Assert.Equal(6, tensorCollection.Count); - - IReadOnlyList tensorList = tensor; - int expectedIndexValue = constructor.IsReversedStride ? 4 : 2; - Assert.Equal(expectedIndexValue, tensorList[1]); - } - - [Theory] - [MemberData(nameof(GetConstructedTensors))] - public void TestGetEnumerator(Tensor tensor) - { - static IEnumerable GetExpected(Tensor tensor) - { - for (int index = 0; index < tensor.Length; ++index) - yield return tensor.GetValue(index); - } - - Assert.Equal(GetExpected(tensor), tensor); - } - - [Theory] - [MemberData(nameof(GetConstructedTensors))] - public void TestEnumeratorReset(Tensor tensor) - { - static long AdvanceEnumerator(ref Tensor.Enumerator enumerator, long maxCount) - { - long count = 0; - while (count < maxCount && enumerator.MoveNext()) - count++; - - return count; - } - - static void TestStepCountIfInRange(Tensor tensor, long stepCount) - { - if (stepCount < 0 || stepCount > tensor.Length) - return; - - var enumerator = tensor.GetEnumerator(); - long actualStepCount = AdvanceEnumerator(ref enumerator, stepCount); - - Assert.Equal(stepCount, actualStepCount); - - enumerator.Reset(); - - var itemsPostReset = new List(); - while (enumerator.MoveNext()) - itemsPostReset.Add(enumerator.Current); - - Assert.Equal(tensor, itemsPostReset); - } - - TestStepCountIfInRange(tensor, 1); - TestStepCountIfInRange(tensor, tensor.Length - 1); - TestStepCountIfInRange(tensor, tensor.Length / 4); - TestStepCountIfInRange(tensor, tensor.Length - tensor.Length / 4); - TestStepCountIfInRange(tensor, tensor.Length / 2); - TestStepCountIfInRange(tensor, tensor.Length); - } - - [Theory] - [MemberData(nameof(GetConstructedTensors))] - public void TestEnumeratorDispose_DoesNotThrow(Tensor tensor) - { - var enumerator = tensor.GetEnumerator(); - - enumerator.Dispose(); - enumerator.Dispose(); - } - } -} diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorTestsBase.cs b/src/libraries/System.Numerics.Tensors/tests/TensorTestsBase.cs deleted file mode 100644 index 9774dd22662e6a..00000000000000 --- a/src/libraries/System.Numerics.Tensors/tests/TensorTestsBase.cs +++ /dev/null @@ -1,187 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Linq; - -namespace System.Numerics.Tensors.Tests -{ - public class TensorTestsBase - { - public enum TensorType - { - Dense, - Sparse, - CompressedSparse - }; - - public class TensorConstructor - { - public TensorType TensorType { get; set; } - - public bool IsReversedStride { get; set; } - - public Tensor CreateFromArray(Array array) - { - switch (TensorType) - { - case TensorType.Dense: - return array.ToTensor(IsReversedStride); - case TensorType.Sparse: - return array.ToSparseTensor(IsReversedStride); - case TensorType.CompressedSparse: - return array.ToCompressedSparseTensor(IsReversedStride); - } - - throw new ArgumentException(nameof(TensorType)); - } - public Tensor CreateFromDimensions(ReadOnlySpan dimensions) - { - switch (TensorType) - { - case TensorType.Dense: - return new DenseTensor(dimensions, IsReversedStride); - case TensorType.Sparse: - return new SparseTensor(dimensions, IsReversedStride); - case TensorType.CompressedSparse: - return new CompressedSparseTensor(dimensions, IsReversedStride); - } - - throw new ArgumentException(nameof(TensorType)); - } - - public override string ToString() - { - return $"{TensorType}, {nameof(IsReversedStride)} = {IsReversedStride}"; - } - } - - private static TensorType[] s_tensorTypes = new[] - { - TensorType.Dense, - TensorType.Sparse, - TensorType.CompressedSparse - }; - - private static bool[] s_reverseStrideValues = new[] - { - false, - true - }; - - public static IEnumerable GetSingleTensorConstructors() - { - foreach (TensorType tensorType in s_tensorTypes) - { - foreach (bool isReversedStride in s_reverseStrideValues) - { - yield return new[] - { - new TensorConstructor() - { - TensorType = tensorType, - IsReversedStride = isReversedStride - } - }; - } - } - } - - public static IEnumerable GetDualTensorConstructors() - { - foreach (TensorType leftTensorType in s_tensorTypes) - { - foreach (TensorType rightTensorType in s_tensorTypes) - { - foreach (bool isLeftReversedStride in s_reverseStrideValues) - { - foreach (bool isRightReversedStride in s_reverseStrideValues) - { - yield return new[] - { - new TensorConstructor() - { - TensorType = leftTensorType, - IsReversedStride = isLeftReversedStride - }, - new TensorConstructor() - { - TensorType = rightTensorType, - IsReversedStride = isRightReversedStride - } - }; - } - } - } - } - } - - public static IEnumerable GetTensorAndResultConstructor() - { - foreach (TensorType leftTensorType in s_tensorTypes) - { - foreach (TensorType rightTensorType in s_tensorTypes) - { - foreach (bool isReversedStride in s_reverseStrideValues) - { - yield return new[] - { - new TensorConstructor() - { - TensorType = leftTensorType, - IsReversedStride = isReversedStride - }, - new TensorConstructor() - { - TensorType = rightTensorType, - IsReversedStride = isReversedStride - } - }; - } - } - } - } - - public static IEnumerable GetConstructedTensors() - { - foreach (var ctor in GetSingleTensorConstructors().Select(x => (TensorConstructor)x[0])) - { - yield return new object[] { ctor.CreateFromArray(Array.Empty()) }; - yield return new object[] { ctor.CreateFromArray(new[] { 7 }) }; - yield return new object[] { ctor.CreateFromArray(new[] { 7, 14 }) }; - yield return new object[] { ctor.CreateFromArray(new[] { 7, 14, 21 }) }; - yield return new object[] - { - ctor.CreateFromArray(new[,] - { - { 3, 6, 9 }, - { 5, 10, 15 }, - { 7, 14, 21 }, - { 11, 22, 33 } - }) - }; - } - } - - public static NativeMemory NativeMemoryFromArray(T[] array) - { - return NativeMemoryFromArray((Array)array); - } - - public static NativeMemory NativeMemoryFromArray(Array array) - { - // this silly method takes a managed array and copies it over to unmanaged memory, - // **only for test purposes** - - var memory = NativeMemory.Allocate(array.Length); - var span = memory.GetSpan(); - int index = 0; - foreach (T item in array) - { - span[index++] = item; - } - - return memory; - } - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.cs b/src/libraries/System.Private.CoreLib/src/System/Math.cs index 7d20cc72202dd1..266e49fc39dd94 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.cs @@ -1033,7 +1033,7 @@ public static double Min(double val1, double val2) // // It propagates NaN inputs back to the caller and // otherwise returns the lesser of the inputs. It - // treats +0 as lesser than -0 as per the specification. + // treats +0 as greater than -0 as per the specification. if (val1 != val2) { @@ -1091,7 +1091,7 @@ public static float Min(float val1, float val2) // // It propagates NaN inputs back to the caller and // otherwise returns the lesser of the inputs. It - // treats +0 as lesser than -0 as per the specification. + // treats +0 as greater than -0 as per the specification. if (val1 != val2) { @@ -1145,7 +1145,7 @@ public static double MinMagnitude(double x, double y) // // It propagates NaN inputs back to the caller and // otherwise returns the input with a lesser magnitude. - // It treats +0 as lesser than -0 as per the specification. + // It treats +0 as greater than -0 as per the specification. double ax = Abs(x); double ay = Abs(y); diff --git a/src/libraries/System.Private.CoreLib/src/System/MathF.cs b/src/libraries/System.Private.CoreLib/src/System/MathF.cs index 2726d14492f6ab..de0efc14f0ac4f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/MathF.cs +++ b/src/libraries/System.Private.CoreLib/src/System/MathF.cs @@ -285,7 +285,7 @@ public static float MinMagnitude(float x, float y) // // It propagates NaN inputs back to the caller and // otherwise returns the input with a lesser magnitude. - // It treats +0 as lesser than -0 as per the specification. + // It treats +0 as greater than -0 as per the specification. float ax = Abs(x); float ay = Abs(y); From a4459b5da3ebe2fc4b615a26cfe6e795a1b706c5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 21:38:03 -0700 Subject: [PATCH 273/783] [release/8.0] Fix: Config binder generator doesn't generate code when named arguments are out of order (#92257) * Fix Named parameters bug * Test the generator only, don't compare generated file row by row * Add other named parameter combinatios for other overloads in the test, add test for OptionsBuilder... and ServiceCollection extensins * Adjust line numbers with source generator updates * Move similar code section into helper method, don't exact exact line count * Apply feedbacks --------- Co-authored-by: Buyaa Namnan --- .../gen/Parser/ConfigurationBinder.cs | 19 +++- .../ConfigurationBinderTests.Generator.cs | 2 +- .../GeneratorTests.Baselines.Options.cs | 75 +++++++++++++ .../GeneratorTests.Baselines.cs | 106 ++++++++++++++++++ .../GeneratorTests.Helpers.cs | 8 ++ .../ConfigurationExtensionsTest.Generator.cs | 17 +++ 6 files changed, 223 insertions(+), 4 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/ConfigurationBinder.cs index 9feafd72ce7c59..3996142adf9089 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/ConfigurationBinder.cs @@ -77,7 +77,7 @@ private void ParseBindInvocation_ConfigurationBinder(BinderInvocation invocation _ => throw new InvalidOperationException() }; - IArgumentOperation instanceArg = operation.Arguments[instanceIndex]; + IArgumentOperation instanceArg = GetArgumentForParameterAtIndex(operation.Arguments, instanceIndex); if (instanceArg.Parameter.Type.SpecialType != SpecialType.System_Object) { return; @@ -119,6 +119,19 @@ private void ParseBindInvocation_ConfigurationBinder(BinderInvocation invocation }; } + private static IArgumentOperation GetArgumentForParameterAtIndex(ImmutableArray arguments, int parameterIndex) + { + foreach (var argument in arguments) + { + if (argument.Parameter?.Ordinal == parameterIndex) + { + return argument; + } + } + + throw new InvalidOperationException(); + } + private void ParseGetInvocation(BinderInvocation invocation) { IInvocationOperation operation = invocation.Operation!; @@ -158,7 +171,7 @@ private void ParseGetInvocation(BinderInvocation invocation) } else { - ITypeOfOperation? typeOfOperation = operation.Arguments[1].ChildOperations.FirstOrDefault() as ITypeOfOperation; + ITypeOfOperation? typeOfOperation = GetArgumentForParameterAtIndex(operation.Arguments, 1).ChildOperations.FirstOrDefault() as ITypeOfOperation; type = typeOfOperation?.TypeOperand; if (paramCount is 2) @@ -218,7 +231,7 @@ private void ParseGetValueInvocation(BinderInvocation invocation) return; } - ITypeOfOperation? typeOfOperation = operation.Arguments[1].ChildOperations.FirstOrDefault() as ITypeOfOperation; + ITypeOfOperation? typeOfOperation = GetArgumentForParameterAtIndex(operation.Arguments, 1).ChildOperations.FirstOrDefault() as ITypeOfOperation; type = typeOfOperation?.TypeOperand; if (paramCount is 3) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBinderTests.Generator.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBinderTests.Generator.cs index 1ffb263c836a1c..5b6d824e87dbe9 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBinderTests.Generator.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBinderTests.Generator.cs @@ -317,7 +317,7 @@ internal class ClassWithThisIdentifier /// /// These are regression tests for https://github.com/dotnet/runtime/issues/90909. /// Ensure that we don't emit root interceptors to handle types/members that - /// are inaccessible to the generated helpers. Tests for inaccessbile transitive members + /// are inaccessible to the generated helpers. Tests for inaccessible transitive members /// are covered in the shared (reflection/src-gen) , /// e.g. . /// diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.Options.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.Options.cs index c3d1ce89c1206f..4480ab4066882c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.Options.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.Options.cs @@ -60,6 +60,81 @@ public async Task Configure_T_BinderOptions() => public async Task Configure_T_name_BinderOptions() => await VerifyAgainstBaselineUsingFile("Configure_T_name_BinderOptions.generated.txt", GetConfigureSource(@""""", section, _ => { }"), extType: ExtensionClassType.ServiceCollection); + [Theory] + [InlineData("OptionsConfigurationServiceCollectionExtensions.Configure(config: section, services: services);")] + [InlineData("""OptionsConfigurationServiceCollectionExtensions.Configure(name: "", config: section, services: services);""")] + [InlineData("OptionsConfigurationServiceCollectionExtensions.Configure(configureBinder: _ => { }, config: section, services: services);")] + [InlineData("""OptionsConfigurationServiceCollectionExtensions.Configure(configureBinder: _ => { }, config: section, name: "", services: services);""")] + [InlineData("""OptionsConfigurationServiceCollectionExtensions.Configure(name: "", services: services, configureBinder: _ => { }, config: section);""")] + public async Task Configure_T_NamedParameters_OutOfOrder(string row) + { + string source = $$""" + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfiguration config = configurationBuilder.Build(); + IConfigurationSection section = config.GetSection("MySection"); + ServiceCollection services = new(); + + {{row}} + } + + public class MyClass + { + public string MyString { get; set; } + public int MyInt { get; set; } + public List MyList { get; set; } + public Dictionary MyDictionary { get; set; } + } + } + """; + + await VerifyThatSourceIsGenerated(source); + } + + [Theory] + [InlineData("OptionsBuilderConfigurationExtensions.Bind(config: config, optionsBuilder: optionsBuilder);")] + [InlineData("OptionsBuilderConfigurationExtensions.Bind(configureBinder: _ => { }, config: config, optionsBuilder: optionsBuilder);")] + [InlineData("OptionsBuilderConfigurationExtensions.Bind(config: config, configureBinder: _ => { }, optionsBuilder: optionsBuilder);")] + public async Task Bind_T_NamedParameters_OutOfOrder(string row) + { + string source = $$""" + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Options; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfiguration config = configurationBuilder.Build(); + var services = new ServiceCollection(); + OptionsBuilder optionsBuilder = new(services, ""); + + {{row}} + } + + public class MyClass + { + public string MyString { get; set; } + public int MyInt { get; set; } + public List MyList { get; set; } + public Dictionary MyDictionary { get; set; } + } + } + """; + + await VerifyThatSourceIsGenerated(source); + } + private string GetBindSource(string? configureActions = null) => $$""" using System.Collections.Generic; using Microsoft.Extensions.Configuration; diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs index c48148c74c5891..3c46f5f99818b1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs @@ -15,6 +15,112 @@ public partial class ConfigurationBindingGeneratorTests public async Task Bind() => await VerifyAgainstBaselineUsingFile("Bind.generated.txt", BindCallSampleCode, extType: ExtensionClassType.ConfigurationBinder); + [Theory] + [InlineData("ConfigurationBinder.Bind(instance: configObj, configuration: config);")] + [InlineData("""ConfigurationBinder.Bind(key: "", instance: configObj, configuration: config);""")] + [InlineData("""ConfigurationBinder.Bind(instance: configObj, key: "", configuration: config);""")] + [InlineData("ConfigurationBinder.Bind(configureOptions: _ => { }, configuration: config, instance: configObj);")] + [InlineData("ConfigurationBinder.Bind(configuration: config, configureOptions: _ => { }, instance: configObj);")] + public async Task Bind_NamedParameters_OutOfOrder(string row) + { + string source = $$""" + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfigurationRoot config = configurationBuilder.Build(); + + MyClass configObj = new(); + {{row}} + } + + public class MyClass + { + public string MyString { get; set; } + public int MyInt { get; set; } + public List MyList { get; set; } + public Dictionary MyDictionary { get; set; } + } + } + """; + + await VerifyThatSourceIsGenerated(source); + } + + [Theory] + [InlineData("var obj = ConfigurationBinder.Get(type: typeof(MyClass), configuration: config);")] + [InlineData("var obj = ConfigurationBinder.Get(configureOptions: _ => { }, configuration: config);")] + [InlineData("var obj = ConfigurationBinder.Get(configureOptions: _ => { }, type: typeof(MyClass), configuration: config);")] + [InlineData("var obj = ConfigurationBinder.Get(type: typeof(MyClass), configureOptions: _ => { }, configuration: config);")] + public async Task Get_TypeOf_NamedParametersOutOfOrder(string row) + { + string source = $$""" + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfigurationRoot config = configurationBuilder.Build(); + + MyClass configObj = new(); + {{row}} + } + + public class MyClass + { + public string MyString { get; set; } + public int MyInt { get; set; } + public List MyList { get; set; } + public Dictionary MyDictionary { get; set; } + } + } + """; + + await VerifyThatSourceIsGenerated(source); + } + + [Theory] + [InlineData("""var str = ConfigurationBinder.GetValue(key: "key", configuration: config, type: typeof(string));""")] + [InlineData("""var str = ConfigurationBinder.GetValue(key: "key", configuration: config);""")] + [InlineData("""var str = ConfigurationBinder.GetValue(key: "key", defaultValue: "default", configuration: config);""")] + [InlineData("""var str = ConfigurationBinder.GetValue(configuration: config, key: "key", defaultValue: "default");""")] + [InlineData("""var str = ConfigurationBinder.GetValue(defaultValue: "default", key: "key", configuration: config, type: typeof(string));""")] + [InlineData("""var str = ConfigurationBinder.GetValue(defaultValue: "default", type: typeof(string), key: "key", configuration: config);""")] + public async Task GetValue_NamedParametersOutOfOrder(string row) + { + string source = $$""" + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfigurationRoot config = configurationBuilder.Build(); + {{row}} + } + + public class MyClass + { + public string MyString { get; set; } + public int MyInt { get; set; } + public List MyList { get; set; } + public Dictionary MyDictionary { get; set; } + } + } + """; + + await VerifyThatSourceIsGenerated(source); + } + [Fact] public async Task Bind_Instance() { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs index 0053cb41f37020..bee4d14072ad48 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs @@ -85,6 +85,14 @@ private enum ExtensionClassType ServiceCollection, } + private static async Task VerifyThatSourceIsGenerated(string testSourceCode) + { + var (d, r) = await RunGenerator(testSourceCode); + Assert.Equal(1, r.Length); + Assert.Empty(d); + Assert.True(r[0].SourceText.Lines.Count > 10); + } + private static async Task VerifyAgainstBaselineUsingFile( string filename, string testSourceCode, diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/ConfigurationExtensionsTest.Generator.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/ConfigurationExtensionsTest.Generator.cs index a18efc6909b71d..9b3aff8c495a77 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/ConfigurationExtensionsTest.Generator.cs +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/ConfigurationExtensionsTest.Generator.cs @@ -156,5 +156,22 @@ public void TestBindingInvocationsWithNewlines_StaticCalls() ) ; } + + [Fact] + public void TestBindAndConfigureWithNamedParameters() + { + OptionsBuilder? optionsBuilder = CreateOptionsBuilder(); + IServiceCollection services = new ServiceCollection(); + + OptionsBuilderConfigurationExtensions.Bind(config: s_emptyConfig, optionsBuilder: optionsBuilder); + OptionsBuilderConfigurationExtensions.Bind(configureBinder: _ => { }, config: s_emptyConfig, optionsBuilder: optionsBuilder); + + OptionsBuilderConfigurationExtensions.BindConfiguration(configureBinder: _ => { }, configSectionPath: "path", optionsBuilder: optionsBuilder); + + OptionsConfigurationServiceCollectionExtensions.Configure(config: s_emptyConfig, services: services); + OptionsConfigurationServiceCollectionExtensions.Configure(name: "", config: s_emptyConfig, services: services); + OptionsConfigurationServiceCollectionExtensions.Configure(configureBinder: _ => { }, config: s_emptyConfig, services: services); + OptionsConfigurationServiceCollectionExtensions.Configure(name: "", configureBinder: _ => { }, config: s_emptyConfig, services: services); + } } } From f678a18f80574f3b9233406a76ffa93faf0fcbab Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Mon, 18 Sep 2023 21:38:23 -0700 Subject: [PATCH 274/783] Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2270458 (#92258) --- .../gen/Resources/xlf/Strings.cs.xlf | 2 +- .../gen/Resources/xlf/Strings.pt-BR.xlf | 2 +- .../gen/Resources/xlf/Strings.tr.xlf | 2 +- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 2 +- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf index 3f881b123eb971..8af274c8cb6562 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.cs.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + Pro volání vazby se nevygenerovala logika vazby. Mezi nepodporované vstupní vzory patří obecná volání, předávání zabalených objektů a předávání typů, které nejsou public ani internal. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf index e15e781b7abfdc..965a1181aacd34 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.pt-BR.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + A lógica de associação não foi gerada para uma chamada de fichário. Padrões de entrada sem suporte incluem chamadas genéricas, passagem de objetos em caixa e passagem de tipos que não são 'públicos' ou 'internos'. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf index cd53389a70ed28..1ffbaa22a96a85 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.tr.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + Bağlama mantığı bir bağlayıcı çağrısı için oluşturulmadı. Desteklenmeyen giriş düzenleri şunları içerir: genel çağrılar, geçirilen kutulu nesneler ve ‘genel’ veya ‘iç’ olmayan geçirme türleri. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf index 55c321ec0d801f..dd89336534060a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + 没有为绑定器调用生成绑定逻辑。不支持的输入模式包括泛型调用、传递装箱对象和传递不是“public”或“internal”的类型。 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf index edc74d0c17ad97..a30c193b7f0115 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -9,7 +9,7 @@ Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. - Binding logic was not generated for a binder call. Unsupported input patterns include generic calls, passing boxed objects, and passing types that are not 'public' or 'internal'. + 未產生文件夾呼叫的繫結邏輯。不支援的輸入模式包括一般呼叫、傳遞方塊物件,以及非 'public' 或 'internal' 的傳遞類型。。 From c38ca786c62107935f48cdf156d3f23405efa85b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 21:38:55 -0700 Subject: [PATCH 275/783] [release/8.0] Use strategy in StrategyBasedComWrappers.ComputeVtables (#92250) * Use strategy in StrategyBasedComWrappers.ComputeVtables We didn't actually use the strategy object here, so users like WinForms can't actually use it. * Update src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/StrategyBasedComWrappers.cs Co-authored-by: Jackson Schuster <36744439+jtschuster@users.noreply.github.com> --------- Co-authored-by: Jeremy Koritzinsky Co-authored-by: Jackson Schuster <36744439+jtschuster@users.noreply.github.com> --- .../InteropServices/Marshalling/StrategyBasedComWrappers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/StrategyBasedComWrappers.cs b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/StrategyBasedComWrappers.cs index 14ced03d3a7fd0..9741b482633c24 100644 --- a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/StrategyBasedComWrappers.cs +++ b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/StrategyBasedComWrappers.cs @@ -76,7 +76,7 @@ static IIUnknownInterfaceDetailsStrategy GetInteropStrategy() /// protected sealed override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { - if (obj.GetType().GetCustomAttribute(typeof(ComExposedClassAttribute<>)) is IComExposedDetails details) + if (GetOrCreateInterfaceDetailsStrategy().GetComExposedTypeDetails(obj.GetType().TypeHandle) is { } details) { return details.GetComInterfaceEntries(out count); } From 18810713324b93a18fba99d3be2ac12bd2794cb0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 09:09:48 -0700 Subject: [PATCH 276/783] [release/8.0] Update dependencies from dotnet/roslyn (#92149) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/dotnet/roslyn build 20230915.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23462.10 -> To Version 4.8.0-3.23465.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230915.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23462.10 -> To Version 4.8.0-3.23465.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230915.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23462.10 -> To Version 4.8.0-3.23465.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230915.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23462.10 -> To Version 4.8.0-3.23465.5 * Use InterceptorsPreviewNamespaces instead of the InterceptorsPreview feature * Update dependencies from https://github.com/dotnet/roslyn build 20230918.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23462.10 -> To Version 4.8.0-3.23468.1 * Bring back removed lines * Add CSharpParseOption InterceptorsPreviewNamespaces feature to GeneratorTests.Helpers.cs * Add TODO comment to remove feature * Update dependencies from https://github.com/dotnet/roslyn build 20230918.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23462.10 -> To Version 4.8.0-3.23468.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230918.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23462.10 -> To Version 4.8.0-3.23468.4 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- .../SourceGenerationTests/GeneratorTests.Helpers.cs | 5 ++++- ...onfiguration.Binder.SourceGeneration.Tests.csproj | 2 ++ ...Microsoft.Extensions.Logging.Configuration.csproj | 2 ++ .../src/Microsoft.Extensions.Logging.Console.csproj | 2 ++ ...igurationExtensions.SourceGeneration.Tests.csproj | 2 ++ 7 files changed, 21 insertions(+), 10 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 161eab1c82c64c..1cc807a9f61d92 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - 1b7a6f807cb8ce709048debae6b771f4705a697a + a19fe34b7266ab7638a12c2b54748d89d35a21a7 - + https://github.com/dotnet/roslyn - 1b7a6f807cb8ce709048debae6b771f4705a697a + a19fe34b7266ab7638a12c2b54748d89d35a21a7 - + https://github.com/dotnet/roslyn - 1b7a6f807cb8ce709048debae6b771f4705a697a + a19fe34b7266ab7638a12c2b54748d89d35a21a7 https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index f71e6cc183dd73..abad67dca392aa 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -42,9 +42,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23462.10 - 4.8.0-3.23462.10 - 4.8.0-3.23462.10 + 4.8.0-3.23468.4 + 4.8.0-3.23468.4 + 4.8.0-3.23468.4 SYSLIB1100,SYSLIB1101 $(Features);InterceptorsPreview + + $(InterceptorsPreviewNamespaces);Microsoft.Extensions.Configuration.Binder.SourceGeneration true diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj index c0074144e78d9f..820eb7fa062e72 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj @@ -4,6 +4,8 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true $(Features);InterceptorsPreview + + $(InterceptorsPreviewNamespaces);Microsoft.Extensions.Configuration.Binder.SourceGeneration true true Configuration support for Microsoft.Extensions.Logging. diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj index 0dceab438f82f3..1f12dab5b9ac44 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj @@ -8,6 +8,8 @@ true true $(Features);InterceptorsPreview + + $(InterceptorsPreviewNamespaces);Microsoft.Extensions.Configuration.Binder.SourceGeneration true true Console logger provider implementation for Microsoft.Extensions.Logging. diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/Microsoft.Extensions.Options.ConfigurationExtensions.SourceGeneration.Tests.csproj b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/Microsoft.Extensions.Options.ConfigurationExtensions.SourceGeneration.Tests.csproj index f08d2bd649bc3f..2bdacc95ff39e6 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/Microsoft.Extensions.Options.ConfigurationExtensions.SourceGeneration.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/tests/SourceGenerationTests/Microsoft.Extensions.Options.ConfigurationExtensions.SourceGeneration.Tests.csproj @@ -4,6 +4,8 @@ $(NetCoreAppCurrent);$(NetFrameworkMinimum) $(DefineConstants);BUILDING_SOURCE_GENERATOR_TESTS;ROSLYN4_0_OR_GREATER;ROSLYN4_4_OR_GREATER $(Features);InterceptorsPreview + + $(InterceptorsPreviewNamespaces);Microsoft.Extensions.Configuration.Binder.SourceGeneration true true From 575843df1aeb430a3071e2e494d29b59080751ad Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 09:15:33 -0700 Subject: [PATCH 277/783] [release/8.0] Fix downlevel build break in TensorPrimitives (#92270) * Fix downlevel build break in TensorPrimitives * Make net6.0 Tensors use ns2.0 implementation --------- Co-authored-by: Stephen Toub Co-authored-by: Eric StJohn --- .../ref/System.Numerics.Tensors.csproj | 2 +- .../src/System.Numerics.Tensors.csproj | 4 ++-- .../Tensors/TensorPrimitives.netcore.cs | 6 ++++++ .../Tensors/TensorPrimitives.netstandard.cs | 20 +++++++++---------- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj index 89bdef6ea38ed9..8d28b0e077d9cd 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj index 097fa244ad4913..be4a04702af5e1 100644 --- a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj @@ -16,11 +16,11 @@ - + - + diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs index 4f40aa31494c97..ae5af404ac1aff 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs @@ -1159,7 +1159,9 @@ public static float Invoke(Vector512 x) public static float Invoke(float x) => -x; public static Vector128 Invoke(Vector128 x) => -x; public static Vector256 Invoke(Vector256 x) => -x; +#if NET8_0_OR_GREATER public static Vector512 Invoke(Vector512 x) => -x; +#endif } private readonly struct AddMultiplyOperator : ITernaryOperator @@ -1167,7 +1169,9 @@ public static float Invoke(Vector512 x) public static float Invoke(float x, float y, float z) => (x + y) * z; public static Vector128 Invoke(Vector128 x, Vector128 y, Vector128 z) => (x + y) * z; public static Vector256 Invoke(Vector256 x, Vector256 y, Vector256 z) => (x + y) * z; +#if NET8_0_OR_GREATER public static Vector512 Invoke(Vector512 x, Vector512 y, Vector512 z) => (x + y) * z; +#endif } private readonly struct MultiplyAddOperator : ITernaryOperator @@ -1175,7 +1179,9 @@ public static float Invoke(Vector512 x) public static float Invoke(float x, float y, float z) => (x * y) + z; public static Vector128 Invoke(Vector128 x, Vector128 y, Vector128 z) => (x * y) + z; public static Vector256 Invoke(Vector256 x, Vector256 y, Vector256 z) => (x * y) + z; +#if NET8_0_OR_GREATER public static Vector512 Invoke(Vector512 x, Vector512 y, Vector512 z) => (x * y) + z; +#endif } private readonly struct LoadIdentity : IUnaryOperator diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs index 134364708b8e5d..ba3fc69bab527f 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs @@ -69,8 +69,8 @@ private static float CosineSimilarityCore(ReadOnlySpan x, ReadOnlySpan( float identityValue, ReadOnlySpan x, TLoad load = default, TAggregate aggregate = default) - where TLoad : IUnaryOperator - where TAggregate : IBinaryOperator + where TLoad : struct, IUnaryOperator + where TAggregate : struct, IBinaryOperator { // Initialize the result to the identity value float result = identityValue; @@ -112,8 +112,8 @@ private static float Aggregate( private static float Aggregate( float identityValue, ReadOnlySpan x, ReadOnlySpan y, TBinary binary = default, TAggregate aggregate = default) - where TBinary : IBinaryOperator - where TAggregate : IBinaryOperator + where TBinary : struct, IBinaryOperator + where TAggregate : struct, IBinaryOperator { // Initialize the result to the identity value float result = identityValue; @@ -156,7 +156,7 @@ private static float Aggregate( private static void InvokeSpanIntoSpan( ReadOnlySpan x, Span destination, TUnaryOperator op = default) - where TUnaryOperator : IUnaryOperator + where TUnaryOperator : struct, IUnaryOperator { if (x.Length > destination.Length) { @@ -203,7 +203,7 @@ private static void InvokeSpanIntoSpan( private static void InvokeSpanSpanIntoSpan( ReadOnlySpan x, ReadOnlySpan y, Span destination, TBinaryOperator op = default) - where TBinaryOperator : IBinaryOperator + where TBinaryOperator : struct, IBinaryOperator { if (x.Length != y.Length) { @@ -258,7 +258,7 @@ private static void InvokeSpanSpanIntoSpan( private static void InvokeSpanScalarIntoSpan( ReadOnlySpan x, float y, Span destination, TBinaryOperator op = default) - where TBinaryOperator : IBinaryOperator + where TBinaryOperator : struct, IBinaryOperator { if (x.Length > destination.Length) { @@ -309,7 +309,7 @@ private static void InvokeSpanScalarIntoSpan( private static void InvokeSpanSpanSpanIntoSpan( ReadOnlySpan x, ReadOnlySpan y, ReadOnlySpan z, Span destination, TTernaryOperator op = default) - where TTernaryOperator : ITernaryOperator + where TTernaryOperator : struct, ITernaryOperator { if (x.Length != y.Length || x.Length != z.Length) { @@ -369,7 +369,7 @@ private static void InvokeSpanSpanSpanIntoSpan( private static void InvokeSpanSpanScalarIntoSpan( ReadOnlySpan x, ReadOnlySpan y, float z, Span destination, TTernaryOperator op = default) - where TTernaryOperator : ITernaryOperator + where TTernaryOperator : struct, ITernaryOperator { if (x.Length != y.Length) { @@ -430,7 +430,7 @@ private static void InvokeSpanSpanScalarIntoSpan( private static void InvokeSpanScalarSpanIntoSpan( ReadOnlySpan x, float y, ReadOnlySpan z, Span destination, TTernaryOperator op = default) - where TTernaryOperator : ITernaryOperator + where TTernaryOperator : struct, ITernaryOperator { if (x.Length != z.Length) { From 3108db27c369bdfec2eaf28329656652a6201eab Mon Sep 17 00:00:00 2001 From: Matt Thalman Date: Tue, 19 Sep 2023 14:00:12 -0500 Subject: [PATCH 278/783] Update Newtonsoft.Json from 13.0.1 to 13.0.3 (#92277) * Update Newtonsoft.Json from 13.0.1 to 13.0.3 * Update source-build-externals * Add prebuilt exclusion --- eng/SourceBuildPrebuiltBaseline.xml | 7 ++++++- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/eng/SourceBuildPrebuiltBaseline.xml b/eng/SourceBuildPrebuiltBaseline.xml index 46dd7457d764aa..458b2d756cba9a 100644 --- a/eng/SourceBuildPrebuiltBaseline.xml +++ b/eng/SourceBuildPrebuiltBaseline.xml @@ -16,7 +16,12 @@ - + + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1cc807a9f61d92..648b4f19642f87 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -100,9 +100,9 @@ 3dd2c0ef203db8fe0e849557960b4cd009afbaac - + https://github.com/dotnet/source-build-externals - de4dda48d0cf31e13182bc24107b2246c61ed483 + e9d6489787a5ea5400a31dfa34aa6ad6b590de9b diff --git a/eng/Versions.props b/eng/Versions.props index abad67dca392aa..dff5222a155585 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -191,7 +191,7 @@ 3.12.0 4.1.0 6.0.0 - 13.0.1 + 13.0.3 1.0.2 2.0.4 4.18.4 From a49a52951a185779e017f49681abf12943b9e8e8 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 12:22:09 -0700 Subject: [PATCH 279/783] Update dependencies from https://github.com/dotnet/roslyn build 20230919.1 (#92288) Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23468.4 -> To Version 4.8.0-3.23469.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 648b4f19642f87..83e0c865d5612a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - a19fe34b7266ab7638a12c2b54748d89d35a21a7 + 9233e36abc5e2ca263dbd4d1616f35623440a935 - + https://github.com/dotnet/roslyn - a19fe34b7266ab7638a12c2b54748d89d35a21a7 + 9233e36abc5e2ca263dbd4d1616f35623440a935 - + https://github.com/dotnet/roslyn - a19fe34b7266ab7638a12c2b54748d89d35a21a7 + 9233e36abc5e2ca263dbd4d1616f35623440a935 https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index dff5222a155585..f053a60a286cb8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -42,9 +42,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23468.4 - 4.8.0-3.23468.4 - 4.8.0-3.23468.4 + 4.8.0-3.23469.1 + 4.8.0-3.23469.1 + 4.8.0-3.23469.1 - 8.0.0-preview-20230828.1 + 8.0.0-preview-20230918.1 8.0.0-rc.1.23406.6 From d3da653d407bede37c51b3ed7ecac0498ae63e39 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 13:00:17 -0700 Subject: [PATCH 281/783] [release/8.0] Update dependencies from 7 repositories (#92143) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/dotnet/emsdk build 20230915.1 Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rc.2.23463.1 -> To Version 8.0.0-rc.2.23465.1 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20230916.2 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23464.2 -> To Version 3.11.0-beta1.23466.2 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20230916.2 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23464.2 -> To Version 3.11.0-beta1.23466.2 * Update dependencies from https://github.com/dotnet/emsdk build 20230918.1 Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rc.2.23463.1 -> To Version 8.0.0-rc.2.23468.1 * Update dependencies from https://github.com/dotnet/emsdk build 20230918.2 Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rc.2.23463.1 -> To Version 8.0.0-rtm.23468.2 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20230918.1 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23464.2 -> To Version 3.11.0-beta1.23468.1 * Update dependencies from https://github.com/dotnet/cecil build 20230918.2 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23461.1 -> To Version 0.11.4-alpha.23468.2 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20230918.1 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23464.2 -> To Version 3.11.0-beta1.23468.1 * Update dependencies from https://github.com/dotnet/msquic build 20230918.1 System.Net.MsQuic.Transport From Version 8.0.0-alpha.1.23412.1 -> To Version 8.0.0-alpha.1.23468.1 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20230918.2 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23461.1 -> To Version 8.0.0-alpha.0.23468.2 * Update dependencies from https://github.com/dotnet/icu build 20230918.3 Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rc.2.23454.2 -> To Version 8.0.0-rtm.23468.3 * Roll back icu and emsdk to rc2 builds * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20230919.1 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23463.1 -> To Version 8.0.0-alpha.1.23469.1 * Update dependencies from https://github.com/dotnet/emsdk build 20230919.3 Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rc.2.23463.1 -> To Version 8.0.0-rtm.23469.3 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> Co-authored-by: Larry Ewing --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 83e0c865d5612a..04567c6742f81f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + https://github.com/dotnet/icu - 0bd4ee514dc6abe5cc664282709e70d5e26bb11d + ac7697a28716e68e986d3db72cbc10324f8961fe - + https://github.com/dotnet/msquic - 72811ab66f2611ac9f652cbb020dba033fc37401 + bbb1252b31e3a194be3163982d972e4583c75476 https://github.com/dotnet/wcf @@ -85,19 +85,19 @@ 02fe27cd6a9b001c8feb7938e6ef4b3799745759b - + https://github.com/dotnet/cecil - a112f15aa032c029b7d9c77df3427111d93cf407 + 89be445dd4936157533ad96bafb95f701430653a - + https://github.com/dotnet/emsdk - 1999c8c8ab7473a7e1c5b7bdf5ba6d9a985a69cc + 50bf805c8b5ca52abd34fde390609d8a54640246 - + https://github.com/dotnet/source-build-reference-packages - 3dd2c0ef203db8fe0e849557960b4cd009afbaac + d825c6693d4e26f63aaa93c3c1d057faa098e347 @@ -371,13 +371,13 @@ https://github.com/dotnet/roslyn 9233e36abc5e2ca263dbd4d1616f35623440a935 - + https://github.com/dotnet/roslyn-analyzers - 7ec4e8924bcbc469e00aa2bda84251c3e90aa96e + 2c9a20b6706b8a9ad650b41bff30980cf5af67ed - + https://github.com/dotnet/roslyn-analyzers - 7ec4e8924bcbc469e00aa2bda84251c3e90aa96e + 2c9a20b6706b8a9ad650b41bff30980cf5af67ed https://github.com/dotnet/sdk diff --git a/eng/Versions.props b/eng/Versions.props index f18a9bdf8b010d..113383aab30cf2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,8 +34,8 @@ - 3.11.0-beta1.23464.2 - 8.0.0-preview.23464.2 + 3.11.0-beta1.23468.1 + 8.0.0-preview.23468.1 8.0.0-rc.1.23406.6 - 0.11.4-alpha.23461.1 + 0.11.4-alpha.23468.2 8.0.0-rc.1.23406.6 - 8.0.0-rc.2.23454.2 + 8.0.0-rc.2.23468.2 2.2.2 - 8.0.0-alpha.1.23412.1 + 8.0.0-alpha.1.23468.1 16.0.5-alpha.1.23423.1 16.0.5-alpha.1.23423.1 @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.0-rc.2.23463.1 + 8.0.0-rtm.23469.3 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda From 36b7c0b8e28e78109594f74a4119ab0e1247bdd0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 17:12:11 -0700 Subject: [PATCH 282/783] Update dependencies from https://github.com/dotnet/emsdk build 20230919.1 (#92306) Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rtm.23469.3 -> To Version 8.0.0-rc.2.23469.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 04567c6742f81f..489044e0d17884 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,9 +90,9 @@ 89be445dd4936157533ad96bafb95f701430653a - + https://github.com/dotnet/emsdk - 50bf805c8b5ca52abd34fde390609d8a54640246 + ca3e8e40f417e421141638c66dd301395afee66d diff --git a/eng/Versions.props b/eng/Versions.props index 113383aab30cf2..d56eeab17ef17d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.0-rtm.23469.3 + 8.0.0-rc.2.23469.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda From dcdc5f5269c2cb44c92a8ddf7917eaa30a9ca248 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 23:11:15 -0700 Subject: [PATCH 283/783] Fix options Validation with objects have indexers (#92311) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tarek Mahmoud Sayed Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- .../src/DataAnnotationValidateOptions.cs | 3 +- .../OptionsRuntimeTests.cs | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/DataAnnotationValidateOptions.cs b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/DataAnnotationValidateOptions.cs index e8f4b606882cf9..5b734edf32738c 100644 --- a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/DataAnnotationValidateOptions.cs +++ b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/DataAnnotationValidateOptions.cs @@ -95,7 +95,8 @@ private static bool TryValidateOptions(object options, string qualifiedName, Lis foreach (PropertyInfo propertyInfo in options.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) { - if (propertyInfo.GetMethod is null) + // Indexers are properties which take parameters. Ignore them. + if (propertyInfo.GetMethod is null || propertyInfo.GetMethod.GetParameters().Length > 0) { continue; } diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs index b644eea74120f7..6109bccd296463 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs @@ -177,6 +177,30 @@ public void TestValidationWithEnumeration() result2.Failures); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + public void TestObjectsWithIndexerProperties() + { + DataAnnotationValidateOptions dataAnnotationValidateOptions1 = new("MyDictionaryOptions"); + MyDictionaryOptionsOptionsValidator sourceGenOptionsValidator1 = new(); + + var options1 = new MyDictionaryOptions(); + ValidateOptionsResult result1 = sourceGenOptionsValidator1.Validate("MyDictionaryOptions", options1); + ValidateOptionsResult result2 = dataAnnotationValidateOptions1.Validate("MyDictionaryOptions", options1); + + Assert.True(result1.Succeeded); + Assert.True(result2.Succeeded); + + DataAnnotationValidateOptions> dataAnnotationValidateOptions2 = new("MyListOptions"); + MyListOptionsOptionsValidator sourceGenOptionsValidator2 = new(); + + var options2 = new MyListOptions() { Prop = "test" }; + result1 = sourceGenOptionsValidator2.Validate("MyListOptions", options2); + result2 = dataAnnotationValidateOptions2.Validate("MyListOptions", options2); + + Assert.True(result1.Succeeded); + Assert.True(result2.Succeeded); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] public void TestValidationWithCyclicReferences() { @@ -302,6 +326,12 @@ public partial class MySourceGenOptionsValidator : IValidateOptions { } + public class MyDictionaryOptions : Dictionary { [Required] public string Prop { get; set; } = "test"; } + [OptionsValidator] public partial class MyDictionaryOptionsOptionsValidator : IValidateOptions { } + + public class MyListOptions : List { [Required] public T Prop { get; set; } = default; } + [OptionsValidator] public partial class MyListOptionsOptionsValidator : IValidateOptions> { } + #if NET8_0_OR_GREATER public class OptionsUsingNewAttributes { From f6489fe1d785747308433213b4558171c63eef30 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 23:12:03 -0700 Subject: [PATCH 284/783] JIT: add missing xarch RMW case (#92293) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handle the case where we're indirectly updating a local with a value that is not a constant. Fixes #92218. Co-authored-by: Andy Ayers Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- src/coreclr/jit/emitxarch.cpp | 7 ++++ .../JitBlue/Runtime_92218/Runtime_92218.cs | 40 +++++++++++++++++++ .../Runtime_92218/Runtime_92218.csproj | 8 ++++ 3 files changed, 55 insertions(+) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.csproj diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 980d40a47ac318..1c48d1c52f0bb2 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -5485,6 +5485,13 @@ void emitter::emitInsRMW(instruction ins, emitAttr attr, GenTreeStoreInd* storeI { assert(!src->isContained()); // there must be one non-contained src + if (addr->isContained() && addr->OperIs(GT_LCL_ADDR)) + { + GenTreeLclVarCommon* lclVar = addr->AsLclVarCommon(); + emitIns_S_R(ins, attr, src->GetRegNum(), lclVar->GetLclNum(), lclVar->GetLclOffs()); + return; + } + // ind, reg id = emitNewInstrAmd(attr, offset); emitHandleMemOp(storeInd, id, emitInsModeFormat(ins, IF_ARD_RRD), ins); diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.cs b/src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.cs new file mode 100644 index 00000000000000..9b4696e31fc16c --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Threading; +using Xunit; + +public struct MutableStruct +{ + private long _internalValue; + + public long InternalValue + { + get => Volatile.Read(ref _internalValue); + private set => Volatile.Write(ref _internalValue, value); + } + + public void Add(long value) => AddInternal(value); + private void AddInternal(long value) => InternalValue += value; + public MutableStruct(long value) => InternalValue = value; +} + +public static class Runtime_92218 +{ + [Fact] + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + public static void Problem() + { + var test = new MutableStruct(420); + var from = new MutableStruct(42); + + var wrapper = -new TimeSpan(3); + + while (test.InternalValue >= from.InternalValue) + { + test.Add(wrapper.Ticks); + } + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_92218/Runtime_92218.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From 09429dc1204365c3c7de70233db5e7c4f13ce3b9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 23:12:45 -0700 Subject: [PATCH 285/783] Don't generate AddMask as it requires more explicit consideration of semantics (#92308) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tanner Gooding Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- src/coreclr/jit/morph.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 153f9b8bba8a82..3deada8eec085b 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -10807,8 +10807,6 @@ GenTree* Compiler::fgOptimizeHWIntrinsic(GenTreeHWIntrinsic* node) } #if defined(TARGET_XARCH) - case NI_AVX512F_Add: - case NI_AVX512BW_Add: case NI_AVX512F_And: case NI_AVX512DQ_And: case NI_AVX512F_AndNot: @@ -10850,13 +10848,6 @@ GenTree* Compiler::fgOptimizeHWIntrinsic(GenTreeHWIntrinsic* node) switch (intrinsicId) { - case NI_AVX512F_Add: - case NI_AVX512BW_Add: - { - maskIntrinsicId = NI_AVX512F_AddMask; - break; - } - case NI_AVX512F_And: case NI_AVX512DQ_And: { From eafb0d69da05c5cbe52bd7c6eca77e256c40d3f4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 08:10:18 -0700 Subject: [PATCH 286/783] [release/8.0-rc1] [release/8.0] Events for IL methods without IL headers (#92317) * Events for IL methods without IL headers Dynamically generated methods like UnsafeAccessor functions are marked as IL, but don't contain an IL header. The lack of header is an indication the IL must be generated at runtime. * Debugger check for no IL header * Update src/coreclr/debug/daccess/stack.cpp Co-authored-by: Tlakaelel Axayakatl Ceja * Review feedback * Remove redundent calls and another spot to check. * Move header include --------- Co-authored-by: Aaron R Robinson Co-authored-by: Tlakaelel Axayakatl Ceja --- src/coreclr/debug/daccess/stack.cpp | 9 +- src/coreclr/inc/eventtracebase.h | 6 +- src/coreclr/utilcode/stresslog.cpp | 2 +- src/coreclr/vm/eventtrace.cpp | 21 ++-- src/coreclr/vm/jitinterface.cpp | 2 +- src/coreclr/vm/method.hpp | 2 +- src/coreclr/vm/prestub.cpp | 116 ++++++++++---------- src/coreclr/vm/versionresilienthashcode.cpp | 8 +- 8 files changed, 90 insertions(+), 76 deletions(-) diff --git a/src/coreclr/debug/daccess/stack.cpp b/src/coreclr/debug/daccess/stack.cpp index 9402d529eb8ea3..6b9f1a491c291c 100644 --- a/src/coreclr/debug/daccess/stack.cpp +++ b/src/coreclr/debug/daccess/stack.cpp @@ -1253,14 +1253,19 @@ ClrDataFrame::GetLocalSig(MetaSig** sig, { // It turns out we cannot really get rid of this check. Dynamic methods // (including IL stubs) do not have their local sig's available after JIT time. - if (!m_methodDesc->IsIL()) + // IL methods with dynamically generated IL (for example, UnsafeAccessors) may + // not have an IL header. + COR_ILMETHOD* ilHeader = m_methodDesc->IsIL() + ? m_methodDesc->GetILHeader() + : NULL; + if (ilHeader == NULL) { *sig = NULL; *count = 0; return E_FAIL; } - COR_ILMETHOD_DECODER methodDecoder(m_methodDesc->GetILHeader()); + COR_ILMETHOD_DECODER methodDecoder(ilHeader); mdSignature localSig = methodDecoder.GetLocalVarSigTok() ? methodDecoder.GetLocalVarSigTok() : mdSignatureNil; if (localSig == mdSignatureNil) diff --git a/src/coreclr/inc/eventtracebase.h b/src/coreclr/inc/eventtracebase.h index 97c3135153038c..3648b1f3a72136 100644 --- a/src/coreclr/inc/eventtracebase.h +++ b/src/coreclr/inc/eventtracebase.h @@ -905,7 +905,7 @@ namespace ETW BOOL fSendRichDebugInfoEvent, BOOL fGetCodeIds); static VOID SendEventsForNgenMethods(Module *pModule, DWORD dwEventOptions); - static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL); + static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL); static VOID SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWORD dwEventOptions, PCODE pNativeCodeStartAddress, DWORD nativeCodeId, ReJITID ilCodeId); static VOID SendMethodRichDebugInfo(MethodDesc * pMethodDesc, PCODE pNativeCodeStartAddress, DWORD nativeCodeId, ReJITID ilCodeId, MethodDescSet* sentMethodDetailsSet); static VOID SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptions, BOOL bIsJit, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, PCODE pNativeCodeStartAddress = 0, PrepareCodeConfig *pConfig = NULL, MethodDescSet* sentMethodDetailsSet = NULL); @@ -938,7 +938,7 @@ namespace ETW static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc); static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint); - static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature); + static VOID MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature); static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig); static VOID SendMethodDetailsEvent(MethodDesc *pMethodDesc); static VOID SendNonDuplicateMethodDetailsEvent(MethodDesc* pMethodDesc, MethodDescSet* set); @@ -952,7 +952,7 @@ namespace ETW public: static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc) {}; static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint) {}; - static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature); + static VOID MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature); static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig); static VOID StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName) {}; static VOID StubsInitialized(PVOID *pHelperStartAddress, PVOID *pHelperNames, LONG ulNoOfHelpers) {}; diff --git a/src/coreclr/utilcode/stresslog.cpp b/src/coreclr/utilcode/stresslog.cpp index c55c5afe9249c8..90ad5900473ed7 100644 --- a/src/coreclr/utilcode/stresslog.cpp +++ b/src/coreclr/utilcode/stresslog.cpp @@ -12,9 +12,9 @@ #include "switches.h" #include "stresslog.h" #include "clrhost.h" +#include "ex.h" #define DONOT_DEFINE_ETW_CALLBACK #include "eventtracebase.h" -#include "ex.h" #if !defined(STRESS_LOG_READONLY) #ifdef HOST_WINDOWS diff --git a/src/coreclr/vm/eventtrace.cpp b/src/coreclr/vm/eventtrace.cpp index b9a82cfb7c28e9..9498f00edf4329 100644 --- a/src/coreclr/vm/eventtrace.cpp +++ b/src/coreclr/vm/eventtrace.cpp @@ -3555,7 +3555,7 @@ VOID ETW::MethodLog::MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrC /*************************************************/ /* This is called by the runtime when method jitting started */ /*************************************************/ -VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature) +VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature) { CONTRACTL { NOTHROW; @@ -3570,7 +3570,7 @@ VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOr CLR_JIT_KEYWORD)) { pMethodDesc->GetMethodInfo(*namespaceOrClassName, *methodName, *methodSignature); - ETW::MethodLog::SendMethodJitStartEvent(pMethodDesc, namespaceOrClassName, methodName, methodSignature); + ETW::MethodLog::SendMethodJitStartEvent(pMethodDesc, methodDecoder, namespaceOrClassName, methodName, methodSignature); } } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions); } @@ -4528,7 +4528,12 @@ VOID ETW::MethodLog::SendNonDuplicateMethodDetailsEvent(MethodDesc* pMethodDesc, /*****************************************************************/ /* This routine is used to send an ETW event just before a method starts jitting*/ /*****************************************************************/ -VOID ETW::MethodLog::SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature) +VOID ETW::MethodLog::SendMethodJitStartEvent( + MethodDesc *pMethodDesc, + COR_ILMETHOD_DECODER* methodDecoder, + SString *namespaceOrClassName, + SString *methodName, + SString *methodSignature) { CONTRACTL { THROWS; @@ -4566,15 +4571,13 @@ VOID ETW::MethodLog::SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *n ulMethodToken = (ULONG)0; } else - ulMethodToken = (ULONG)pMethodDesc->GetMemberDef(); - - if(pMethodDesc->IsIL()) { - COR_ILMETHOD_DECODER::DecoderStatus decoderstatus = COR_ILMETHOD_DECODER::FORMAT_ERROR; - COR_ILMETHOD_DECODER ILHeader(pMethodDesc->GetILHeader(), pMethodDesc->GetMDImport(), &decoderstatus); - ulMethodILSize = (ULONG)ILHeader.GetCodeSize(); + ulMethodToken = (ULONG)pMethodDesc->GetMemberDef(); } + if (methodDecoder != NULL) + ulMethodILSize = methodDecoder->GetCodeSize(); + SString tNamespace, tMethodName, tMethodSignature; if(!namespaceOrClassName|| !methodName|| !methodSignature || (methodName->IsEmpty() && namespaceOrClassName->IsEmpty() && methodSignature->IsEmpty())) { diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 1a3439bdd235ef..74ee2f7482e747 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -12286,7 +12286,7 @@ static CorJitResult CompileMethodWithEtwWrapper(EEJitManager *jitMgr, SString namespaceOrClassName, methodName, methodSignature; // Fire an ETW event to mark the beginning of JIT'ing - ETW::MethodLog::MethodJitting(reinterpret_cast(info->ftn), &namespaceOrClassName, &methodName, &methodSignature); + ETW::MethodLog::MethodJitting(reinterpret_cast(info->ftn), NULL, &namespaceOrClassName, &methodName, &methodSignature); CorJitResult ret = jitMgr->m_jit->compileMethod(comp, info, flags, nativeEntry, nativeSizeOfCode); diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index 4b34045b57671e..e51d9f7453d35e 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -1819,7 +1819,7 @@ class MethodDesc PCODE GetMulticoreJitCode(PrepareCodeConfig* pConfig, bool* pWasTier0); PCODE JitCompileCode(PrepareCodeConfig* pConfig); PCODE JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry); - PCODE JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEntry* pLockEntry, ULONG* pSizeOfCode); + PCODE JitCompileCodeLocked(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pilHeader, JitListLockEntry* pLockEntry, ULONG* pSizeOfCode); public: bool TryGenerateUnsafeAccessor(DynamicResolver** resolver, COR_ILMETHOD_DECODER** methodILDecoder); diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp index 174e48565f31b8..32944952301648 100644 --- a/src/coreclr/vm/prestub.cpp +++ b/src/coreclr/vm/prestub.cpp @@ -709,6 +709,53 @@ PCODE MethodDesc::JitCompileCode(PrepareCodeConfig* pConfig) } } +namespace +{ + COR_ILMETHOD_DECODER* GetAndVerifyMetadataILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pDecoderMemory) + { + STANDARD_VM_CONTRACT; + _ASSERTE(pMD != NULL); + _ASSERTE(!pMD->IsNoMetadata()); + _ASSERTE(pConfig != NULL); + _ASSERTE(pDecoderMemory != NULL); + + COR_ILMETHOD_DECODER* pHeader = NULL; + COR_ILMETHOD* ilHeader = pConfig->GetILHeader(); + if (ilHeader == NULL) + return NULL; + + COR_ILMETHOD_DECODER::DecoderStatus status = COR_ILMETHOD_DECODER::FORMAT_ERROR; + { + // Decoder ctor can AV on a malformed method header + AVInRuntimeImplOkayHolder AVOkay; + pHeader = new (pDecoderMemory) COR_ILMETHOD_DECODER(ilHeader, pMD->GetMDImport(), &status); + } + + if (status == COR_ILMETHOD_DECODER::FORMAT_ERROR) + COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL); + + return pHeader; + } + + COR_ILMETHOD_DECODER* GetAndVerifyILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory) + { + STANDARD_VM_CONTRACT; + _ASSERTE(pMD != NULL); + if (pMD->IsIL()) + { + return GetAndVerifyMetadataILHeader(pMD, pConfig, pIlDecoderMemory); + } + else if (pMD->IsILStub()) + { + ILStubResolver* pResolver = pMD->AsDynamicMethodDesc()->GetILStubResolver(); + return pResolver->GetILHeader(); + } + + _ASSERTE(pMD->IsNoMetadata()); + return NULL; + } +} + PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry) { STANDARD_VM_CONTRACT; @@ -759,11 +806,18 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J } #endif // PROFILING_SUPPORTED + // The profiler may have changed the code on the callback. Need to + // pick up the new code. + // + // (don't want this for OSR, need to see how it works) + COR_ILMETHOD_DECODER ilDecoderTemp; + COR_ILMETHOD_DECODER* pilHeader = GetAndVerifyILHeader(this, pConfig, &ilDecoderTemp); + if (!ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context, TRACE_LEVEL_VERBOSE, CLR_JIT_KEYWORD)) { - pCode = JitCompileCodeLocked(pConfig, pEntry, &sizeOfCode); + pCode = JitCompileCodeLocked(pConfig, pilHeader, pEntry, &sizeOfCode); } else { @@ -778,12 +832,13 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J // a small stub of native code but no native-IL mapping. #ifndef FEATURE_INTERPRETER ETW::MethodLog::MethodJitting(this, + pilHeader, &namespaceOrClassName, &methodName, &methodSignature); #endif - pCode = JitCompileCodeLocked(pConfig, pEntry, &sizeOfCode); + pCode = JitCompileCodeLocked(pConfig, pilHeader, pEntry, &sizeOfCode); // Interpretted methods skip this notification #ifdef FEATURE_INTERPRETER @@ -869,66 +924,11 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J return pCode; } -namespace -{ - COR_ILMETHOD_DECODER* GetAndVerifyMetadataILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pDecoderMemory) - { - STANDARD_VM_CONTRACT; - _ASSERTE(pMD != NULL); - _ASSERTE(!pMD->IsNoMetadata()); - _ASSERTE(pConfig != NULL); - _ASSERTE(pDecoderMemory != NULL); - - COR_ILMETHOD_DECODER* pHeader = NULL; - COR_ILMETHOD* ilHeader = pConfig->GetILHeader(); - if (ilHeader == NULL) - return NULL; - - COR_ILMETHOD_DECODER::DecoderStatus status = COR_ILMETHOD_DECODER::FORMAT_ERROR; - { - // Decoder ctor can AV on a malformed method header - AVInRuntimeImplOkayHolder AVOkay; - pHeader = new (pDecoderMemory) COR_ILMETHOD_DECODER(ilHeader, pMD->GetMDImport(), &status); - } - - if (status == COR_ILMETHOD_DECODER::FORMAT_ERROR) - COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL); - - return pHeader; - } - - COR_ILMETHOD_DECODER* GetAndVerifyILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory) - { - STANDARD_VM_CONTRACT; - _ASSERTE(pMD != NULL); - if (pMD->IsIL()) - { - return GetAndVerifyMetadataILHeader(pMD, pConfig, pIlDecoderMemory); - } - else if (pMD->IsILStub()) - { - ILStubResolver* pResolver = pMD->AsDynamicMethodDesc()->GetILStubResolver(); - return pResolver->GetILHeader(); - } - - _ASSERTE(pMD->IsNoMetadata()); - return NULL; - } -} - -PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry, ULONG* pSizeOfCode) +PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pilHeader, JitListLockEntry* pEntry, ULONG* pSizeOfCode) { STANDARD_VM_CONTRACT; PCODE pCode = NULL; - - // The profiler may have changed the code on the callback. Need to - // pick up the new code. - // - // (don't want this for OSR, need to see how it works) - COR_ILMETHOD_DECODER ilDecoderTemp; - COR_ILMETHOD_DECODER* pilHeader = GetAndVerifyILHeader(this, pConfig, &ilDecoderTemp); - CORJIT_FLAGS jitFlags; PCODE pOtherCode = NULL; diff --git a/src/coreclr/vm/versionresilienthashcode.cpp b/src/coreclr/vm/versionresilienthashcode.cpp index b3ba764baac595..85bd146d8dc463 100644 --- a/src/coreclr/vm/versionresilienthashcode.cpp +++ b/src/coreclr/vm/versionresilienthashcode.cpp @@ -286,7 +286,7 @@ bool AddVersionResilientHashCodeForInstruction(ILInstructionParser *parser, xxHa hash->Add(varValue); break; } - + case InlineVar: // 2 byte value which is token change resilient { uint16_t varValue; @@ -388,6 +388,12 @@ bool GetVersionResilientILCodeHashCode(MethodDesc *pMD, int* hashCode, unsigned* initLocals = (options & CORINFO_OPT_INIT_LOCALS) == CORINFO_OPT_INIT_LOCALS; } + else if (!pMD->HasILHeader()) + { + // Dynamically generated IL methods like UnsafeAccessors may not have + // an IL header. + return false; + } else { COR_ILMETHOD_DECODER header(pMD->GetILHeader(TRUE), pMD->GetMDImport(), NULL); From b0b595f388377c351ca980707424b2c66ed9ca2c Mon Sep 17 00:00:00 2001 From: Maoni Stephens Date: Wed, 20 Sep 2023 09:25:14 -0700 Subject: [PATCH 287/783] [release/8.0-rc2] porting DATAS change back to RC2 (#92323) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * new synchronization mechanism for DATAS (#90726) The current mechanism has a fundamental flaw which is the idling threads can start running at unpredictable times when they are woken up. This causes all sorts of problems. For example, when a thread gets here in gc_thread_function - `if (n_heaps <= heap_number)` if it's true it's supposed to wait. But its execution could be delayed so after it reads n_heaps it can stop for a while since no thread is waiting on this thread anyway... till some time later when a heap count changes happens again and it requires this thread to participating. And now this thread does the comparison and discovers that it needs to wait so it goes idle and all other threads will just be waiting for this thread to join. Another example is it's not safe to change the heap count for a join from a larger one to a smaller one. It's fine to change from a smaller one to a larger one because all the threads participating will have to run in order for a join to finish. But if no one is waiting on a thread, it could just wake up from the event being set by the last thread joining and not run for a while. Then go back to the respin loop at a point where the color was changed and changed again! So now it thinks it can proceed with a join it does not belong to. And of course that wouldn't work. The way threads are going idle/waking up is hard to keep track of - not only does it involve the gc_start_event and gc_idle_thread_event, it also uses WaitForGCEvent which is used by SuspendEE/RestartEE which in turn means whenever we want to call these we'd need to care about how that would affect this. The new mechanism only uses gc_start_event and gc_idle_thread_event, but I changed gc_idle_thread_event to a per heap event. We can easily track which threads are going idling easily - whenever a thread is about to wait on the idle event, we increase the current idle_thread_count. And when we increase the heap count we only set the gc_idle_thread_event for the new heaps that are about to participate so we can deduct that many from idle_thread_count. There's a much simpler code path between "we know we don't need these threads anymore" to "these threads are at a known point" because the next time gc_start_event is set (ie, a GC is requested) we make sure to get these threads to a good known point, ie, we wait till all of them have completed increasing idle_thread_count. Also fixed a couple of other problems that I hit while testing the new mechanism - We are setting freeable_uoh_segment and freeable_soh_segment in decommission_heap to DECOMMISSIONED_REGION_P. And this causes us to simply lose the value for them. We should make sure we do push these to the free regions before we start changing the heap count. We should also call background_delay_delete_uoh_segments before we start changing the heap count so we can get rid of the regions marked with heap_segment_flags_uoh_delete. If we allow these to be rearranged in equalize_promoted_bytes it means the order can change the invariant of the first region never being deleted no longer holds true and we can AV in this method. I added an new method delay_free_segments to perform both tasks. The accounting of generation_free_list_space is slightly off for LOH which causes us to hit assert (gen_size >= dd_fragmentation (dd)); in change_heap_count because we were not counting the loh_pad size. I also disabled assert (free_list_space_decrease <= dd_fragmentation (dd)); for gen2 since I'm seeing this fired while I'm doing stress runs. I have yet to investigate this since I didn't want to add yet more changes to this PR. * fixed problems with how sampling is done and how we suspend to change heap count in DATAS (#91712) + Moved the sample recording into when we are suspended. The way we were calculating the throughput cost was in check_heap_count (which is called right after we restart EE on heap0), we record the msl_wait_time (and reset it to 0 for soh/uoh). This is not synchronized with the allocating threads (which are already running at this point). So what can happen is the allocating threads are already accumulated more wait time which is attributed to this GC but it's not within the period we are counting for this GC (and we lose this part for the next GC). For BGC this is incorrect. If an ephemeral GC did happen before the BGC starts, we'd be adding a sample for that GC which is basically correct for that eph GC. But if an eph GC did not happen, we are just adding a random sample which is calculating the tcp as (msl wait + whatever GC that was finished before this BGC) so obviously incorrect. + Added gen2 sampling - this was adapted from Peter's gen2 sampling changes. This serves as a backstop in case the existing sampling doesn't ever pick gen2 GC costs. I made the following fixes - 1) changed the way we calculated the median 2) moved where this is calculated to again avoid timing issues 3) made the gen2 samples actually count instead of losing that info if we happen to sample when a gen2 didn't just occur. + Changed when check_heap_count is called - the previous place is right after a suspension which does not help with spacing the suspension time out (it was "suspend for GC" then "immediately suspend to change heap count"). And it caused a problem with BGC which was it always tried to change heap count when it couldn't because BGC was in progress. I changed this to be on a timeout to intentionally space the suspensions out. Now most of the time, heap count changes happen due to this time out. If we are really in a situation where GCs are happening too quickly and we return from waiting on the ee_suspend_event due to a GC started, we change the heap count right before we do a GC. So this also helps with the BGC problem. * gen0_bricks_cleared flag needs to be propagated when we change heap count (#90457) when we change the heap count, in heap X we get a region from heap Y and the gen0_bricks_cleared flag from Y says false but heap X says true. So when we check the bricks on heap X, we assume it’s true but it’s not. the fix is to detect if any heap has this flag as false and if so make all heaps’ flag false (tracking which region is moved from which other heap is something we need additional recording for and it’s not really worth doing just for this) * a logging change --------- Co-authored-by: Maoni0 --- src/coreclr/gc/gc.cpp | 1001 +++++++++++++++++++++++++------------ src/coreclr/gc/gcconfig.h | 1 + src/coreclr/gc/gcpriv.h | 93 +++- 3 files changed, 746 insertions(+), 349 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index daeadfe9821b8c..7351954070725e 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -823,6 +823,11 @@ class t_join join_struct.r_join_lock = n_th; } + int get_num_threads() + { + return join_struct.n_threads; + } + void destroy () { dprintf (JOIN_LOG, ("Destroying join structure")); @@ -887,6 +892,8 @@ class t_join // avoid race due to the thread about to reset the event (occasionally) being preempted before ResetEvent() if (color == join_struct.lock_color.LoadWithoutBarrier()) { + dprintf (9999, ("---h%d %d j%d %d - respin!!! (c:%d-%d)", + gch->heap_number, join_id, join_struct.n_threads, color, join_struct.lock_color.LoadWithoutBarrier())); goto respin; } @@ -1117,6 +1124,25 @@ t_join bgc_t_join; } \ } +#define spin_and_wait(count_to_spin, expr) \ +{ \ + while (!expr) \ + { \ + for (int j = 0; j < count_to_spin; j++) \ + { \ + if (expr) \ + { \ + break; \ + } \ + YieldProcessor (); \ + } \ + if (!(expr)) \ + { \ + GCToOSInterface::YieldThread (0); \ + } \ + } \ +} + #ifdef BACKGROUND_GC #define max_pending_allocs 64 @@ -1429,8 +1455,6 @@ enter_msl_status gc_heap::enter_spin_lock_msl_helper (GCSpinLock* msl) { #ifdef DYNAMIC_HEAP_COUNT uint64_t start = GetHighPrecisionTimeStamp(); - - msl->msl_wait_count++; #endif //DYNAMIC_HEAP_COUNT unsigned int i = 0; @@ -1485,7 +1509,7 @@ enter_msl_status gc_heap::enter_spin_lock_msl_helper (GCSpinLock* msl) #ifdef DYNAMIC_HEAP_COUNT uint64_t end = GetHighPrecisionTimeStamp(); Interlocked::ExchangeAdd64 (&msl->msl_wait_time, end - start); - dprintf (6666, ("wait for msl lock total time: %zd, total count: %zd, this time: %zd, this count: %u", msl->msl_wait_time, msl->msl_wait_count, end - start, i)); + dprintf (3, ("h%d wait for msl lock wait time %zd, total wait time: %zd", heap_number, (end - start), msl->msl_wait_time)); #endif //DYNAMIC_HEAP_COUNT } while (Interlocked::CompareExchange (&msl->lock, lock_taken, lock_free) != lock_free); @@ -2318,9 +2342,6 @@ sorted_table* gc_heap::seg_table; #ifdef MULTIPLE_HEAPS GCEvent gc_heap::ee_suspend_event; -#ifdef DYNAMIC_HEAP_COUNT -GCEvent gc_heap::gc_idle_thread_event; -#endif //DYNAMIC_HEAP_COUNT size_t gc_heap::min_gen0_balance_delta = 0; size_t gc_heap::min_balance_threshold = 0; #endif //MULTIPLE_HEAPS @@ -2919,6 +2940,12 @@ BOOL gc_heap::should_expand_in_full_gc = FALSE; #ifdef DYNAMIC_HEAP_COUNT int gc_heap::dynamic_adaptation_mode = dynamic_adaptation_default; gc_heap::dynamic_heap_count_data_t SVR::gc_heap::dynamic_heap_count_data; +uint64_t gc_heap::last_suspended_end_time = 0; +size_t gc_heap::gc_index_full_gc_end = 0; + +#ifdef STRESS_DYNAMIC_HEAP_COUNT +int gc_heap::heaps_in_this_gc = 0; +#endif //STRESS_DYNAMIC_HEAP_COUNT #endif // DYNAMIC_HEAP_COUNT // Provisional mode related stuff. @@ -6967,12 +6994,6 @@ BOOL gc_heap::create_thread_support (int number_of_heaps) { goto cleanup; } -#ifdef DYNAMIC_HEAP_COUNT - if (!gc_idle_thread_event.CreateOSManualEventNoThrow (FALSE)) - { - goto cleanup; - } -#endif //DYNAMIC_HEAP_COUNT if (!ee_suspend_event.CreateOSAutoEventNoThrow (FALSE)) { goto cleanup; @@ -7020,10 +7041,6 @@ bool gc_heap::create_gc_thread () return GCToEEInterface::CreateThread(gc_thread_stub, this, false, ".NET Server GC"); } -#ifdef DYNAMIC_HEAP_COUNT -static size_t prev_change_heap_count_gc_index; -#endif //DYNAMIC_HEAP_COUNT - #ifdef _MSC_VER #pragma warning(disable:4715) //IA64 xcompiler recognizes that without the 'break;' the while(1) will never end and therefore not return a value for that code path #endif //_MSC_VER @@ -7042,18 +7059,87 @@ void gc_heap::gc_thread_function () if (heap_number == 0) { - uint32_t wait_result = gc_heap::ee_suspend_event.Wait(gradual_decommit_in_progress_p ? DECOMMIT_TIME_STEP_MILLISECONDS : INFINITE, FALSE); + bool wait_on_time_out_p = gradual_decommit_in_progress_p; + uint32_t wait_time = DECOMMIT_TIME_STEP_MILLISECONDS; +#ifdef DYNAMIC_HEAP_COUNT + // background_running_p can only change from false to true during suspension. + if (!gc_heap::background_running_p () && dynamic_heap_count_data.should_change_heap_count) + { + assert (dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes); + + dynamic_heap_count_data_t::sample& sample = dynamic_heap_count_data.samples[dynamic_heap_count_data.sample_index]; + wait_time = min (wait_time, (uint32_t)(sample.elapsed_between_gcs / 1000 / 3)); + wait_time = max (wait_time, 1); + + dprintf (6666, ("gc#0 thread waiting for %d ms (betwen GCs %I64d)", wait_time, sample.elapsed_between_gcs)); + } +#endif //DYNAMIC_HEAP_COUNT + uint32_t wait_result = gc_heap::ee_suspend_event.Wait(wait_on_time_out_p ? wait_time : INFINITE, FALSE); + dprintf (9999, ("waiting for ee done res %d (timeout %d, %I64d ms since last suspend end)(should_change_heap_count is %d) (gradual_decommit_in_progress_p %d)", + wait_result, wait_time, ((GetHighPrecisionTimeStamp() - last_suspended_end_time) / 1000), + dynamic_heap_count_data.should_change_heap_count, gradual_decommit_in_progress_p)); if (wait_result == WAIT_TIMEOUT) { - decommit_lock.Enter(); - gradual_decommit_in_progress_p = decommit_step (DECOMMIT_TIME_STEP_MILLISECONDS); - decommit_lock.Leave(); +#ifdef DYNAMIC_HEAP_COUNT + if (dynamic_heap_count_data.should_change_heap_count) + { +#ifdef BACKGROUND_GC + if (!gc_heap::background_running_p ()) +#endif //BACKGROUND_GC + { + dprintf (6666, ("changing heap count due to timeout")); + check_heap_count(); + } + } +#endif //DYNAMIC_HEAP_COUNT + + if (gradual_decommit_in_progress_p) + { + decommit_lock.Enter (); + gradual_decommit_in_progress_p = decommit_step (DECOMMIT_TIME_STEP_MILLISECONDS); + decommit_lock.Leave (); + } continue; } +#ifdef DYNAMIC_HEAP_COUNT + // We might want to consider also doing this when a BGC finishes. + if (dynamic_heap_count_data.should_change_heap_count) + { +#ifdef BACKGROUND_GC + if (!gc_heap::background_running_p ()) +#endif //BACKGROUND_GC + { + // this was a request to do a GC so make sure we follow through with one. + dprintf (6666, ("changing heap count at a GC start")); + check_heap_count (); + } + } + + // wait till the threads that should have gone idle at least reached the place where they are about to wait on the idle event. + if ((gc_heap::dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes) && + (n_heaps != dynamic_heap_count_data.last_n_heaps)) + { + int spin_count = 1024; + int idle_thread_count = n_max_heaps - n_heaps; + dprintf (9999, ("heap count changed %d->%d, idle should be %d and is %d", dynamic_heap_count_data.last_n_heaps, n_heaps, + idle_thread_count, VolatileLoadWithoutBarrier (&dynamic_heap_count_data.idle_thread_count))); + if (idle_thread_count != dynamic_heap_count_data.idle_thread_count) + { + spin_and_wait (spin_count, (idle_thread_count == dynamic_heap_count_data.idle_thread_count)); + dprintf (9999, ("heap count changed %d->%d, now idle is %d", dynamic_heap_count_data.last_n_heaps, n_heaps, + VolatileLoadWithoutBarrier (&dynamic_heap_count_data.idle_thread_count))); + } + + dynamic_heap_count_data.last_n_heaps = n_heaps; + } +#endif //DYNAMIC_HEAP_COUNT + suspended_start_time = GetHighPrecisionTimeStamp(); BEGIN_TIMING(suspend_ee_during_log); + dprintf (9999, ("h0 suspending EE in GC!")); GCToEEInterface::SuspendEE(SUSPEND_FOR_GC); + dprintf (9999, ("h0 suspended EE in GC!")); END_TIMING(suspend_ee_during_log); proceed_with_gc_p = TRUE; @@ -7067,46 +7153,74 @@ void gc_heap::gc_thread_function () { settings.init_mechanisms(); #ifdef DYNAMIC_HEAP_COUNT - // make sure the other gc threads cannot see this as a request to change heap count - // see explanation below about the cases when we return from gc_start_event.Wait - assert (dynamic_heap_count_data.new_n_heaps == n_heaps); + if (gc_heap::dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes) + { + // make sure the other gc threads cannot see this as a request to change heap count + // see explanation below about the cases when we return from gc_start_event.Wait + assert (dynamic_heap_count_data.new_n_heaps == n_heaps); + } #endif //DYNAMIC_HEAP_COUNT + dprintf (9999, ("GC thread %d setting_gc_start_in_gc(h%d)", heap_number, n_heaps)); gc_start_event.Set(); } dprintf (3, (ThreadStressLog::gcServerThread0StartMsg(), heap_number)); } else { + dprintf (9999, ("GC thread %d waiting_for_gc_start(%d)(gc%Id)", heap_number, n_heaps, VolatileLoadWithoutBarrier(&settings.gc_index))); gc_start_event.Wait(INFINITE, FALSE); #ifdef DYNAMIC_HEAP_COUNT - // we have a couple different cases to handle here when we come back from the wait: - // 1. We are starting a GC. Signaled by dynamic_heap_count_data.new_n_heaps == n_heaps - // a) We are starting a GC, but this thread is idle. Signaled by n_heaps <= heap_number - // b) We are starting a GC, and this thread is participating. Signaled by heap_number < n_heaps - // 2. We are changing heap count. Signaled by dynamic_heap_count_data.new_n_heaps != n_heaps - // a) We are changing heap count, but this thread is idle. Signaled by n_heaps <= heap_number. - // b) We are changing heap count, and this thread is participating. Signaled by heap_number < n_heaps. - - // check for 1.a) and 2.a) cases above - if (n_heaps <= heap_number) - { - dprintf (2, ("GC thread %d idle", heap_number)); - - // make sure GC is complete so we know the gc_idle_thread_event has been reset - g_theGCHeap->WaitUntilGCComplete(); + dprintf (9999, ("GC thread %d waiting_done_gc_start(%d-%d)(i: %d)(gc%Id)", + heap_number, n_heaps, dynamic_heap_count_data.new_n_heaps, dynamic_heap_count_data.init_only_p, VolatileLoadWithoutBarrier (&settings.gc_index))); + + if ((gc_heap::dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes) && + (dynamic_heap_count_data.new_n_heaps != n_heaps)) + { + // The reason why we need to do this is - + // + for threads that were participating, we need them to do work for change_heap_count + // + for threads that were not participating but will need to participate, we need to make sure they are woken now instead of + // randomly sometime later. + int old_n_heaps = n_heaps; + int new_n_heaps = dynamic_heap_count_data.new_n_heaps; + int num_threads_to_wake = max (new_n_heaps, old_n_heaps); + if (heap_number < num_threads_to_wake) + { + dprintf (9999, ("h%d < %d, calling change", heap_number, num_threads_to_wake)); + change_heap_count (dynamic_heap_count_data.new_n_heaps); + if (new_n_heaps < old_n_heaps) + { + dprintf (9999, ("h%d after change", heap_number)); + // at the end of change_heap_count we've changed join's heap count to the new one if it's smaller. So we need to make sure + // only that many threads will participate in the following GCs. + if (heap_number < new_n_heaps) + { + dprintf (9999, ("h%d < %d participating (dec)", heap_number, new_n_heaps)); + } + else + { + Interlocked::Increment (&dynamic_heap_count_data.idle_thread_count); + dprintf (9999, ("GC thread %d wait_on_idle(%d < %d)(gc%Id), total idle %d", heap_number, old_n_heaps, new_n_heaps, + VolatileLoadWithoutBarrier (&settings.gc_index), VolatileLoadWithoutBarrier (&dynamic_heap_count_data.idle_thread_count))); + gc_idle_thread_event.Wait (INFINITE, FALSE); + dprintf (9999, ("GC thread %d waking_from_idle(%d)(gc%Id) after doing change", heap_number, n_heaps, VolatileLoadWithoutBarrier (&settings.gc_index))); + } + } + else + { + dprintf (9999, ("h%d < %d participating (inc)", heap_number, new_n_heaps)); + } + } + else + { + Interlocked::Increment (&dynamic_heap_count_data.idle_thread_count); + dprintf (9999, ("GC thread %d wait_on_idle(< max %d)(gc%Id), total idle %d", heap_number, num_threads_to_wake, + VolatileLoadWithoutBarrier (&settings.gc_index), VolatileLoadWithoutBarrier (&dynamic_heap_count_data.idle_thread_count))); + gc_idle_thread_event.Wait (INFINITE, FALSE); + dprintf (9999, ("GC thread %d waking_from_idle(%d)(gc%Id)", heap_number, n_heaps, VolatileLoadWithoutBarrier (&settings.gc_index))); + } - // now wait on the gc_idle_thread_event - gc_idle_thread_event.Wait(INFINITE, FALSE); - dprintf (2, ("GC thread %d waking from idle", heap_number)); - continue; - } - // case 2.b) above: is this a request to change heap count? - if (dynamic_heap_count_data.new_n_heaps != n_heaps) - { - change_heap_count (dynamic_heap_count_data.new_n_heaps); continue; } - // case 1.b) above: we're starting a GC. #endif //DYNAMIC_HEAP_COUNT dprintf (3, (ThreadStressLog::gcServerThreadNStartMsg(), heap_number)); } @@ -7191,10 +7305,6 @@ void gc_heap::gc_thread_function () { gradual_decommit_in_progress_p = decommit_step (DECOMMIT_TIME_STEP_MILLISECONDS); } -#ifdef DYNAMIC_HEAP_COUNT - // check if we should adjust the number of heaps - check_heap_count(); -#endif //DYNAMIC_HEAP_COUNT } else { @@ -12527,6 +12637,16 @@ void gc_heap::rearrange_uoh_segments() freeable_uoh_segment = 0; } +void gc_heap::delay_free_segments() +{ + rearrange_uoh_segments(); +#ifdef BACKGROUND_GC + background_delay_delete_uoh_segments(); + if (!gc_heap::background_running_p()) + rearrange_small_heap_segments(); +#endif //BACKGROUND_GC +} + #ifndef USE_REGIONS void gc_heap::rearrange_heap_segments(BOOL compacting) { @@ -14860,6 +14980,25 @@ gc_heap::init_gc_heap (int h_number) gc_done_event_lock = -1; gc_done_event_set = false; +#ifdef DYNAMIC_HEAP_COUNT + if (h_number != 0) + { + if (!gc_idle_thread_event.CreateAutoEventNoThrow (FALSE)) + { + return 0; + } + +#ifdef BACKGROUND_GC + if (!bgc_idle_thread_event.CreateAutoEventNoThrow (FALSE)) + { + return 0; + } +#endif //BACKGROUND_GC + + dprintf (9999, ("creating idle events for h%d", h_number)); + } +#endif //DYNAMIC_HEAP_COUNT + if (!init_dynamic_data()) { return 0; @@ -16038,7 +16177,6 @@ void min_fl_list_info::thread_item_no_prev (uint8_t* item) tail = item; } -// This is only implemented for gen2 right now!!!! // the min_fl_list array is arranged as chunks of n_heaps min_fl_list_info, the 1st chunk corresponds to the 1st bucket, // and so on. void allocator::rethread_items (size_t* num_total_fl_items, size_t* num_total_fl_items_rethreaded, gc_heap* current_heap, @@ -17406,6 +17544,7 @@ BOOL gc_heap::a_fit_free_list_uoh_p (size_t size, gen_number, align_const); dd_new_allocation (dynamic_data_of (gen_number)) -= limit; + size_t saved_free_list_size = free_list_size; #ifdef FEATURE_LOH_COMPACTION if (loh_pad) { @@ -17434,7 +17573,7 @@ BOOL gc_heap::a_fit_free_list_uoh_p (size_t size, { generation_free_obj_space (gen) += remain_size; } - generation_free_list_space (gen) -= free_list_size; + generation_free_list_space (gen) -= saved_free_list_size; assert ((ptrdiff_t)generation_free_list_space (gen) >= 0); generation_free_list_allocated (gen) += limit; @@ -22000,11 +22139,70 @@ BOOL gc_heap::should_proceed_with_gc() void gc_heap::update_end_gc_time_per_heap() { +#ifdef DYNAMIC_HEAP_COUNT + size_t prev_gen2_end_time = 0; + if ((heap_number == 0) && (dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes) && (settings.condemned_generation == max_generation)) + { + dynamic_data* dd = dynamic_data_of (max_generation); + prev_gen2_end_time = dd_previous_time_clock (dd) + dd_gc_elapsed_time (dd);; + } +#endif //DYNAMIC_HEAP_COUNT + for (int gen_number = 0; gen_number <= settings.condemned_generation; gen_number++) { dynamic_data* dd = dynamic_data_of (gen_number); + + if (heap_number == 0) + { + dprintf (6666, ("prev gen%d GC end time: prev start %I64d + prev gc elapsed %Id = %I64d", + gen_number, dd_previous_time_clock (dd), dd_gc_elapsed_time (dd), (dd_previous_time_clock (dd) + dd_gc_elapsed_time (dd)))); + } + dd_gc_elapsed_time (dd) = (size_t)(end_gc_time - dd_time_clock (dd)); + + if (heap_number == 0) + { + dprintf (6666, ("updated NGC%d %Id elapsed time to %I64d - %I64d = %I64d", gen_number, dd_gc_clock (dd), end_gc_time, dd_time_clock (dd), dd_gc_elapsed_time (dd))); + } + } + +#ifdef DYNAMIC_HEAP_COUNT + if ((heap_number == 0) && (dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes)) + { + dynamic_heap_count_data_t::sample& sample = dynamic_heap_count_data.samples[dynamic_heap_count_data.sample_index]; + sample.elapsed_between_gcs = end_gc_time - last_suspended_end_time; + sample.gc_pause_time = dd_gc_elapsed_time (dynamic_data_of (0)); + sample.msl_wait_time = get_msl_wait_time(); + + dprintf (6666, ("sample#%d: this GC end %I64d - last sus end %I64d = %I64d, this GC pause %I64d, msl wait %I64d", + dynamic_heap_count_data.sample_index, end_gc_time, last_suspended_end_time, sample.elapsed_between_gcs, sample.gc_pause_time, sample.msl_wait_time)); + + last_suspended_end_time = end_gc_time; + + GCEventFireHeapCountSample_V1 ( + (uint64_t)VolatileLoadWithoutBarrier (&settings.gc_index), + sample.elapsed_between_gcs, + sample.gc_pause_time, + sample.msl_wait_time); + + dynamic_heap_count_data.sample_index = (dynamic_heap_count_data.sample_index + 1) % dynamic_heap_count_data_t::sample_size; + + if (settings.condemned_generation == max_generation) + { + gc_index_full_gc_end = dd_gc_clock (dynamic_data_of (0)); + size_t elapsed_between_gen2_gcs = end_gc_time - prev_gen2_end_time; + size_t gen2_elapsed_time = sample.gc_pause_time; + dynamic_heap_count_data.gen2_gc_percents[dynamic_heap_count_data.gen2_sample_index] = (float)gen2_elapsed_time * 100.0f / elapsed_between_gen2_gcs; + + dprintf (6666, ("gen2 sample#%d: this GC end %I64d - last gen2 end %I64d = %I64d, GC elapsed %I64d, percent %.3f", + dynamic_heap_count_data.gen2_sample_index, end_gc_time, prev_gen2_end_time, elapsed_between_gen2_gcs, + gen2_elapsed_time, dynamic_heap_count_data.gen2_gc_percents[dynamic_heap_count_data.gen2_sample_index])); + dynamic_heap_count_data.gen2_sample_index = (dynamic_heap_count_data.gen2_sample_index + 1) % dynamic_heap_count_data_t::sample_size; + } + + calculate_new_heap_count (); } +#endif //DYNAMIC_HEAP_COUNT } void gc_heap::update_end_ngc_time() @@ -22151,7 +22349,31 @@ void gc_heap::gc1() { dynamic_data* dd = dynamic_data_of (n); end_gc_time = GetHighPrecisionTimeStamp(); + size_t time_since_last_gen2 = 0; + +#ifdef DYNAMIC_HEAP_COUNT + if ((heap_number == 0) && (dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes)) + { + time_since_last_gen2 = (size_t)(end_gc_time - (dd_previous_time_clock (dd) + dd_gc_elapsed_time (dd))); + dprintf (6666, ("BGC %Id end %I64d - (prev gen2 start %I64d + elapsed %Id = %I64d) = time inbewteen gen2 %Id", + dd_gc_clock (dd), end_gc_time, dd_previous_time_clock (dd), dd_gc_elapsed_time (dd), (dd_previous_time_clock (dd) + dd_gc_elapsed_time (dd)), time_since_last_gen2)); + } +#endif //DYNAMIC_HEAP_COUNT + dd_gc_elapsed_time (dd) = (size_t)(end_gc_time - dd_time_clock (dd)); +#ifdef DYNAMIC_HEAP_COUNT + if ((heap_number == 0) && (dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes)) + { + dprintf (6666, ("updating BGC %Id elapsed time to %I64d - %I64d = %I64d", dd_gc_clock (dd), end_gc_time, dd_time_clock (dd), dd_gc_elapsed_time (dd))); + + float bgc_percent = (float)dd_gc_elapsed_time (dd) * 100.0f / (float)time_since_last_gen2; + dynamic_heap_count_data.gen2_gc_percents[dynamic_heap_count_data.gen2_sample_index] = bgc_percent; + dprintf (6666, ("gen2 sample %d elapsed %Id * 100 / time inbetween gen2 %Id = %.3f", + dynamic_heap_count_data.gen2_sample_index, dd_gc_elapsed_time (dd), time_since_last_gen2, bgc_percent)); + dynamic_heap_count_data.gen2_sample_index = (dynamic_heap_count_data.gen2_sample_index + 1) % dynamic_heap_count_data_t::sample_size; + gc_index_full_gc_end = dd_gc_clock (dynamic_data_of (0)); + } +#endif //DYNAMIC_HEAP_COUNT #ifdef HEAP_BALANCE_INSTRUMENTATION if (heap_number == 0) @@ -22758,7 +22980,12 @@ void gc_heap::merge_fl_from_other_heaps (int gen_idx, int to_n_heaps, int from_n assert (free_list_space_decrease <= generation_free_list_space (gen)); generation_free_list_space (gen) -= free_list_space_decrease; - assert (free_list_space_decrease <= dd_fragmentation (dd)); + // TODO - I'm seeing for gen2 this is free_list_space_decrease can be a bit larger than frag. + // Need to fix this later. + if (gen_idx != max_generation) + { + assert (free_list_space_decrease <= dd_fragmentation (dd)); + } size_t free_list_space_increase = 0; for (int from_hn = 0; from_hn < from_n_heaps; from_hn++) @@ -23733,9 +23960,6 @@ void gc_heap::garbage_collect (int n) #ifdef MULTIPLE_HEAPS gc_start_event.Reset(); -#ifdef DYNAMIC_HEAP_COUNT - gc_idle_thread_event.Reset(); -#endif //DYNAMIC_HEAP_COUNT gc_t_join.restart(); #endif //MULTIPLE_HEAPS } @@ -23757,6 +23981,9 @@ void gc_heap::garbage_collect (int n) #endif // STRESS_HEAP #ifdef MULTIPLE_HEAPS +#ifdef STRESS_DYNAMIC_HEAP_COUNT + Interlocked::Increment (&heaps_in_this_gc); +#endif //STRESS_DYNAMIC_HEAP_COUNT //align all heaps on the max generation to condemn dprintf (3, ("Joining for max generation to condemn")); condemned_generation_num = generation_to_condemn (n, @@ -23772,30 +23999,31 @@ void gc_heap::garbage_collect (int n) #endif //FEATURE_BASICFREEZE #ifdef MULTIPLE_HEAPS +#ifdef STRESS_DYNAMIC_HEAP_COUNT + dprintf (9999, ("%d heaps, join sees %d, actually joined %d, %d idle threads (%d)", + n_heaps, gc_t_join.get_num_threads (), heaps_in_this_gc, + VolatileLoadWithoutBarrier(&dynamic_heap_count_data.idle_thread_count), (n_max_heaps - n_heaps))); + if (heaps_in_this_gc != n_heaps) + { + dprintf (9999, ("should have %d heaps but actually have %d!!", n_heaps, heaps_in_this_gc)); + GCToOSInterface::DebugBreak (); + } + + heaps_in_this_gc = 0; +#endif //STRESS_DYNAMIC_HEAP_COUNT + for (int i = 0; i < n_heaps; i++) { gc_heap* hp = g_heaps[i]; // check for card table growth if (g_gc_card_table != hp->card_table) hp->copy_brick_card_table(); - - hp->rearrange_uoh_segments(); -#ifdef BACKGROUND_GC - hp->background_delay_delete_uoh_segments(); - if (!gc_heap::background_running_p()) - hp->rearrange_small_heap_segments(); -#endif //BACKGROUND_GC + hp->delay_free_segments(); } #else //MULTIPLE_HEAPS if (g_gc_card_table != card_table) copy_brick_card_table(); - - rearrange_uoh_segments(); -#ifdef BACKGROUND_GC - background_delay_delete_uoh_segments(); - if (!gc_heap::background_running_p()) - rearrange_small_heap_segments(); -#endif //BACKGROUND_GC + delay_free_segments(); #endif //MULTIPLE_HEAPS BOOL should_evaluate_elevation = TRUE; @@ -23882,10 +24110,8 @@ void gc_heap::garbage_collect (int n) do_pre_gc(); #ifdef MULTIPLE_HEAPS + dprintf (9999, ("in GC, resetting gc_start")); gc_start_event.Reset(); -#ifdef DYNAMIC_HEAP_COUNT - gc_idle_thread_event.Reset(); -#endif //DYNAMIC_HEAP_COUNT dprintf(3, ("Starting all gc threads for gc")); gc_t_join.restart(); #endif //MULTIPLE_HEAPS @@ -24341,7 +24567,7 @@ void gc_heap::equalize_promoted_bytes(int condemned_gen_number) // hope is to achieve better work balancing in relocate and compact phases // this is also used when the heap count changes to balance regions between heaps int highest_gen_number = ((condemned_gen_number == max_generation) ? - (total_generation_count - 1) : condemned_gen_number); + (total_generation_count - 1) : condemned_gen_number); int stop_gen_idx = get_stop_generation_index (condemned_gen_number); for (int gen_idx = highest_gen_number; gen_idx >= stop_gen_idx; gen_idx--) @@ -25050,285 +25276,332 @@ void gc_heap::recommission_heap() #endif //RECORD_LOH_STATE } -void gc_heap::check_heap_count () +float median_of_3 (float a, float b, float c) { - dynamic_heap_count_data.new_n_heaps = n_heaps; +#define compare_and_swap(i, j) \ + { \ + if (i < j) \ + { \ + float t = i; \ + i = j; \ + j = t; \ + } \ + } + compare_and_swap (b, a); + compare_and_swap (c, a); + compare_and_swap (c, b); +#undef compare_and_swap + return b; +} - if (dynamic_adaptation_mode != dynamic_adaptation_to_application_sizes) +size_t gc_heap::get_num_completed_gcs () +{ + size_t num_completed_gcs = settings.gc_index; +#ifdef BACKGROUND_GC + if (g_heaps[0]->is_bgc_in_progress ()) { - return; + num_completed_gcs--; + dprintf (6666, ("BGC in prog, completed GCs -> %Id", num_completed_gcs)); } +#endif //BACKGROUND_GC - // we should be calling this only on the main GC thread - assert (heap_number == 0); + return num_completed_gcs; +} - // acquire data for the current sample - uint64_t soh_msl_wait_time = 0; - uint64_t uoh_msl_wait_time = 0; - size_t allocating_thread_count = 0; - size_t heap_size = 0; - for (int i = 0; i < n_heaps; i++) +int gc_heap::calculate_new_heap_count () +{ + assert (dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes); + + size_t num_completed_gcs = get_num_completed_gcs (); + + dprintf (6666, ("current GC %Id(completed: %Id), prev completed GCs %Id, last full GC happened at index %Id", + VolatileLoadWithoutBarrier (&settings.gc_index), num_completed_gcs, dynamic_heap_count_data.prev_num_completed_gcs, gc_index_full_gc_end)); + + if (num_completed_gcs < (dynamic_heap_count_data.prev_num_completed_gcs + dynamic_heap_count_data_t::sample_size)) { - gc_heap* hp = g_heaps[i]; + dprintf (6666, ("not enough GCs, skipping")); + return n_heaps; + } - allocating_thread_count += hp->alloc_contexts_used; + float median_gen2_tcp_percent = 0.0f; + if (gc_index_full_gc_end >= (settings.gc_index - dynamic_heap_count_data_t::sample_size)) + { + median_gen2_tcp_percent = dynamic_heap_count_data.get_median_gen2_gc_percent (); + } - soh_msl_wait_time += hp->more_space_lock_soh.msl_wait_time; - hp->more_space_lock_soh.msl_wait_time = 0; - hp->more_space_lock_soh.msl_wait_count = 0; + // If there was a blocking gen2 GC, the overhead would be very large and most likely we would not pick it. So we + // rely on the gen2 sample's overhead calculated above. + float throughput_cost_percents[dynamic_heap_count_data_t::sample_size]; + for (int i = 0; i < dynamic_heap_count_data_t::sample_size; i++) + { + dynamic_heap_count_data_t::sample& sample = dynamic_heap_count_data.samples[i]; + throughput_cost_percents[i] = (sample.elapsed_between_gcs ? (((float)sample.msl_wait_time / n_heaps + sample.gc_pause_time) * 100.0f / (float)sample.elapsed_between_gcs) : 0.0f); + assert (throughput_cost_percents[i] >= 0.0); + if (throughput_cost_percents[i] > 100.0) + throughput_cost_percents[i] = 100.0; + dprintf (6666, ("sample %d: msl %I64d / %d + pause %I64d / elapsed %I64d = throughput_cost_percent: %.3f", i, + sample.msl_wait_time, n_heaps, sample.gc_pause_time, sample.elapsed_between_gcs, throughput_cost_percents[i])); + } - uoh_msl_wait_time += hp->more_space_lock_uoh.msl_wait_time; - hp->more_space_lock_uoh.msl_wait_time = 0; - hp->more_space_lock_uoh.msl_wait_count = 0; + float median_throughput_cost_percent = median_of_3 (throughput_cost_percents[0], throughput_cost_percents[1], throughput_cost_percents[2]); + + // apply exponential smoothing and use 1/3 for the smoothing factor + const float smoothing = 3; + float smoothed_median_throughput_cost_percent = dynamic_heap_count_data.smoothed_median_throughput_cost_percent; + if (smoothed_median_throughput_cost_percent != 0.0f) + { + // average it with the previous value + smoothed_median_throughput_cost_percent = median_throughput_cost_percent / smoothing + (smoothed_median_throughput_cost_percent / smoothing) * (smoothing - 1); + } + else + { + smoothed_median_throughput_cost_percent = median_throughput_cost_percent; + } + + dprintf (6666, ("median tcp: %.3f, smoothed tcp: %.3f, gen2 tcp %.3f(%.3f, %.3f, %.3f)", + median_throughput_cost_percent, smoothed_median_throughput_cost_percent, median_gen2_tcp_percent, + dynamic_heap_count_data.gen2_gc_percents[0], dynamic_heap_count_data.gen2_gc_percents[1], dynamic_heap_count_data.gen2_gc_percents[2])); + + size_t heap_size = 0; + for (int i = 0; i < n_heaps; i++) + { + gc_heap* hp = g_heaps[i]; for (int gen_idx = 0; gen_idx < total_generation_count; gen_idx++) { dynamic_data* dd = hp->dynamic_data_of (gen_idx); // estimate the size of each generation as the live data size plus the budget - heap_size += dd_promoted_size (dd) + dd_desired_allocation (dd); - dprintf (6666, ("h%d g%d promoted: %zd desired allocation: %zd", i, gen_idx, dd_promoted_size (dd), dd_desired_allocation (dd))); + heap_size += dd_current_size (dd) + dd_desired_allocation (dd); + dprintf (3, ("h%d g%d current: %zd desired allocation: %zd", i, gen_idx, dd_promoted_size (dd), dd_desired_allocation (dd))); } } - dynamic_data* hp0_dd0 = g_heaps[0]->dynamic_data_of (0); + // estimate the space cost of adding a heap as the min gen0 budget + size_t heap_space_cost_per_heap = dd_min_size (g_heaps[0]->dynamic_data_of (0)); - // persist data for the current sample - dynamic_heap_count_data_t::sample& sample = dynamic_heap_count_data.samples[dynamic_heap_count_data.sample_index]; + // compute the % space cost of adding a heap + float percent_heap_space_cost_per_heap = heap_space_cost_per_heap * 100.0f / heap_size; - sample.soh_msl_wait_time = soh_msl_wait_time / n_heaps; - sample.uoh_msl_wait_time = uoh_msl_wait_time / n_heaps; - sample.elapsed_between_gcs = dd_time_clock (hp0_dd0) - dd_previous_time_clock (hp0_dd0); - sample.gc_elapsed_time = dd_gc_elapsed_time (hp0_dd0); - sample.allocating_thread_count = allocating_thread_count; - sample.heap_size = heap_size; + // compute reasonable step sizes for the heap count + // + // on the way up, we essentially multiply the heap count by 1.5, so we go 1, 2, 3, 5, 8 ... + // we don't go all the way to the number of CPUs, but stay 1 or 2 short + int step_up = (n_heaps + 1) / 2; + int extra_heaps = 1 + (n_max_heaps >= 32); + step_up = min (step_up, n_max_heaps - extra_heaps - n_heaps); - dprintf (6666, ("sample %d: soh_msl_wait_time: %zd, uoh_msl_wait_time: %zd, elapsed_between_gcs: %zd, gc_elapsed_time: %d, heap_size: %zd MB", - dynamic_heap_count_data.sample_index, - sample.soh_msl_wait_time, - sample.uoh_msl_wait_time, - sample.elapsed_between_gcs, - sample.gc_elapsed_time, - sample.heap_size/(1024*1024))); + // on the way down, we essentially divide the heap count by 1.5 + int step_down = (n_heaps + 1) / 3; - dynamic_heap_count_data.sample_index = (dynamic_heap_count_data.sample_index + 1) % dynamic_heap_count_data_t::sample_size; + // estimate the potential time benefit of going up a step + float tcp_reduction_per_step_up = smoothed_median_throughput_cost_percent * step_up / (n_heaps + step_up); - GCEventFireHeapCountSample_V1( - sample.gc_elapsed_time, - sample.soh_msl_wait_time, - sample.uoh_msl_wait_time, - sample.elapsed_between_gcs - ); + // estimate the potential time cost of going down a step + float tcp_increase_per_step_down = smoothed_median_throughput_cost_percent * step_down / (n_heaps - step_down); + + // estimate the potential space cost of going up a step + float scp_increase_per_step_up = percent_heap_space_cost_per_heap * step_up; - if (settings.gc_index < prev_change_heap_count_gc_index + 3) + // estimate the potential space saving of going down a step + float scp_decrease_per_step_down = percent_heap_space_cost_per_heap * step_down; + + dprintf (6666, ("[CHP] u %d, d %d | space cost %Id / heap %Id(%.2fmb) = scp %.3f (u: %.3f, d: %.3f) | stcp %.3f, u * %.1f = %.3f, d * %.1f = %.3f", + step_up, step_down, + heap_space_cost_per_heap, heap_size, ((float)heap_size / (float)1000 / (float)1000), percent_heap_space_cost_per_heap, + scp_increase_per_step_up, scp_decrease_per_step_down, + smoothed_median_throughput_cost_percent, + ((float)step_up / (float)(n_heaps + step_up)), tcp_reduction_per_step_up, + ((float)step_down / (float)(n_heaps - step_down)), tcp_increase_per_step_down)); + +#ifdef STRESS_DYNAMIC_HEAP_COUNT + // quick hack for initial testing + int new_n_heaps = (int)gc_rand::get_rand (n_max_heaps - 1) + 1; + + // if we are adjusting down, make sure we adjust lower than the lowest uoh msl heap + if ((new_n_heaps < n_heaps) && (dynamic_heap_count_data.lowest_heap_with_msl_uoh != -1)) { - // reconsider the decision every few gcs - return; + new_n_heaps = min (dynamic_heap_count_data.lowest_heap_with_msl_uoh, new_n_heaps); + new_n_heaps = max (new_n_heaps, 1); } - - if (gc_heap::background_running_p()) + dprintf (6666, ("stress %d -> %d", n_heaps, new_n_heaps)); +#else //STRESS_DYNAMIC_HEAP_COUNT + int new_n_heaps = n_heaps; + if (median_throughput_cost_percent > 10.0f) { - // can't have background gc running while we change the number of heaps - // so it's useless to compute a new number of heaps here + // ramp up more agressively - use as many heaps as it would take to bring + // the tcp down to 5% + new_n_heaps = (int)(n_heaps * (median_throughput_cost_percent / 5.0)); + dprintf (6666, ("[CHP0] tcp %.3f -> %d * %.3f = %d", median_throughput_cost_percent, n_heaps, (median_throughput_cost_percent / 5.0), new_n_heaps)); + new_n_heaps = min (new_n_heaps, n_max_heaps - extra_heaps); } - else + // if the median tcp is 10% or less, react slower + else if ((smoothed_median_throughput_cost_percent > 5.0f) || (median_gen2_tcp_percent > 10.0f)) { - // compute the % overhead from msl waiting time and gc time for each of the samples - float percent_overhead[dynamic_heap_count_data_t::sample_size]; - for (int i = 0; i < dynamic_heap_count_data_t::sample_size; i++) - { - dynamic_heap_count_data_t::sample& sample = dynamic_heap_count_data.samples[i]; - uint64_t overhead_time = sample.soh_msl_wait_time + sample.uoh_msl_wait_time + sample.gc_elapsed_time; - percent_overhead[i] = overhead_time * 100.0f / sample.elapsed_between_gcs; - if (percent_overhead[i] < 0) - percent_overhead[i] = 0; - else if (percent_overhead[i] > 100) - percent_overhead[i] = 100; - dprintf (6666, ("sample %d: percent_overhead: %d%%", i, (int)percent_overhead[i])); - } - // compute the median of the percent overhead samples - #define compare_and_swap(i, j) \ - { \ - if (percent_overhead[i] < percent_overhead[j]) \ - { \ - float t = percent_overhead[i]; \ - percent_overhead[i] = percent_overhead[j]; \ - percent_overhead[j] = t; \ - } \ - } - compare_and_swap (1, 0); - compare_and_swap (2, 0); - compare_and_swap (2, 1); - #undef compare_and_swap - - // the middle element is the median overhead percentage - float median_percent_overhead = percent_overhead[1]; - - // apply exponential smoothing and use 1/3 for the smoothing factor - const float smoothing = 3; - float smoothed_median_percent_overhead = dynamic_heap_count_data.smoothed_median_percent_overhead; - if (smoothed_median_percent_overhead != 0.0f) - { - // average it with the previous value - smoothed_median_percent_overhead = median_percent_overhead / smoothing + (smoothed_median_percent_overhead / smoothing) * (smoothing - 1); + if (smoothed_median_throughput_cost_percent > 5.0f) + { + dprintf (6666, ("[CHP1] stcp %.3f > 5, %d + %d = %d", smoothed_median_throughput_cost_percent, n_heaps, step_up, (n_heaps + step_up))); } else { - // first time? initialize to the median - smoothed_median_percent_overhead = median_percent_overhead; + dprintf (6666, ("[CHP2] tcp %.3f > 10, %d + %d = %d", median_gen2_tcp_percent, n_heaps, step_up, (n_heaps + step_up))); } + new_n_heaps += step_up; + } + // if we can save at least 1% more in time than we spend in space, increase number of heaps + else if ((tcp_reduction_per_step_up - scp_increase_per_step_up) >= 1.0f) + { + dprintf (6666, ("[CHP3] % .3f - % .3f = % .3f, % d + % d = % d", + tcp_reduction_per_step_up, scp_increase_per_step_up, (tcp_reduction_per_step_up - scp_increase_per_step_up), + n_heaps, step_up, (n_heaps + step_up))); + new_n_heaps += step_up; + } + // if we can save at least 1% more in space than we spend in time, decrease number of heaps + else if ((smoothed_median_throughput_cost_percent < 1.0f) && + (median_gen2_tcp_percent < 5.0f) && + ((scp_decrease_per_step_down - tcp_increase_per_step_down) >= 1.0f)) + { + dprintf (6666, ("[CHP4] stcp %.3f tcp %.3f, %.3f - %.3f = %.3f, %d + %d = %d", + smoothed_median_throughput_cost_percent, median_gen2_tcp_percent, + scp_decrease_per_step_down, tcp_increase_per_step_down, (scp_decrease_per_step_down - tcp_increase_per_step_down), + n_heaps, step_up, (n_heaps + step_up))); + new_n_heaps -= step_down; + } - dprintf (6666, ("median overhead: %d%% smoothed median overhead: %d%%", (int)(median_percent_overhead*1000), (int)(smoothed_median_percent_overhead*1000))); - - // estimate the space cost of adding a heap as the min gen0 size - size_t heap_space_cost_per_heap = dd_min_size (hp0_dd0); - - // compute the % space cost of adding a heap - float percent_heap_space_cost_per_heap = heap_space_cost_per_heap * 100.0f / heap_size; - - // compute reasonable step sizes for the heap count + assert (new_n_heaps >= 1); + assert (new_n_heaps <= n_max_heaps); +#endif //STRESS_DYNAMIC_HEAP_COUNT - // on the way up, we essentially multiply the heap count by 1.5, so we go 1, 2, 3, 5, 8 ... - // we don't go all the way to the number of CPUs, but stay 1 or 2 short - int step_up = (n_heaps + 1) / 2; - int extra_heaps = 1 + (n_max_heaps >= 32); - step_up = min (step_up, n_max_heaps - extra_heaps - n_heaps); + // store data used for decision to emit in ETW event + dynamic_heap_count_data.median_throughput_cost_percent = median_throughput_cost_percent; + dynamic_heap_count_data.smoothed_median_throughput_cost_percent = smoothed_median_throughput_cost_percent; + dynamic_heap_count_data.percent_heap_space_cost_per_heap = percent_heap_space_cost_per_heap; + dynamic_heap_count_data.tcp_reduction_per_step_up = tcp_reduction_per_step_up; + dynamic_heap_count_data.tcp_increase_per_step_down = tcp_increase_per_step_down; + dynamic_heap_count_data.scp_increase_per_step_up = scp_increase_per_step_up; + dynamic_heap_count_data.scp_decrease_per_step_down = scp_decrease_per_step_down; + + GCEventFireHeapCountTuning_V1 ( + (uint16_t)dynamic_heap_count_data.new_n_heaps, + (uint64_t)VolatileLoadWithoutBarrier (&settings.gc_index), + dynamic_heap_count_data.median_throughput_cost_percent, + dynamic_heap_count_data.smoothed_median_throughput_cost_percent, + dynamic_heap_count_data.tcp_reduction_per_step_up, + dynamic_heap_count_data.tcp_increase_per_step_down, + dynamic_heap_count_data.scp_increase_per_step_up, + dynamic_heap_count_data.scp_decrease_per_step_down + ); - // on the way down, we essentially divide the heap count by 1.5 - int step_down = (n_heaps + 1) / 3; + dynamic_heap_count_data.prev_num_completed_gcs = num_completed_gcs; - // estimate the potential time benefit of going up a step - float overhead_reduction_per_step_up = smoothed_median_percent_overhead * step_up / (n_heaps + step_up); + if (new_n_heaps != n_heaps) + { + dprintf (6666, ("should change! %d->%d", n_heaps, new_n_heaps)); + dynamic_heap_count_data.heap_count_to_change_to = new_n_heaps; + dynamic_heap_count_data.should_change_heap_count = true; + } - // estimate the potential time cost of going down a step - float overhead_increase_per_step_down = smoothed_median_percent_overhead * step_down / (n_heaps - step_down); + return new_n_heaps; +} - // estimate the potential space cost of going up a step - float space_cost_increase_per_step_up = percent_heap_space_cost_per_heap * step_up; +void gc_heap::check_heap_count () +{ + dynamic_heap_count_data.new_n_heaps = dynamic_heap_count_data.heap_count_to_change_to; - // estimate the potential space saving of going down a step - float space_cost_decrease_per_step_down = percent_heap_space_cost_per_heap * step_down; + assert (dynamic_heap_count_data.new_n_heaps != n_heaps); -#ifdef STRESS_DYNAMIC_HEAP_COUNT - // quick hack for initial testing - int new_n_heaps = (int)gc_rand::get_rand (n_max_heaps - 1) + 1; + if (dynamic_heap_count_data.new_n_heaps != n_heaps) + { + dprintf (9999, ("h0 suspending EE in check")); + // can't have threads allocating while we change the number of heaps + GCToEEInterface::SuspendEE(SUSPEND_FOR_GC_PREP); + dprintf (9999, ("h0 suspended EE in check")); - // if we are adjusting down, make sure we adjust lower than the lowest uoh msl heap - if ((new_n_heaps < n_heaps) && (dynamic_heap_count_data.lowest_heap_with_msl_uoh != -1)) +#ifdef BACKGROUND_GC + if (gc_heap::background_running_p()) { - new_n_heaps = min (dynamic_heap_count_data.lowest_heap_with_msl_uoh, new_n_heaps); + // background GC is running - reset the new heap count + dynamic_heap_count_data.new_n_heaps = n_heaps; + dprintf (6666, ("can't change heap count! BGC in progress")); - // but not down to zero, obviously... - new_n_heaps = max (new_n_heaps, 1); - } -#else //STRESS_DYNAMIC_HEAP_COUNT - int new_n_heaps = n_heaps; - if (median_percent_overhead > 10.0f) - { - // ramp up more agressively - use as many heaps as it would take to bring - // the overhead down to 5% - new_n_heaps = (int)(n_heaps * (median_percent_overhead / 5.0)); - new_n_heaps = min (new_n_heaps, n_max_heaps - extra_heaps); - } - // if the median overhead is 10% or less, react slower - else if (smoothed_median_percent_overhead > 5.0f) - { - new_n_heaps += step_up; - } - // if we can save at least 1% more in time than we spend in space, increase number of heaps - else if (overhead_reduction_per_step_up - space_cost_increase_per_step_up >= 1.0f) - { - new_n_heaps += step_up; - } - // if we can save at least 1% more in space than we spend in time, decrease number of heaps - else if (smoothed_median_percent_overhead < 1.0f && space_cost_decrease_per_step_down - overhead_increase_per_step_down >= 1.0f) - { - new_n_heaps -= step_down; + GCToEEInterface::RestartEE(TRUE); } +#endif //BACKGROUND_GC + } - dprintf (6666, ("or: %d, si: %d, sd: %d, oi: %d => %d -> %d", - (int)overhead_reduction_per_step_up, - (int)space_cost_increase_per_step_up, - (int)space_cost_decrease_per_step_down, - (int)overhead_increase_per_step_down, - n_heaps, - new_n_heaps)); - - assert (1 <= new_n_heaps); - assert (new_n_heaps <= n_max_heaps); -#endif //STRESS_DYNAMIC_HEAP_COUNT - - dynamic_heap_count_data.new_n_heaps = new_n_heaps; - - // store data used for decision to emit in ETW event - dynamic_heap_count_data.median_percent_overhead = median_percent_overhead; - dynamic_heap_count_data.smoothed_median_percent_overhead = smoothed_median_percent_overhead; - dynamic_heap_count_data.percent_heap_space_cost_per_heap = percent_heap_space_cost_per_heap; - dynamic_heap_count_data.overhead_reduction_per_step_up = overhead_reduction_per_step_up; - dynamic_heap_count_data.overhead_increase_per_step_down = overhead_increase_per_step_down; - dynamic_heap_count_data.space_cost_increase_per_step_up = space_cost_increase_per_step_up; - dynamic_heap_count_data.space_cost_decrease_per_step_down = space_cost_decrease_per_step_down; - - GCEventFireHeapCountTuning_V1( - (uint16_t)dynamic_heap_count_data.new_n_heaps, - (uint64_t)VolatileLoad(&settings.gc_index), - dynamic_heap_count_data.median_percent_overhead, - dynamic_heap_count_data.smoothed_median_percent_overhead, - dynamic_heap_count_data.overhead_reduction_per_step_up, - dynamic_heap_count_data.overhead_increase_per_step_down, - dynamic_heap_count_data.space_cost_increase_per_step_up, - dynamic_heap_count_data.space_cost_decrease_per_step_down - ); - - if (new_n_heaps != n_heaps) + if (dynamic_heap_count_data.new_n_heaps != n_heaps) + { + dprintf (6666, ("prep to change from %d to %d", n_heaps, dynamic_heap_count_data.new_n_heaps)); + if (!prepare_to_change_heap_count (dynamic_heap_count_data.new_n_heaps)) { - // can't have threads allocating while we change the number of heaps - GCToEEInterface::SuspendEE(SUSPEND_FOR_GC_PREP); - - if (gc_heap::background_running_p()) - { - // background GC is running - reset the new heap count - dynamic_heap_count_data.new_n_heaps = n_heaps; - - GCToEEInterface::RestartEE(TRUE); - } + // we don't have sufficient resources - reset the new heap count + dynamic_heap_count_data.new_n_heaps = n_heaps; } } if (dynamic_heap_count_data.new_n_heaps == n_heaps) { // heap count stays the same, no work to do - dprintf (6666, ("heap count stays the same, no work to do %d == %d", dynamic_heap_count_data.new_n_heaps, n_heaps)); + dynamic_heap_count_data.prev_num_completed_gcs = get_num_completed_gcs (); + dynamic_heap_count_data.should_change_heap_count = false; - // come back after 3 GCs to reconsider - prev_change_heap_count_gc_index = settings.gc_index; + dprintf (6666, ("heap count stays the same %d, no work to do, set prev completed to %Id", dynamic_heap_count_data.new_n_heaps, dynamic_heap_count_data.prev_num_completed_gcs)); return; } - if (GCScan::GetGcRuntimeStructuresValid()) + int new_n_heaps = dynamic_heap_count_data.new_n_heaps; + + assert (!(dynamic_heap_count_data.init_only_p)); + { + // At this point we are guaranteed to be able to change the heap count to the new one. + // Change the heap count for joins here because we will need to join new_n_heaps threads together. + dprintf (9999, ("changing join hp %d->%d", n_heaps, new_n_heaps)); + int max_threads_to_wake = max (n_heaps, new_n_heaps); + gc_t_join.update_n_threads (max_threads_to_wake); + // make sure the other gc threads cannot see this as a request to GC assert (dynamic_heap_count_data.new_n_heaps != n_heaps); + + if (n_heaps < new_n_heaps) + { + int saved_idle_thread_count = dynamic_heap_count_data.idle_thread_count; + Interlocked::ExchangeAdd (&dynamic_heap_count_data.idle_thread_count, (n_heaps - new_n_heaps)); + dprintf (9999, ("GC thread %d setting idle events for h%d-h%d, total idle %d -> %d", heap_number, n_heaps, (new_n_heaps - 1), + saved_idle_thread_count, VolatileLoadWithoutBarrier (&dynamic_heap_count_data.idle_thread_count))); + + for (int heap_idx = n_heaps; heap_idx < new_n_heaps; heap_idx++) + { + g_heaps[heap_idx]->gc_idle_thread_event.Set(); +#ifdef BACKGROUND_GC + g_heaps[heap_idx]->bgc_idle_thread_event.Set(); +#endif //BACKGROUND_GC + } + } + gc_start_event.Set(); } int old_n_heaps = n_heaps; + (dynamic_heap_count_data.heap_count_change_count)++; change_heap_count (dynamic_heap_count_data.new_n_heaps); GCToEEInterface::RestartEE(TRUE); - prev_change_heap_count_gc_index = settings.gc_index; + dprintf (9999, ("h0 restarted EE")); // we made changes to the heap count that will change the overhead, // so change the smoothed overhead to reflect that - int new_n_heaps = n_heaps; - dynamic_heap_count_data.smoothed_median_percent_overhead = dynamic_heap_count_data.smoothed_median_percent_overhead/new_n_heaps*old_n_heaps; + dynamic_heap_count_data.smoothed_median_throughput_cost_percent = dynamic_heap_count_data.smoothed_median_throughput_cost_percent / n_heaps * old_n_heaps; + + dprintf (6666, ("h0 finished changing, set should change to false!")); + dynamic_heap_count_data.should_change_heap_count = false; } bool gc_heap::prepare_to_change_heap_count (int new_n_heaps) { - dprintf (6666, ("trying to change heap count %d -> %d", n_heaps, new_n_heaps)); + dprintf (9999, ("trying to change heap count %d -> %d", n_heaps, new_n_heaps)); // use this variable for clarity - n_heaps will change during the transition int old_n_heaps = n_heaps; @@ -25371,6 +25644,17 @@ bool gc_heap::prepare_to_change_heap_count (int new_n_heaps) } } + // Before we look at whether we have sufficient regions we should return regions that should be deleted to free + // so we don't lose them when we decommission heaps. We could do this for only heaps that we are about + // to decomission. But it's better to do this for all heaps because we don't need to worry about adding them to the + // heaps remain (freeable uoh/soh regions) and we get rid of regions with the heap_segment_flags_uoh_delete flag + // because background_delay_delete_uoh_segments makes the assumption it can't be the start region. + for (int i = 0; i < old_n_heaps; i++) + { + gc_heap* hp = g_heaps[i]; + hp->delay_free_segments (); + } + // if we want to increase the number of heaps, we have to make sure we can give // each heap a region for each generation. If we cannot do that, we have to give up ptrdiff_t region_count_in_gen[total_generation_count]; @@ -25451,39 +25735,34 @@ bool gc_heap::prepare_to_change_heap_count (int new_n_heaps) bool gc_heap::change_heap_count (int new_n_heaps) { + dprintf (9999, ("BEG heap%d changing %d->%d", heap_number, n_heaps, new_n_heaps)); + // use this variable for clarity - n_heaps will change during the transition int old_n_heaps = n_heaps; + bool init_only_p = dynamic_heap_count_data.init_only_p; - if (heap_number == 0) { - if (!prepare_to_change_heap_count (new_n_heaps)) - { - // we don't have sufficient resources - reset the new heap count - dynamic_heap_count_data.new_n_heaps = n_heaps; - } - } - - if (GCScan::GetGcRuntimeStructuresValid()) - { - // join for sufficient resources decision gc_t_join.join (this, gc_join_merge_temp_fl); if (gc_t_join.joined ()) { + // BGC is not running, we can safely change its join's heap count. +#ifdef BACKGROUND_GC + bgc_t_join.update_n_threads (new_n_heaps); +#endif //BACKGROUND_GC + + dynamic_heap_count_data.init_only_p = false; + dprintf (9999, ("in change h%d resetting gc_start, update bgc join to %d heaps", heap_number, new_n_heaps)); gc_start_event.Reset(); gc_t_join.restart (); } } - // gc_heap::n_heaps may have changed by now, compare to the snapshot *before* the join - if (dynamic_heap_count_data.new_n_heaps == old_n_heaps) - { - dprintf (6666, ("failed to change heap count, no work to do %d == %d", dynamic_heap_count_data.new_n_heaps, old_n_heaps)); - return false; - } + assert (dynamic_heap_count_data.new_n_heaps != old_n_heaps); + + dprintf (9999, ("Waiting h0 heap%d changing %d->%d", heap_number, n_heaps, new_n_heaps)); if (heap_number == 0) { - // after having checked for sufficient resources, we are now committed to actually change the heap count dprintf (3, ("switching heap count from %d to %d heaps", old_n_heaps, new_n_heaps)); // spread finalization data out to heaps coming into service @@ -25504,17 +25783,23 @@ bool gc_heap::change_heap_count (int new_n_heaps) from_heap_number = (from_heap_number + 1) % old_n_heaps; } - // prepare for the switch by fixing the allocation contexts on the old heaps, + // prepare for the switch by fixing the allocation contexts on the old heaps, unify the gen0_bricks_cleared flag, // and setting the survived size for the existing regions to their allocated size + BOOL unified_gen0_bricks_cleared = TRUE; for (int i = 0; i < old_n_heaps; i++) { gc_heap* hp = g_heaps[i]; - if (GCScan::GetGcRuntimeStructuresValid()) + if (!init_only_p) { hp->fix_allocation_contexts (TRUE); } + if (unified_gen0_bricks_cleared && (hp->gen0_bricks_cleared == FALSE)) + { + unified_gen0_bricks_cleared = FALSE; + } + for (int gen_idx = 0; gen_idx < total_generation_count; gen_idx++) { generation* gen = hp->generation_of (gen_idx); @@ -25614,7 +25899,7 @@ bool gc_heap::change_heap_count (int new_n_heaps) hpd->free_regions[kind].transfer_regions(&hp->free_regions[kind]); } } - // update number of heaps + dprintf (9999, ("h%d changing %d->%d", heap_number, n_heaps, new_n_heaps)); n_heaps = new_n_heaps; // even out the regions over the current number of heaps @@ -25625,6 +25910,8 @@ bool gc_heap::change_heap_count (int new_n_heaps) { gc_heap* hp = g_heaps[i]; + hp->gen0_bricks_cleared = unified_gen0_bricks_cleared; + // establish invariants regarding the ephemeral segment generation* gen0 = hp->generation_of (0); if ((hp->ephemeral_heap_segment == nullptr) || @@ -25653,7 +25940,9 @@ bool gc_heap::change_heap_count (int new_n_heaps) } } - if (GCScan::GetGcRuntimeStructuresValid()) + dprintf (3, ("individual heap%d changing %d->%d", heap_number, n_heaps, new_n_heaps)); + + if (!init_only_p) { // join for rethreading the free lists gc_t_join.join (this, gc_join_merge_temp_fl); @@ -25665,7 +25954,11 @@ bool gc_heap::change_heap_count (int new_n_heaps) // rethread the free lists for (int gen_idx = 0; gen_idx < total_generation_count; gen_idx++) { - rethread_fl_items (gen_idx); + if (heap_number < old_n_heaps) + { + dprintf (3, ("h%d calling per heap work!", heap_number)); + rethread_fl_items (gen_idx); + } // join for merging the free lists gc_t_join.join (this, gc_join_merge_temp_fl); @@ -25676,18 +25969,14 @@ bool gc_heap::change_heap_count (int new_n_heaps) gc_t_join.restart (); } } +#ifdef BACKGROUND_GC // there should be no items in the bgc_alloc_lock bgc_alloc_lock->check(); +#endif //BACKGROUND_GC } if (heap_number == 0) { - // udate the number of heaps in the joins - gc_t_join.update_n_threads(new_n_heaps); - #ifdef BACKGROUND_GC - bgc_t_join.update_n_threads(new_n_heaps); - #endif //BACKGROUND_GC - // compute the total budget per generation over the old heaps // and figure out what the new budget per heap is ptrdiff_t budget_per_heap[total_generation_count]; @@ -25747,21 +26036,50 @@ bool gc_heap::change_heap_count (int new_n_heaps) hp->decommission_heap(); } - if (GCScan::GetGcRuntimeStructuresValid()) + if (!init_only_p) { // make sure no allocation contexts point to idle heaps fix_allocation_contexts_heaps(); } - if (old_n_heaps < new_n_heaps) + dynamic_heap_count_data.last_n_heaps = old_n_heaps; + } + + // join the last time to change the heap count again if needed. + if (new_n_heaps < old_n_heaps) + { + gc_t_join.join (this, gc_join_merge_temp_fl); + if (gc_t_join.joined ()) { - // wake up threads for the new heaps - gc_idle_thread_event.Set(); + dprintf (9999, ("now changing the join heap count to the smaller one %d", new_n_heaps)); + gc_t_join.update_n_threads (new_n_heaps); + + gc_t_join.restart (); } } return true; } + +size_t gc_heap::get_msl_wait_time() +{ + assert (dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes); + + size_t msl_wait_since_pause = 0; + + for (int i = 0; i < n_heaps; i++) + { + gc_heap* hp = g_heaps[i]; + + msl_wait_since_pause += hp->more_space_lock_soh.msl_wait_time; + hp->more_space_lock_soh.msl_wait_time = 0; + + msl_wait_since_pause += hp->more_space_lock_uoh.msl_wait_time; + hp->more_space_lock_uoh.msl_wait_time = 0; + } + + return msl_wait_since_pause; +} #endif //DYNAMIC_HEAP_COUNT #endif //USE_REGIONS @@ -32805,17 +33123,17 @@ void gc_heap::plan_phase (int condemned_gen_number) } else { - dprintf (2, ("gen2 didn't grow (end seg alloc: %zd, , condemned alloc: %zd, gen1 c alloc: %zd", + dprintf (1, ("gen2 didn't grow (end seg alloc: %zd, , condemned alloc: %zd, gen1 c alloc: %zd", end_seg_allocated, condemned_allocated, generation_condemned_allocated (generation_of (max_generation - 1)))); } - dprintf (1, ("older gen's free alloc: %zd->%zd, seg alloc: %zd->%zd, condemned alloc: %zd->%zd", + dprintf (2, ("older gen's free alloc: %zd->%zd, seg alloc: %zd->%zd, condemned alloc: %zd->%zd", r_older_gen_free_list_allocated, generation_free_list_allocated (older_gen), r_older_gen_end_seg_allocated, generation_end_seg_allocated (older_gen), r_older_gen_condemned_allocated, generation_condemned_allocated (older_gen))); - dprintf (1, ("this GC did %zd free list alloc(%zd bytes free space rejected)", + dprintf (2, ("this GC did %zd free list alloc(%zd bytes free space rejected)", free_list_allocated, rejected_free_space)); maxgen_size_increase* maxgen_size_info = &(get_gc_data_per_heap()->maxgen_size_info); @@ -38908,9 +39226,9 @@ void gc_heap::bgc_thread_function() { // this is the case where we have more background GC threads than heaps // - wait until we're told to continue... - dprintf (3, ("BGC thread %d idle", heap_number)); - gc_idle_thread_event.Wait(INFINITE, FALSE); - dprintf (3, ("BGC thread %d waking from idle", heap_number)); + dprintf (9999, ("BGC thread %d idle (%d heaps) (gc%Id)", heap_number, n_heaps, VolatileLoadWithoutBarrier (&settings.gc_index))); + bgc_idle_thread_event.Wait(INFINITE, FALSE); + dprintf (9999, ("BGC thread %d waking from idle (%d heaps) (gc%Id)", heap_number, n_heaps, VolatileLoadWithoutBarrier (&settings.gc_index))); continue; } #endif //DYNAMIC_HEAP_COUNT @@ -38982,7 +39300,7 @@ void gc_heap::bgc_thread_function() dprintf (SPINLOCK_LOG, ("bgc Lgc")); leave_spin_lock (&gc_lock); #ifdef MULTIPLE_HEAPS - dprintf(1, ("End of BGC - starting all BGC threads")); + dprintf(1, ("End of BGC")); bgc_t_join.restart(); #endif //MULTIPLE_HEAPS } @@ -42859,6 +43177,9 @@ bool gc_heap::init_dynamic_data() { process_start_time = now; smoothed_desired_total[0] = dynamic_data_of (0)->min_size * n_heaps; +#ifdef DYNAMIC_HEAP_COUNT + last_suspended_end_time = now; +#endif //DYNAMIC_HEAP_COUNT #ifdef HEAP_BALANCE_INSTRUMENTATION last_gc_end_time_us = now; dprintf (HEAP_BALANCE_LOG, ("qpf=%zd, start: %zd(%d)", qpf, start_raw_ts, now)); @@ -47957,6 +48278,7 @@ HRESULT GCHeap::Initialize() uint32_t nhp = 1; uint32_t nhp_from_config = 0; + uint32_t max_nhp_from_config = (uint32_t)GCConfig::GetMaxHeapCount(); #ifndef MULTIPLE_HEAPS GCConfig::SetServerGC(false); @@ -48151,6 +48473,10 @@ HRESULT GCHeap::Initialize() #ifdef MULTIPLE_HEAPS assert (nhp <= g_num_processors); + if (max_nhp_from_config) + { + nhp = min (nhp, max_nhp_from_config); + } gc_heap::n_max_heaps = nhp; gc_heap::n_heaps = nhp; hr = gc_heap::initialize_gc (seg_size, large_seg_size, pin_seg_size, nhp); @@ -48301,9 +48627,32 @@ HRESULT GCHeap::Initialize() { // start with only 1 heap gc_heap::smoothed_desired_total[0] /= gc_heap::n_heaps; - gc_heap::g_heaps[0]->change_heap_count (1); + int initial_n_heaps = 1; + dprintf (9999, ("gc_heap::n_heaps is %d, initial %d", gc_heap::n_heaps, initial_n_heaps)); + + { + if (!gc_heap::prepare_to_change_heap_count (initial_n_heaps)) + { + // we don't have sufficient resources. + return E_FAIL; + } + + gc_heap::dynamic_heap_count_data.new_n_heaps = initial_n_heaps; + gc_heap::dynamic_heap_count_data.idle_thread_count = 0; + gc_heap::dynamic_heap_count_data.init_only_p = true; + + int max_threads_to_wake = max (gc_heap::n_heaps, initial_n_heaps); + gc_t_join.update_n_threads (max_threads_to_wake); + gc_heap::gc_start_event.Set (); + } + + gc_heap::g_heaps[0]->change_heap_count (initial_n_heaps); + gc_heap::gc_start_event.Reset (); + + // This needs to be different from our initial heap count so we can make sure we wait for + // the idle threads correctly in gc_thread_function. + gc_heap::dynamic_heap_count_data.last_n_heaps = 0; } - gc_heap::dynamic_heap_count_data.new_n_heaps = gc_heap::n_heaps; #endif //DYNAMIC_HEAP_COUNT GCScan::GcRuntimeStructuresValid (TRUE); @@ -49875,10 +50224,16 @@ void gc_heap::do_post_gc() } #endif //BGC_SERVO_TUNING +#ifdef BACKGROUND_GC + const char* str_gc_type = (settings.concurrent ? "BGC" : (gc_heap::background_running_p () ? "FGC" : "NGC")); +#else + const char* str_gc_type = "NGC"; +#endif //BACKGROUND_GC + dprintf (1, (ThreadStressLog::gcDetailedEndMsg(), - VolatileLoad(&settings.gc_index), - dd_collection_count(hp->dynamic_data_of(0)), - (size_t)(GetHighPrecisionTimeStamp() / 1000), + VolatileLoad (&settings.gc_index), + dd_collection_count (hp->dynamic_data_of (0)), + (size_t)(GetHighPrecisionTimeStamp () / 1000), settings.condemned_generation, (settings.concurrent ? "BGC" : (gc_heap::background_running_p() ? "FGC" : "NGC")), (settings.compaction ? "C" : "S"), diff --git a/src/coreclr/gc/gcconfig.h b/src/coreclr/gc/gcconfig.h index 72786778d5a978..aeded6bc97f17f 100644 --- a/src/coreclr/gc/gcconfig.h +++ b/src/coreclr/gc/gcconfig.h @@ -83,6 +83,7 @@ class GCConfigStringHolder INT_CONFIG (BGCSpinCount, "BGCSpinCount", NULL, 140, "Specifies the bgc spin count") \ INT_CONFIG (BGCSpin, "BGCSpin", NULL, 2, "Specifies the bgc spin time") \ INT_CONFIG (HeapCount, "GCHeapCount", "System.GC.HeapCount", 0, "Specifies the number of server GC heaps") \ + INT_CONFIG (MaxHeapCount, "GCMaxHeapCount", "System.GC.MaxHeapCount", 0, "Specifies the max number of server GC heaps to adjust to") \ INT_CONFIG (Gen0Size, "GCgen0size", NULL, 0, "Specifies the smallest gen0 budget") \ INT_CONFIG (SegmentSize, "GCSegmentSize", NULL, 0, "Specifies the managed heap segment size") \ INT_CONFIG (LatencyMode, "GCLatencyMode", NULL, -1, "Specifies the GC latency mode - batch, interactive or low latency (note that the same " \ diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h index 1a73add83b429f..cce6c5ee28adf0 100644 --- a/src/coreclr/gc/gcpriv.h +++ b/src/coreclr/gc/gcpriv.h @@ -402,8 +402,6 @@ struct GCDebugSpinLock { #if defined(DYNAMIC_HEAP_COUNT) // time in microseconds we wait for the more space lock uint64_t msl_wait_time; - // number of times we wait for the more space lock - uint64_t msl_wait_count; #endif //DYNAMIC_HEAP_COUNT GCDebugSpinLock() @@ -415,7 +413,7 @@ struct GCDebugSpinLock { , num_switch_thread(0), num_wait_longer(0), num_switch_thread_w(0), num_disable_preemptive_w(0) #endif #if defined(DYNAMIC_HEAP_COUNT) - , msl_wait_time(0), msl_wait_count(0) + , msl_wait_time(0) #endif //DYNAMIC_HEAP_COUNT { } @@ -1148,15 +1146,12 @@ class dynamic_data // // The following 3 fields are updated at the beginning of each GC, if that GC condemns this generation. // - // The number of GC that condemned this generation. The only difference between this - // and collection_count is just that collection_count is maintained for all physical generations - // (currently there are 5) whereas this is only updated for logical generations (there are 3). - size_t gc_clock; - uint64_t time_clock; //time when this gc started + size_t gc_clock; // the gc index + uint64_t time_clock; // time when this gc started uint64_t previous_time_clock; // time when previous gc started // Updated at the end of a GC, if that GC condemns this generation. - size_t gc_elapsed_time; // Time it took for the gc to complete + size_t gc_elapsed_time; // time it took for the gc to complete // // The following fields (and fields in sdata) are initialized during GC init time and do not change. @@ -1495,6 +1490,8 @@ class mark_queue_t void verify_empty(); }; +float median_of_3 (float a, float b, float c); + //class definition of the internal class class gc_heap { @@ -2422,6 +2419,7 @@ class gc_heap #ifndef USE_REGIONS PER_HEAP_METHOD void rearrange_heap_segments(BOOL compacting); #endif //!USE_REGIONS + PER_HEAP_METHOD void delay_free_segments(); PER_HEAP_ISOLATED_METHOD void distribute_free_regions(); #ifdef BACKGROUND_GC PER_HEAP_ISOLATED_METHOD void reset_write_watch_for_gc_heap(void* base_address, size_t region_size); @@ -2597,11 +2595,17 @@ class gc_heap // re-initialize a heap in preparation to putting it back into service PER_HEAP_METHOD void recommission_heap(); + PER_HEAP_ISOLATED_METHOD size_t get_num_completed_gcs(); + + PER_HEAP_ISOLATED_METHOD int calculate_new_heap_count(); + // check if we should change the heap count PER_HEAP_METHOD void check_heap_count(); - PER_HEAP_METHOD bool prepare_to_change_heap_count (int new_n_heaps); + PER_HEAP_ISOLATED_METHOD bool prepare_to_change_heap_count (int new_n_heaps); PER_HEAP_METHOD bool change_heap_count (int new_n_heaps); + + PER_HEAP_ISOLATED_METHOD size_t get_msl_wait_time(); #endif //DYNAMIC_HEAP_COUNT #endif //USE_REGIONS @@ -3778,6 +3782,13 @@ class gc_heap PER_HEAP_FIELD_MAINTAINED mark* loh_pinned_queue; #endif //FEATURE_LOH_COMPACTION +#ifdef DYNAMIC_HEAP_COUNT + PER_HEAP_FIELD_MAINTAINED GCEvent gc_idle_thread_event; +#ifdef BACKGROUND_GC + PER_HEAP_FIELD_MAINTAINED GCEvent bgc_idle_thread_event; +#endif //BACKGROUND_GC +#endif //DYNAMIC_HEAP_COUNT + /******************************************/ // PER_HEAP_FIELD_MAINTAINED_ALLOC fields // /******************************************/ @@ -4084,7 +4095,6 @@ class gc_heap // These 2 fields' values do not change but are set/unset per GC PER_HEAP_ISOLATED_FIELD_SINGLE_GC GCEvent gc_start_event; PER_HEAP_ISOLATED_FIELD_SINGLE_GC GCEvent ee_suspend_event; - PER_HEAP_ISOLATED_FIELD_SINGLE_GC GCEvent gc_idle_thread_event; // Also updated on the heap#0 GC thread because that's where we are actually doing the decommit. PER_HEAP_ISOLATED_FIELD_SINGLE_GC BOOL gradual_decommit_in_progress_p; @@ -4163,6 +4173,10 @@ class gc_heap PER_HEAP_ISOLATED_FIELD_SINGLE_GC uint8_t* gc_high; // high end of the highest region being condemned #endif //USE_REGIONS +#ifdef STRESS_DYNAMIC_HEAP_COUNT + PER_HEAP_ISOLATED_FIELD_SINGLE_GC int heaps_in_this_gc; +#endif //STRESS_DYNAMIC_HEAP_COUNT + /**************************************************/ // PER_HEAP_ISOLATED_FIELD_SINGLE_GC_ALLOC fields // /**************************************************/ @@ -4261,37 +4275,65 @@ class gc_heap #endif //USE_REGIONS #ifdef DYNAMIC_HEAP_COUNT + // Sample collection - + // + // For every GC, we collect the msl wait time + GC pause duration info and use both to calculate the + // throughput cost percentage. We will also be using the wait time and the GC pause duration separately + // for other purposes in the future. + // + // For all gen2 GCs we also keep a separate array currently just for the GC cost. This serves as a backstop + // to smooth out the situation when we rarely pick the gen2 GCs in the first array. struct dynamic_heap_count_data_t { static const int sample_size = 3; struct sample { - uint64_t elapsed_between_gcs; // time between gcs in microseconds - uint64_t gc_elapsed_time; // time the gc took - uint64_t soh_msl_wait_time; // time the allocator spent waiting for the soh msl lock - uint64_t uoh_msl_wait_time; // time the allocator spent waiting for the uoh msl lock - size_t allocating_thread_count;// number of allocating threads - size_t heap_size; + uint64_t elapsed_between_gcs; // time between gcs in microseconds (this should really be between_pauses) + uint64_t gc_pause_time; // pause time for this GC + uint64_t msl_wait_time; }; - unsigned sample_index; + uint32_t sample_index; sample samples[sample_size]; + size_t prev_num_completed_gcs; + + uint32_t gen2_sample_index; + // This is (gc_elapsed_time / time inbetween this and the last gen2 GC) + float gen2_gc_percents[sample_size]; - float median_percent_overhead; // estimated overhead of allocator + gc - float smoothed_median_percent_overhead; // exponentially smoothed version - float percent_heap_space_cost_per_heap; // percent space cost of adding a heap - float overhead_reduction_per_step_up; // percentage effect on overhead of increasing heap count - float overhead_increase_per_step_down; // percentage effect on overhead of decreasing heap count - float space_cost_increase_per_step_up; // percentage effect on space of increasing heap count - float space_cost_decrease_per_step_down;// percentage effect on space of decreasing heap count + float median_throughput_cost_percent; // estimated overhead of allocator + gc + float smoothed_median_throughput_cost_percent; // exponentially smoothed version + float percent_heap_space_cost_per_heap; // percent space cost of adding a heap + float tcp_reduction_per_step_up; // throughput cost percent effect of increasing heap count + float tcp_increase_per_step_down; // throughput cost percent effect of decreasing heap count + float scp_increase_per_step_up; // space cost percent effect of increasing heap count + float scp_decrease_per_step_down; // space cost percent effect of decreasing heap count int new_n_heaps; + // the heap count we changed from + int last_n_heaps; + // don't start a GC till we see (n_max_heaps - new_n_heaps) number of threads idling + VOLATILE(int32_t) idle_thread_count; + bool init_only_p; + + bool should_change_heap_count; + int heap_count_to_change_to; + int heap_count_change_count; #ifdef STRESS_DYNAMIC_HEAP_COUNT int lowest_heap_with_msl_uoh; #endif //STRESS_DYNAMIC_HEAP_COUNT + + float get_median_gen2_gc_percent() + { + return median_of_3 (gen2_gc_percents[0], gen2_gc_percents[1], gen2_gc_percents[2]); + } }; PER_HEAP_ISOLATED_FIELD_MAINTAINED dynamic_heap_count_data_t dynamic_heap_count_data; + PER_HEAP_ISOLATED_FIELD_MAINTAINED uint64_t last_suspended_end_time; + // If the last full GC is blocking, this is that GC's index; for BGC, this is the settings.gc_index + // when the BGC ended. + PER_HEAP_ISOLATED_FIELD_MAINTAINED size_t gc_index_full_gc_end; #endif //DYNAMIC_HEAP_COUNT /****************************************************/ @@ -4867,7 +4909,6 @@ uint64_t& dd_previous_time_clock (dynamic_data* inst) return inst->previous_time_clock; } - inline size_t& dd_gc_clock_interval (dynamic_data* inst) { From 18bfe59bc967529e633498ad20c9710a5e4752d0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 09:26:56 -0700 Subject: [PATCH 288/783] Update dependencies from https://github.com/dotnet/emsdk build 20230919.4 (#92322) Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rc.2.23469.1 -> To Version 8.0.0-rc.2.23469.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 489044e0d17884..bb8f1d633fbb01 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,9 +90,9 @@ 89be445dd4936157533ad96bafb95f701430653a - + https://github.com/dotnet/emsdk - ca3e8e40f417e421141638c66dd301395afee66d + ea0e8e8214e9acc0cba7e78a836ed6656f788d11 diff --git a/eng/Versions.props b/eng/Versions.props index d56eeab17ef17d..61344b9a916136 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.0-rc.2.23469.1 + 8.0.0-rc.2.23469.4 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda From 49bf70a429a6122217f2c88e778ce8115ceac3bd Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 09:30:17 -0700 Subject: [PATCH 289/783] Update dependencies from https://github.com/dotnet/source-build-externals build 20230919.1 (#92340) Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.23468.1 -> To Version 8.0.0-alpha.1.23469.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 04567c6742f81f..951d1ef1c05f97 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -100,9 +100,9 @@ d825c6693d4e26f63aaa93c3c1d057faa098e347 - + https://github.com/dotnet/source-build-externals - e9d6489787a5ea5400a31dfa34aa6ad6b590de9b + c42a7ce3b6fa02957e7b4ef995c5c2a9a23d294c From f52a29561c30ccd7475e40a4fb56928738a6eac2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 13:19:28 -0700 Subject: [PATCH 290/783] [release/8.0-rc1] [release/8.0] Fix wasi build. (#92368) * Fix wasi build. * dummy change in wasi README to trigger a build * dummy change in wasi to trigger a build --------- Co-authored-by: Zoltan Varga Co-authored-by: Ankit Jain --- eng/pipelines/common/templates/pipeline-with-resources.yml | 4 ++-- src/mono/wasi/README.md | 3 ++- src/mono/wasi/build/WasiApp.targets | 2 -- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/eng/pipelines/common/templates/pipeline-with-resources.yml b/eng/pipelines/common/templates/pipeline-with-resources.yml index c30ce8597808d8..02242394fba671 100644 --- a/eng/pipelines/common/templates/pipeline-with-resources.yml +++ b/eng/pipelines/common/templates/pipeline-with-resources.yml @@ -85,12 +85,12 @@ resources: image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8 - container: browser_wasm - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly-20230913040940-1edc1c6 env: ROOTFS_DIR: /crossrootfs/x64 - container: wasi_wasm - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly-20230913040940-1edc1c6 env: ROOTFS_DIR: /crossrootfs/x64 diff --git a/src/mono/wasi/README.md b/src/mono/wasi/README.md index 66e59384297bb3..4c8759006359da 100644 --- a/src/mono/wasi/README.md +++ b/src/mono/wasi/README.md @@ -17,6 +17,7 @@ or for just native rebuild ./build.sh -bl -os wasi -subset mono.runtime+libs.native+mono.wasiruntime -c Debug ``` + ### 3. Run it Finally, you can build and run the sample: @@ -49,4 +50,4 @@ Download the Mono Debug extension and configure a launch.json like this: } ] } -``` \ No newline at end of file +``` diff --git a/src/mono/wasi/build/WasiApp.targets b/src/mono/wasi/build/WasiApp.targets index 1b8fc4e3fa9333..099ba8c3ebea27 100644 --- a/src/mono/wasi/build/WasiApp.targets +++ b/src/mono/wasi/build/WasiApp.targets @@ -4,8 +4,6 @@ - 8.0.100-rc.1.23415.5 1.1.2-beta1.23323.1 8.0.0-preview-20230918.1 @@ -257,5 +255,8 @@ 3.1.7 1.0.406601 + + 8.0.100-rc.2.23470.7 + $(MicrosoftDotnetSdkInternalVersion) diff --git a/src/mono/wasm/README.md b/src/mono/wasm/README.md index 34c18bc8711468..cdace086f5603e 100644 --- a/src/mono/wasm/README.md +++ b/src/mono/wasm/README.md @@ -350,3 +350,12 @@ npm update --lockfile-version=1 | Multi-thread | linux: build only | none | * `high resource aot` runs a few specific library tests with AOT, that require more memory to AOT. + + +# Perf pipeline + +TBD + +## Updates needed + +- when the base OS is upgraded, check if the version of node installed in the `eng/pipelines/coreclr/templates/run-performance-job.yml` needs an upgrade too. diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/MiscTests3.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/MiscTests3.cs index 10717b334174b9..b006bf7a93e5c3 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/MiscTests3.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/MiscTests3.cs @@ -63,7 +63,7 @@ public static class MyDllImports public static extern int cpp_add(int a, int b); }}"; - File.WriteAllText(Path.Combine(_projectDir!, "Pages", "MyDllImport.cs"), myDllImportCs); + File.WriteAllText(Path.Combine(_projectDir!, "Components", "Pages", "MyDllImport.cs"), myDllImportCs); AddItemsPropertiesToProject(projectFile, extraItems: @""); BlazorAddRazorButton("cpp_add", """ @@ -144,7 +144,7 @@ public void BugRegression_60479_WithRazorClassLib() Assert.Contains(razorClassLibraryFileName, lazyVal.EnumerateObject().Select(jp => jp.Name)); } - private void BlazorAddRazorButton(string buttonText, string customCode, string methodName = "test", string razorPage = "Pages/Counter.razor") + private void BlazorAddRazorButton(string buttonText, string customCode, string methodName = "test", string razorPage = "Components/Pages/Counter.razor") { string additionalCode = $$"""

Output: @outputText

diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/WorkloadRequiredTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/WorkloadRequiredTests.cs index cbe3e461ec9cde..7ca663dce5372f 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/WorkloadRequiredTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/WorkloadRequiredTests.cs @@ -84,7 +84,7 @@ public async Task WorkloadNotRequiredForInvariantGlobalization(string config, bo if (invariant) AddItemsPropertiesToProject(projectFile, extraProperties: "true"); - string counterPath = Path.Combine(Path.GetDirectoryName(projectFile)!, "Pages", "Counter.razor"); + string counterPath = Path.Combine(Path.GetDirectoryName(projectFile)!, "Components", "Pages", "Counter.razor"); string allText = File.ReadAllText(counterPath); string ccText = "currentCount++;"; if (allText.IndexOf(ccText) < 0) diff --git a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs index e520057d5b3bdf..224527142fa898 100644 --- a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs +++ b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs @@ -215,7 +215,7 @@ private bool InstallPacks(InstallWorkloadRequest req, string nugetConfigContents (int exitCode, string output) = Utils.TryRunProcess( Log, Path.Combine(req.TargetPath, "dotnet"), - $"workload install --skip-manifest-update --configfile \"{nugetConfigPath}\" --temp-dir \"{_tempDir}/workload-install-temp\" {req.WorkloadId}", + $"workload install --skip-manifest-update --skip-sign-check --configfile \"{nugetConfigPath}\" --temp-dir \"{_tempDir}/workload-install-temp\" {req.WorkloadId}", workingDir: _tempDir, envVars: new Dictionary () { ["NUGET_PACKAGES"] = _nugetCachePath From 1361b189a45e312958e3f8509f053150300b494f Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Wed, 20 Sep 2023 19:15:45 -0400 Subject: [PATCH 292/783] Update dependencies from dotnet/emsdk Picking the update from https://github.com/dotnet/runtime/pull/92320 to here, to avoid the overlap. --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9bedd07535a17d..f33ad2fde34080 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,9 +90,9 @@ 89be445dd4936157533ad96bafb95f701430653a
- + https://github.com/dotnet/emsdk - ea0e8e8214e9acc0cba7e78a836ed6656f788d11 + 446eeb331fcbf2f48c14a377601a8ab950ec942e diff --git a/eng/Versions.props b/eng/Versions.props index abf8964b954d1c..a8dc199cc94ed3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -238,7 +238,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.0-rc.2.23469.4 + 8.0.0-rtm.23470.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda From 02d408eeb7e74d6cbc58807eb5c418180e6b6909 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Wed, 20 Sep 2023 16:41:07 -0400 Subject: [PATCH 293/783] [wasm] InstallWorkloadFromArtifacts: correctly handle rtm versions In case of a version like `8.0.100-rtm.23470.1`, we incorrectly extracted `-rtm.23470` instead of `-rtm`, which resulted in trying to install package named `Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100-rtm.23470` instead of `Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100-rtm`. --- src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs index 224527142fa898..62817719af0a14 100644 --- a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs +++ b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs @@ -49,7 +49,7 @@ public partial class InstallWorkloadFromArtifacts : Task private string _tempDir = string.Empty; private string _nugetCachePath = string.Empty; - [GeneratedRegex(@"^\d+\.\d+\.\d+(-[A-z]*\.*\d*)?")] + [GeneratedRegex(@"^\d+\.\d+\.\d+(-rtm|-[A-z]*\.*\d*)?")] private static partial Regex bandVersionRegex(); public override bool Execute() From c4ea964c38a09a86871d9ad19deefe5fb5070315 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 02:24:03 -0700 Subject: [PATCH 294/783] Add missing case for constrained gsharedvt call. (#92347) https://github.com/dotnet/runtime/commit/1b788f4dc3e3a8829488e52c032ad6a70671e070 added a new value to our MonoRgctxInfoType enum type, but appears that all cases where not full adjusted. Running System.Buffers tests in full AOT hits the assert in info_equal about missing case, https://github.com/dotnet/runtime/blob/0dc5903679606b072adac70a268cdb77d1147b3e/src/mono/mono/mini/mini-generic-sharing.c#L2908. This commit adds the new enum value and align handling similar to other cases added by that commit. Co-authored-by: lateralusX --- src/mono/mono/mini/mini-generic-sharing.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index 6ad8dcb0075cfc..c131d51a6bd070 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -2886,7 +2886,8 @@ info_equal (gpointer data1, gpointer data2, MonoRgctxInfoType info_type) return data1 == data2; case MONO_RGCTX_INFO_VIRT_METHOD: case MONO_RGCTX_INFO_VIRT_METHOD_CODE: - case MONO_RGCTX_INFO_VIRT_METHOD_BOX_TYPE: { + case MONO_RGCTX_INFO_VIRT_METHOD_BOX_TYPE: + case MONO_RGCTX_INFO_GSHAREDVT_CONSTRAINED_CALL_INFO: { MonoJumpInfoVirtMethod *info1 = (MonoJumpInfoVirtMethod *)data1; MonoJumpInfoVirtMethod *info2 = (MonoJumpInfoVirtMethod *)data2; From 8ae598eed28b27cb15c75abf61c7abf0fdd9f367 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 02:24:45 -0700 Subject: [PATCH 295/783] [release/8.0-rc2] Fixes for LLVM AOT on Windows from @lateralusX (#92365) * Fixes for LLVM AOT on Windows from @lateralusX * fix HOST/TARGET issue --------- Co-authored-by: Jo Shields --- src/mono/mono/mini/aot-compiler.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index e067d2714d8a37..c342ef5d007571 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -10708,6 +10708,18 @@ execute_system (const char * command) #ifdef ENABLE_LLVM +#ifdef HOST_WIN32 +#define OPT_NAME "opt.exe" +#else +#define OPT_NAME "opt" +#endif + +#ifdef HOST_WIN32 +#define LLC_NAME "llc.exe" +#else +#define LLC_NAME "llc" +#endif + /* * emit_llvm_file: * @@ -10776,11 +10788,11 @@ emit_llvm_file (MonoAotCompile *acfg) } else { #if LLVM_API_VERSION >= 1600 /* The safepoints pass requires new pass manager syntax*/ - opts = g_strdup ("-disable-tail-calls -passes='"); + opts = g_strdup ("-disable-tail-calls -passes=\""); if (!acfg->aot_opts.llvm_only) { opts = g_strdup_printf ("%sdefault,", opts); } - opts = g_strdup_printf ("%splace-safepoints' -spp-all-backedges", opts); + opts = g_strdup_printf ("%splace-safepoints\" -spp-all-backedges", opts); #elif LLVM_API_VERSION >= 1300 /* The safepoints pass requires the old pass manager */ opts = g_strdup ("-disable-tail-calls -place-safepoints -spp-all-backedges -enable-new-pm=0"); @@ -10810,7 +10822,7 @@ emit_llvm_file (MonoAotCompile *acfg) opts = g_strdup_printf ("%s -fp-contract=fast -enable-no-infs-fp-math -enable-no-nans-fp-math -enable-no-signed-zeros-fp-math -enable-no-trapping-fp-math -enable-unsafe-fp-math", opts); } - command = g_strdup_printf ("\"%sopt\" -f %s -o \"%s\" \"%s\"", acfg->aot_opts.llvm_path, opts, optbc, tempbc); + command = g_strdup_printf ("\"%s" OPT_NAME "\" -f %s -o \"%s\" \"%s\"", acfg->aot_opts.llvm_path, opts, optbc, tempbc); aot_printf (acfg, "Executing opt: %s\n", command); if (execute_system (command) != 0) return FALSE; @@ -10885,7 +10897,7 @@ emit_llvm_file (MonoAotCompile *acfg) g_string_append_printf (acfg->llc_args, " -mattr=%s", acfg->aot_opts.llvm_cpu_attr); } - command = g_strdup_printf ("\"%sllc\" %s -o \"%s\" \"%s.opt.bc\"", acfg->aot_opts.llvm_path, acfg->llc_args->str, output_fname, acfg->tmpbasename); + command = g_strdup_printf ("\"%s" LLC_NAME "\" %s -o \"%s\" \"%s.opt.bc\"", acfg->aot_opts.llvm_path, acfg->llc_args->str, output_fname, acfg->tmpbasename); g_free (output_fname); aot_printf (acfg, "Executing llc: %s\n", command); From 1757497f37245d1756870fb1c0b3221c0d235d54 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 02:25:17 -0700 Subject: [PATCH 296/783] [release/8.0] Properly handle debugger-enumerating interior pointers and enregistered refs (#92360) * Fix issue with enregistered values * Fix assert and enregistered ref reporting * Fix issue from merge --------- Co-authored-by: Lee Culver Co-authored-by: Juan Sebastian Hoyos Ayala Co-authored-by: Juan Hoyos <19413848+hoyosjs@users.noreply.github.com> --- src/coreclr/debug/daccess/dacdbiimpl.cpp | 3 ++- src/coreclr/debug/di/rsclass.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp index 67d5b1e60d948c..07208001b0c3b8 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -7788,8 +7788,9 @@ HRESULT DacStackReferenceWalker::Next(ULONG count, DacGcReference stackRefs[], U stackRefs[i].i64ExtraData = 0; const SOSStackRefData &sosStackRef = mList.Get(i); - if (sosStackRef.Flags & GC_CALL_INTERIOR) + if (sosStackRef.Flags & GC_CALL_INTERIOR || sosStackRef.Address == 0) { + // Direct pointer case - interior pointer, Frame ref, or enregistered var. stackRefs[i].pObject = CLRDATA_ADDRESS_TO_TADDR(sosStackRef.Object) | 1; } else diff --git a/src/coreclr/debug/di/rsclass.cpp b/src/coreclr/debug/di/rsclass.cpp index ec52823c07af5f..55f83b48a6d211 100644 --- a/src/coreclr/debug/di/rsclass.cpp +++ b/src/coreclr/debug/di/rsclass.cpp @@ -132,6 +132,7 @@ HRESULT CordbClass::GetStaticFieldValue(mdFieldDef fieldDef, IMetaDataImport * pImport = NULL; EX_TRY { + RSLockHolder lockHolder(GetProcess()->GetProcessLock()); pImport = GetModule()->GetMetaDataImporter(); // throws // Validate the token. @@ -1191,4 +1192,3 @@ HRESULT CordbClass::SearchFieldInfo( // Well, the field doesn't even belong to this class... ThrowHR(E_INVALIDARG); } - From 12fc9044307e32e143eb7cbaf1d68badf61b192c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 08:35:35 -0700 Subject: [PATCH 297/783] Fix the VN for xor operation (#92372) Co-authored-by: Kunal Pathak --- src/coreclr/jit/valuenum.cpp | 2 +- .../JitBlue/Runtime_91252/Runtime_91252.cs | 37 +++++++++++++++++++ .../Runtime_91252/Runtime_91252.csproj | 8 ++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91252/Runtime_91252.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_91252/Runtime_91252.csproj diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 2ea2ee7845b8b2..2c638535d786e4 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -7891,7 +7891,7 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary(var_types type, #endif { // Handle `x ^ x == 0` - return arg0VN; + return VNZeroForType(type); } default: diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91252/Runtime_91252.cs b/src/tests/JIT/Regression/JitBlue/Runtime_91252/Runtime_91252.cs new file mode 100644 index 00000000000000..d4035f3de978fc --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91252/Runtime_91252.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// This test verifies if we correctly value number the operation of +// x ^ x to zero. +// +// Found by Antigen + +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using Xunit; + +public class Issue_91252 +{ + static Vector64 s_v64_int_22 = Vector64.Create(-5); + Vector64 v64_int_72 = Vector64.Create(-1); + + [MethodImpl(MethodImplOptions.NoInlining)] + public int Repro() + { + s_v64_int_22 = v64_int_72; + return Check(v64_int_72 ^ v64_int_72); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public int Check(Vector64 a) + { + return (a == Vector64.Zero) ? 100 : 101; + } + + [Fact] + public static int EntryPoint() + { + var obj = new Issue_91252(); + return obj.Repro(); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_91252/Runtime_91252.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_91252/Runtime_91252.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_91252/Runtime_91252.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From 76252f33738dc02f5015510c5ebc52280a0c448b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 09:34:09 -0700 Subject: [PATCH 298/783] [release/8.0] Update dependencies from dotnet/roslyn (#92303) * Update dependencies from https://github.com/dotnet/roslyn build 20230919.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23469.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230919.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23469.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230919.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23469.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230919.7 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23469.7 * Update dependencies from https://github.com/dotnet/roslyn build 20230919.9 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23469.9 * Update dependencies from https://github.com/dotnet/roslyn build 20230919.10 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23469.10 * Update dependencies from https://github.com/dotnet/roslyn build 20230919.11 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23469.11 * Update dependencies from https://github.com/dotnet/roslyn build 20230920.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23470.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230920.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23470.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230920.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23470.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230920.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23470.5 * Update dependencies from https://github.com/dotnet/roslyn build 20230920.7 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23470.7 * Update dependencies from https://github.com/dotnet/roslyn build 20230920.8 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23470.8 * Update dependencies from https://github.com/dotnet/roslyn build 20230920.10 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23470.10 * Update dependencies from https://github.com/dotnet/roslyn build 20230920.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23470.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230920.12 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23470.12 * Update dependencies from https://github.com/dotnet/roslyn build 20230921.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23471.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230921.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23469.1 -> To Version 4.8.0-3.23471.2 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f12a5b894116f2..e40acd650b02cb 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - 9233e36abc5e2ca263dbd4d1616f35623440a935 + 9f6f97debe7fe8121a2249f807343d12ef1e4ac6 - + https://github.com/dotnet/roslyn - 9233e36abc5e2ca263dbd4d1616f35623440a935 + 9f6f97debe7fe8121a2249f807343d12ef1e4ac6 - + https://github.com/dotnet/roslyn - 9233e36abc5e2ca263dbd4d1616f35623440a935 + 9f6f97debe7fe8121a2249f807343d12ef1e4ac6 https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index a8dc199cc94ed3..566506f35543b1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -42,9 +42,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23469.1 - 4.8.0-3.23469.1 - 4.8.0-3.23469.1 + 4.8.0-3.23471.2 + 4.8.0-3.23471.2 + 4.8.0-3.23471.2 false release - -$(PreReleaseVersionLabel).$(PreReleaseVersionIteration) + -$(PreReleaseVersionLabel) + -$(PreReleaseVersionLabel).$(PreReleaseVersionIteration) $(SdkBandVersion)$(WorkloadVersionSuffix) false From d365be87223a7b3575f45b4abac30e742a4619fa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 15:37:09 -0700 Subject: [PATCH 301/783] JIT: Fix invalid containment of vector broadcasts (#92371) The containment checks for vector broadcasts were missing a size check, meaning that a uint broadcast could contain a ubyte/ushort indirection. That would lead to out-of-bounds reads. Fix #83387 Co-authored-by: Jakob Botsch Nielsen --- src/coreclr/jit/gentree.cpp | 4 ++-- src/coreclr/jit/lowerxarch.cpp | 3 +++ .../JitBlue/Runtime_83387/Runtime_83387.cs | 19 +++++++++++++++++++ .../Runtime_83387/Runtime_83387.csproj | 8 ++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_83387/Runtime_83387.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_83387/Runtime_83387.csproj diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index a30c3794efdd29..d6d524f375ea73 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -19639,8 +19639,8 @@ GenTree* Compiler::gtNewSimdBinOpNode( } else { - assert(op2->TypeIs(type, simdBaseType, genActualType(simdBaseType)) || - (op2->TypeIs(TYP_SIMD12) && type == TYP_SIMD16)); + assert((genActualType(op2) == genActualType(type)) || (genActualType(op2) == genActualType(simdBaseType)) || + (op2->TypeIs(TYP_SIMD12) && (type == TYP_SIMD16))); } NamedIntrinsic intrinsic = NI_Illegal; diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index d1c3e317d83b87..30c2a832b94fc1 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -7956,6 +7956,9 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre // The memory form of this already takes a pointer and should be treated like a MemoryLoad supportsGeneralLoads = !childNode->OperIsHWIntrinsic(); } + + supportsGeneralLoads = + supportsGeneralLoads && (genTypeSize(childNode) >= genTypeSize(parentNode->GetSimdBaseType())); break; } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_83387/Runtime_83387.cs b/src/tests/JIT/Regression/JitBlue/Runtime_83387/Runtime_83387.cs new file mode 100644 index 00000000000000..cb70acd1677573 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_83387/Runtime_83387.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using Xunit; + +public class Runtime_83387 +{ + [MethodImpl(MethodImplOptions.NoOptimization)] + [Fact] + public static int TestEntryPoint() + { + (ushort A, ushort R) c = (1, 65535); + Vector128 v1 = Vector128.Create((uint)100); + v1 = v1 * c.A; + return (int)v1.ToScalar(); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_83387/Runtime_83387.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_83387/Runtime_83387.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_83387/Runtime_83387.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From 79bd0070701302c28aa820376c0b029d15f51ac0 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Thu, 21 Sep 2023 15:37:35 -0700 Subject: [PATCH 302/783] [release/8.0-rc2] Bump downlevel version to 7.0.12 (#92419) Co-authored-by: Steve Pfister --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index abf8964b954d1c..a7d36117e12b76 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,7 +7,7 @@ 0 0 8.0.100 - 7.0.11 + 7.0.12 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) rc 2 From b1dbbb964a4daba07fe13c4150133f1d5d41ceb0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 18:54:40 -0700 Subject: [PATCH 303/783] [release/8.0-rc2] [browser] Fix SIMD+EH check (#92439) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Move simd+eh check after emcripten provided build time values * Call cwraps.mono_wasm_abort from runtimeHelpers.abort when cwraps are ready (onRuntimeInitializedAsync) * Assign early mono_wasm_exit and abort even earlier * Fire feature check before awaiting wasm download, but await it after. * Whitespaces --------- Co-authored-by: Marek Fišera --- src/mono/wasm/runtime/globals.ts | 6 +++++ src/mono/wasm/runtime/startup.ts | 38 ++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/mono/wasm/runtime/globals.ts b/src/mono/wasm/runtime/globals.ts index 66948642bbc55c..88be75543ab4e5 100644 --- a/src/mono/wasm/runtime/globals.ts +++ b/src/mono/wasm/runtime/globals.ts @@ -66,6 +66,12 @@ export function setRuntimeGlobals(globalObjects: GlobalObjects) { beforeOnRuntimeInitialized: createPromiseController(), afterOnRuntimeInitialized: createPromiseController(), afterPostRun: createPromiseController(), + mono_wasm_exit: () => { + throw new Error("Mono shutdown"); + }, + abort: (reason: any) => { + throw reason; + } }); Object.assign(globalObjects.module.config!, {}) as any; diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index e6f8d80ef82f48..d8eab74d8b2500 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -40,15 +40,7 @@ import { assertNoProxies } from "./gc-handles"; const MONO_PTHREAD_POOL_SIZE = 4; export async function configureRuntimeStartup(): Promise { - if (linkerWasmEnableSIMD) { - mono_assert(await loaderHelpers.simd(), "This browser/engine doesn't support WASM SIMD. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); - } - if (linkerWasmEnableEH) { - mono_assert(await loaderHelpers.exceptions(), "This browser/engine doesn't support WASM exception handling. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); - } - await init_polyfills_async(); - await checkMemorySnapshotSize(); } @@ -240,6 +232,15 @@ async function onRuntimeInitializedAsync(userOnRuntimeInitialized: () => void) { // wait for previous stage await runtimeHelpers.afterPreRun.promise; mono_log_debug("onRuntimeInitialized"); + + runtimeHelpers.mono_wasm_exit = cwraps.mono_wasm_exit; + runtimeHelpers.abort = (reason: any) => { + if (!loaderHelpers.is_exited()) { + cwraps.mono_wasm_abort(); + } + throw reason; + }; + const mark = startMeasure(); // signal this stage, this will allow pending assets to allocate memory runtimeHelpers.beforeOnRuntimeInitialized.promise_control.resolve(); @@ -361,13 +362,6 @@ function mono_wasm_pre_init_essential(isWorker: boolean): void { } init_c_exports(); - runtimeHelpers.mono_wasm_exit = cwraps.mono_wasm_exit; - runtimeHelpers.abort = (reason: any) => { - if (!loaderHelpers.is_exited()) { - cwraps.mono_wasm_abort(); - } - throw reason; - }; cwraps_internal(INTERNAL); if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop) { cwraps_mono_api(MONO); @@ -386,7 +380,6 @@ async function mono_wasm_pre_init_essential_async(): Promise { mono_log_debug("mono_wasm_pre_init_essential_async"); Module.addRunDependency("mono_wasm_pre_init_essential_async"); - if (MonoWasmThreads) { preAllocatePThreadWorkerPool(MONO_PTHREAD_POOL_SIZE, runtimeHelpers.config); } @@ -466,8 +459,12 @@ async function instantiate_wasm_module( await runtimeHelpers.beforePreInit.promise; Module.addRunDependency("instantiate_wasm_module"); + const wasmFeaturePromise = ensureUsedWasmFeatures(); + replace_linker_placeholders(imports); const assetToLoad = await loaderHelpers.wasmDownloadPromise.promise; + + await wasmFeaturePromise; await instantiate_wasm_asset(assetToLoad, imports, successCallback); assetToLoad.pendingDownloadInternal = null as any; // GC assetToLoad.pendingDownload = null as any; // GC @@ -499,6 +496,15 @@ async function instantiate_wasm_module( Module.removeRunDependency("instantiate_wasm_module"); } +async function ensureUsedWasmFeatures() { + if (linkerWasmEnableSIMD) { + mono_assert(await loaderHelpers.simd(), "This browser/engine doesn't support WASM SIMD. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); + } + if (linkerWasmEnableEH) { + mono_assert(await loaderHelpers.exceptions(), "This browser/engine doesn't support WASM exception handling. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); + } +} + async function mono_wasm_before_memory_snapshot() { const mark = startMeasure(); if (runtimeHelpers.loadedMemorySnapshotSize) { From 63d0c6454c7f9530140bc7aa9d97790996f21d08 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 18:58:50 -0700 Subject: [PATCH 304/783] [release/8.0-rc2] Address feedback and fix some TensorPrimitives issues (#92437) * Address feedback and fix some TensorPrimitives issues - Added a few APIs based on initial feedback: Abs (vectorized), Log2, and element-wise Max/Min{Magnitude} - Renamed L2Normalize to Norm - Fixed semantics of Min/MaxMagnitude to return original value rather than the absolute value - Renamed a few helper types for consistency - Added tests * Add a few more uses of Tolerance --------- Co-authored-by: Stephen Toub --- .../ref/System.Numerics.Tensors.cs | 8 +- .../Numerics/Tensors/TensorPrimitives.cs | 147 ++++++++- .../Tensors/TensorPrimitives.netcore.cs | 12 +- .../Tensors/TensorPrimitives.netstandard.cs | 12 +- .../tests/TensorPrimitivesTests.cs | 285 +++++++++++++++--- 5 files changed, 410 insertions(+), 54 deletions(-) diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.cs b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.cs index 50eaa00160e5cb..99bd4703574e55 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.cs +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.cs @@ -8,6 +8,7 @@ namespace System.Numerics.Tensors { public static partial class TensorPrimitives { + public static void Abs(System.ReadOnlySpan x, System.Span destination) { } public static void Add(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { } public static void Add(System.ReadOnlySpan x, float y, System.Span destination) { } public static void AddMultiply(System.ReadOnlySpan x, System.ReadOnlySpan y, System.ReadOnlySpan multiplier, System.Span destination) { } @@ -24,12 +25,17 @@ public static void Exp(System.ReadOnlySpan x, System.Span destinat public static int IndexOfMaxMagnitude(System.ReadOnlySpan x) { throw null; } public static int IndexOfMin(System.ReadOnlySpan x) { throw null; } public static int IndexOfMinMagnitude(System.ReadOnlySpan x) { throw null; } - public static float L2Normalize(System.ReadOnlySpan x) { throw null; } + public static float Norm(System.ReadOnlySpan x) { throw null; } public static void Log(System.ReadOnlySpan x, System.Span destination) { } + public static void Log2(System.ReadOnlySpan x, System.Span destination) { } public static float Max(System.ReadOnlySpan x) { throw null; } + public static void Max(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { throw null; } public static float MaxMagnitude(System.ReadOnlySpan x) { throw null; } + public static void MaxMagnitude(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { throw null; } public static float Min(System.ReadOnlySpan x) { throw null; } + public static void Min(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { throw null; } public static float MinMagnitude(System.ReadOnlySpan x) { throw null; } + public static void MinMagnitude(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { throw null; } public static void Multiply(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { } public static void Multiply(System.ReadOnlySpan x, float y, System.Span destination) { } public static void MultiplyAdd(System.ReadOnlySpan x, System.ReadOnlySpan y, System.ReadOnlySpan addend, System.Span destination) { } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.cs index a400095b08ad39..d28d4bacafdb8e 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.cs @@ -93,6 +93,14 @@ public static void Divide(ReadOnlySpan x, float y, Span destinatio public static void Negate(ReadOnlySpan x, Span destination) => InvokeSpanIntoSpan(x, destination); + /// Computes the element-wise result of: MathF.Abs(). + /// The tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// This method effectively does [i] = MathF.Abs([i]). + public static void Abs(ReadOnlySpan x, Span destination) => + InvokeSpanIntoSpan(x, destination); + /// Computes the element-wise result of: ( + ) * . /// The first tensor, represented as a span. /// The second tensor, represented as a span. @@ -200,6 +208,24 @@ public static void Log(ReadOnlySpan x, Span destination) } } + /// Computes the element-wise result of: log2(). + /// The tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// This method effectively does [i] = .Log2([i]). + public static void Log2(ReadOnlySpan x, Span destination) + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + for (int i = 0; i < x.Length; i++) + { + destination[i] = Log2(x[i]); + } + } + /// Computes the element-wise result of: cosh(). /// The tensor, represented as a span. /// The destination tensor, represented as a span. @@ -318,9 +344,9 @@ public static float Dot(ReadOnlySpan x, ReadOnlySpan y) // BLAS1: /// /// The first tensor, represented as a span. /// The L2 norm. - public static float L2Normalize(ReadOnlySpan x) // BLAS1: nrm2 + public static float Norm(ReadOnlySpan x) // BLAS1: nrm2 { - return MathF.Sqrt(Aggregate(0f, x)); + return MathF.Sqrt(Aggregate(0f, x)); } /// @@ -345,7 +371,7 @@ public static void SoftMax(ReadOnlySpan x, Span destination) for (int i = 0; i < x.Length; i++) { - expSum += MathF.Pow((float)Math.E, x[i]); + expSum += MathF.Exp(x[i]); } for (int i = 0; i < x.Length; i++) @@ -421,6 +447,31 @@ public static float Max(ReadOnlySpan x) return result; } + /// Computes the element-wise result of: MathF.Max(, ). + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// This method effectively does [i] = MathF.Max([i], [i]). + public static void Max(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + for (int i = 0; i < x.Length; i++) + { + destination[i] = MathF.Max(x[i], y[i]); + } + } + /// Computes the minimum element in . /// The tensor, represented as a span. /// The minimum element in . @@ -464,6 +515,31 @@ public static float Min(ReadOnlySpan x) return result; } + /// Computes the element-wise result of: MathF.Min(, ). + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// This method effectively does [i] = MathF.Min([i], [i]). + public static void Min(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + for (int i = 0; i < x.Length; i++) + { + destination[i] = MathF.Min(x[i], y[i]); + } + } + /// Computes the maximum magnitude of any element in . /// The tensor, represented as a span. /// The maximum magnitude of any element in . @@ -508,7 +584,32 @@ public static float MaxMagnitude(ReadOnlySpan x) } } - return resultMag; + return result; + } + + /// Computes the element-wise result of: MathF.MaxMagnitude(, ). + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// This method effectively does [i] = MathF.MaxMagnitude([i], [i]). + public static void MaxMagnitude(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + for (int i = 0; i < x.Length; i++) + { + destination[i] = MaxMagnitude(x[i], y[i]); + } } /// Computes the minimum magnitude of any element in . @@ -522,6 +623,7 @@ public static float MinMagnitude(ReadOnlySpan x) ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); } + float result = float.PositiveInfinity; float resultMag = float.PositiveInfinity; for (int i = 0; i < x.Length; i++) @@ -543,16 +645,43 @@ public static float MinMagnitude(ReadOnlySpan x) if (currentMag < resultMag) { + result = current; resultMag = currentMag; } } else if (IsNegative(current)) { + result = current; resultMag = currentMag; } } - return resultMag; + return result; + } + + /// Computes the element-wise result of: MathF.MinMagnitude(, ). + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of '' must be same as length of ''. + /// Destination is too short. + /// This method effectively does [i] = MathF.MinMagnitude([i], [i]). + public static void MinMagnitude(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + for (int i = 0; i < x.Length; i++) + { + destination[i] = MinMagnitude(x[i], y[i]); + } } /// Computes the index of the maximum element in . @@ -744,14 +873,14 @@ public static unsafe int IndexOfMinMagnitude(ReadOnlySpan x) /// The tensor, represented as a span. /// The result of adding all elements in , or zero if is empty. public static float Sum(ReadOnlySpan x) => - Aggregate(0f, x); + Aggregate(0f, x); /// Computes the sum of the squares of every element in . /// The tensor, represented as a span. /// The result of adding every element in multiplied by itself, or zero if is empty. /// This method effectively does .Sum(.Multiply(, )). public static float SumOfSquares(ReadOnlySpan x) => - Aggregate(0f, x); + Aggregate(0f, x); /// Computes the sum of the absolute values of every element in . /// The tensor, represented as a span. @@ -761,7 +890,7 @@ public static float SumOfSquares(ReadOnlySpan x) => /// This method corresponds to the asum method defined by BLAS1. /// public static float SumOfMagnitudes(ReadOnlySpan x) => - Aggregate(0f, x); + Aggregate(0f, x); /// Computes the product of all elements in . /// The tensor, represented as a span. @@ -774,7 +903,7 @@ public static float Product(ReadOnlySpan x) ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); } - return Aggregate(1.0f, x); + return Aggregate(1.0f, x); } /// Computes the product of the element-wise result of: + . diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs index ae5af404ac1aff..8eb1769d5eaee8 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs @@ -51,6 +51,12 @@ public static void ConvertToSingle(ReadOnlySpan source, Span destin private static bool IsNegative(float f) => float.IsNegative(f); + private static float MaxMagnitude(float x, float y) => MathF.MaxMagnitude(x, y); + + private static float MinMagnitude(float x, float y) => MathF.MinMagnitude(x, y); + + private static float Log2(float x) => MathF.Log2(x); + private static float CosineSimilarityCore(ReadOnlySpan x, ReadOnlySpan y) { // Compute the same as: @@ -1184,7 +1190,7 @@ public static float Invoke(Vector512 x) #endif } - private readonly struct LoadIdentity : IUnaryOperator + private readonly struct IdentityOperator : IUnaryOperator { public static float Invoke(float x) => x; public static Vector128 Invoke(Vector128 x) => x; @@ -1194,7 +1200,7 @@ public static float Invoke(Vector512 x) #endif } - private readonly struct LoadSquared : IUnaryOperator + private readonly struct SquaredOperator : IUnaryOperator { public static float Invoke(float x) => x * x; public static Vector128 Invoke(Vector128 x) => x * x; @@ -1204,7 +1210,7 @@ public static float Invoke(Vector512 x) #endif } - private readonly struct LoadAbsolute : IUnaryOperator + private readonly struct AbsoluteOperator : IUnaryOperator { public static float Invoke(float x) => MathF.Abs(x); diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs index ba3fc69bab527f..ed8b3aea0d560f 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs @@ -10,6 +10,12 @@ public static partial class TensorPrimitives { private static unsafe bool IsNegative(float f) => *(int*)&f < 0; + private static float MaxMagnitude(float x, float y) => MathF.Abs(x) >= MathF.Abs(y) ? x : y; + + private static float MinMagnitude(float x, float y) => MathF.Abs(x) < MathF.Abs(y) ? x : y; + + private static float Log2(float x) => MathF.Log(x, 2); + private static float CosineSimilarityCore(ReadOnlySpan x, ReadOnlySpan y) { // Compute the same as: @@ -551,19 +557,19 @@ public Vector Invoke(Vector x, Vector y) public Vector Invoke(Vector x, Vector y, Vector z) => (x * y) + z; } - private readonly struct LoadIdentity : IUnaryOperator + private readonly struct IdentityOperator : IUnaryOperator { public float Invoke(float x) => x; public Vector Invoke(Vector x) => x; } - private readonly struct LoadSquared : IUnaryOperator + private readonly struct SquaredOperator : IUnaryOperator { public float Invoke(float x) => x * x; public Vector Invoke(Vector x) => x * x; } - private readonly struct LoadAbsolute : IUnaryOperator + private readonly struct AbsoluteOperator : IUnaryOperator { public float Invoke(float x) => MathF.Abs(x); diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.cs index 181d152e6ae979..777ab49609856e 100644 --- a/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.cs +++ b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.cs @@ -15,6 +15,9 @@ public static partial class TensorPrimitivesTests { private const double Tolerance = 0.0001; + public static IEnumerable TensorLengthsIncluding0 => + TensorLengths.Concat(new object[][] { [0] }); + public static IEnumerable TensorLengths => from length in Enumerable.Range(1, 128) select new object[] { length }; @@ -45,7 +48,7 @@ private static float NextSingle() } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void AddTwoTensors(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -83,7 +86,7 @@ public static void AddTwoTensors_ThrowsForTooShortDestination(int tensorLength) } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void AddTensorAndScalar(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -110,7 +113,7 @@ public static void AddTensorAndScalar_ThrowsForTooShortDestination(int tensorLen } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void SubtractTwoTensors(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -148,7 +151,7 @@ public static void SubtractTwoTensors_ThrowsForTooShortDestination(int tensorLen } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void SubtractTensorAndScalar(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -175,7 +178,7 @@ public static void SubtractTensorAndScalar_ThrowsForTooShortDestination(int tens } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void MultiplyTwoTensors(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -213,7 +216,7 @@ public static void MultiplyTwoTensors_ThrowsForTooShortDestination(int tensorLen } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void MultiplyTensorAndScalar(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -240,7 +243,7 @@ public static void MultiplyTensorAndScalar_ThrowsForTooShortDestination(int tens } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void DivideTwoTensors(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -278,7 +281,7 @@ public static void DivideTwoTensors_ThrowsForTooShortDestination(int tensorLengt } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void DivideTensorAndScalar(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -305,7 +308,7 @@ public static void DivideTensorAndScalar_ThrowsForTooShortDestination(int tensor } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void NegateTensor(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -330,7 +333,7 @@ public static void NegateTensor_ThrowsForTooShortDestination(int tensorLength) } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void AddTwoTensorsAndMultiplyWithThirdTensor(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -383,7 +386,7 @@ public static void AddTwoTensorsAndMultiplyWithThirdTensor_ThrowsForTooShortDest } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void AddTwoTensorsAndMultiplyWithScalar(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -424,7 +427,7 @@ public static void AddTwoTensorsAndMultiplyWithScalar_ThrowsForTooShortDestinati } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void AddTensorAndScalarAndMultiplyWithTensor(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -465,7 +468,7 @@ public static void AddTensorAndScalarAndMultiplyWithTensor_ThrowsForTooShortDest } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void MultiplyTwoTensorsAndAddWithThirdTensor(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -518,7 +521,7 @@ public static void MultiplyTwoTensorsAndAddWithThirdTensor_ThrowsForTooShortDest } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void MultiplyTwoTensorsAndAddWithScalar(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -547,7 +550,7 @@ public static void MultiplyTwoTensorsAndAddWithScalar_ThrowsForTooShortDestinati } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void MultiplyTensorAndScalarAndAddWithTensor(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -576,7 +579,7 @@ public static void MultiplyTensorAndScalarAndAddWithTensor_ThrowsForTooShortDest } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void ExpTensor(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -601,7 +604,7 @@ public static void ExpTensor_ThrowsForTooShortDestination(int tensorLength) } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void LogTensor(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -625,8 +628,33 @@ public static void LogTensor_ThrowsForTooShortDestination(int tensorLength) AssertExtensions.Throws("destination", () => TensorPrimitives.Log(x, destination)); } + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Log2(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Log2(x, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(MathF.Log(x[i], 2), destination[i], Tolerance); + } + } + [Theory] [MemberData(nameof(TensorLengths))] + public static void Log2_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Log2(x, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] public static void CoshTensor(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -651,7 +679,7 @@ public static void CoshTensor_ThrowsForTooShortDestination(int tensorLength) } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void SinhTensor(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -676,7 +704,7 @@ public static void SinhTensor_ThrowsForTooShortDestination(int tensorLength) } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void TanhTensor(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -809,7 +837,7 @@ public static void Dot_KnownValues(float[] x, float[] y, float expectedResult) } [Theory] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void Dot(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -830,14 +858,14 @@ public static void Dot(int tensorLength) [InlineData(new float[] { 3 }, 3)] [InlineData(new float[] { 3, 4, 1, 2 }, 5.477226)] [InlineData(new float[] { }, 0f)] - public static void L2Normalize_KnownValues(float[] x, float expectedResult) + public static void Norm_KnownValues(float[] x, float expectedResult) { - Assert.Equal(expectedResult, TensorPrimitives.L2Normalize(x), Tolerance); + Assert.Equal(expectedResult, TensorPrimitives.Norm(x), Tolerance); } [Theory] - [MemberData(nameof(TensorLengths))] - public static void L2Normalize(int tensorLength) + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Norm(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -847,7 +875,7 @@ public static void L2Normalize(int tensorLength) sumOfSquares += x[i] * x[i]; } - Assert.Equal(Math.Sqrt(sumOfSquares), TensorPrimitives.L2Normalize(x), Tolerance); + Assert.Equal(Math.Sqrt(sumOfSquares), TensorPrimitives.Norm(x), Tolerance); } [Theory] @@ -1160,6 +1188,44 @@ public static void Max_Negative0LesserThanPositive0() Assert.Equal(1, TensorPrimitives.Max([-1, -0f, 1])); } + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Max_TwoTensors(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Max(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(MathF.Max(x[i], y[i]), destination[i], Tolerance); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Max_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.Max(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Max_TwoTensors_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Max(x, y, destination)); + } + [Fact] public static void MaxMagnitude_ThrowsForEmpty() { @@ -1172,14 +1238,16 @@ public static void MaxMagnitude(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - Assert.Equal(Enumerable.Max(MemoryMarshal.ToEnumerable(x.Memory), MathF.Abs), TensorPrimitives.MaxMagnitude(x)); - - float max = 0; - foreach (float f in x.Span) + int index = 0; + for (int i = 0; i < x.Length; i++) { - max = Math.Max(max, MathF.Abs(f)); + if (MathF.Abs(x[i]) >= MathF.Abs(x[index])) + { + index = i; + } } - Assert.Equal(max, TensorPrimitives.MaxMagnitude(x)); + + Assert.Equal(x[index], TensorPrimitives.MaxMagnitude(x), Tolerance); } [Theory] @@ -1199,12 +1267,50 @@ public static void MaxMagnitude_Negative0LesserThanPositive0() { Assert.Equal(+0f, TensorPrimitives.MaxMagnitude([-0f, +0f])); Assert.Equal(+0f, TensorPrimitives.MaxMagnitude([+0f, -0f])); - Assert.Equal(1, TensorPrimitives.MaxMagnitude([-1, -0f])); + Assert.Equal(-1, TensorPrimitives.MaxMagnitude([-1, -0f])); Assert.Equal(1, TensorPrimitives.MaxMagnitude([-1, -0f, 1])); Assert.Equal(0f, TensorPrimitives.MaxMagnitude([-0f, -0f, -0f, -0f, -0f, 0f])); Assert.Equal(1, TensorPrimitives.MaxMagnitude([-0f, -0f, -0f, -0f, -1, -0f, 0f, 1])); } + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void MaxMagnitude_TwoTensors(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.MaxMagnitude(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(MathF.Abs(x[i]) >= MathF.Abs(y[i]) ? x[i] : y[i], destination[i], Tolerance); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MaxMagnitude_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.MaxMagnitude(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MaxMagnitude_TwoTensors_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.MaxMagnitude(x, y, destination)); + } + [Fact] public static void Min_ThrowsForEmpty() { @@ -1248,6 +1354,44 @@ public static void Min_Negative0LesserThanPositive0() Assert.Equal(-1, TensorPrimitives.Min([-1, -0f, 1])); } + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Min_TwoTensors(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Min(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(MathF.Min(x[i], y[i]), destination[i], Tolerance); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Min_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.Min(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Min_TwoTensors_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Min(x, y, destination)); + } + [Fact] public static void MinMagnitude_ThrowsForEmpty() { @@ -1260,14 +1404,16 @@ public static void MinMagnitude(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - Assert.Equal(Enumerable.Min(MemoryMarshal.ToEnumerable(x.Memory), MathF.Abs), TensorPrimitives.MinMagnitude(x)); - - float min = float.PositiveInfinity; - foreach (float f in x.Span) + int index = 0; + for (int i = 0; i < x.Length; i++) { - min = Math.Min(min, MathF.Abs(f)); + if (MathF.Abs(x[i]) < MathF.Abs(x[index])) + { + index = i; + } } - Assert.Equal(min, TensorPrimitives.MinMagnitude(x)); + + Assert.Equal(x[index], TensorPrimitives.MinMagnitude(x), Tolerance); } [Theory] @@ -1291,6 +1437,44 @@ public static void MinMagnitude_Negative0LesserThanPositive0() Assert.Equal(0, TensorPrimitives.MinMagnitude([-1, -0f, 1])); } + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void MinMagnitude_TwoTensors(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.MinMagnitude(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + Assert.Equal(MathF.Abs(x[i]) < MathF.Abs(y[i]) ? x[i] : y[i], destination[i], Tolerance); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MinMagnitude_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.MinMagnitude(x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MinMagnitude_TwoTensors_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.MinMagnitude(x, y, destination)); + } + [Fact] public static void Product_ThrowsForEmpty() { @@ -1480,5 +1664,30 @@ public static void SumOfMagnitudes_KnownValues() Assert.Equal(6, TensorPrimitives.SumOfMagnitudes([-3, 0, 3])); Assert.Equal(float.NaN, TensorPrimitives.SumOfMagnitudes([-3, float.NaN, 3])); } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Abs(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Abs(x, destination); + + for (int i = 0; i < x.Length; i++) + { + Assert.Equal(MathF.Abs(x[i]), destination[i], Tolerance); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Abs_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Abs(x, destination)); + } } } From 40ccd8b848225e001d3066a898da3bbca734e320 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 20:20:42 -0700 Subject: [PATCH 305/783] [release/8.0-rc2] Make HostModel PEUtils always read/write little endian (#92441) * Make HostModel PEUtils always read/write little endian * PR feeback - helper methods --------- Co-authored-by: Elinor Fung --- .../AppHost/PEUtils.cs | 121 ++++++------------ .../AppHostUpdateTests.cs | 6 +- 2 files changed, 44 insertions(+), 83 deletions(-) diff --git a/src/installer/managed/Microsoft.NET.HostModel/AppHost/PEUtils.cs b/src/installer/managed/Microsoft.NET.HostModel/AppHost/PEUtils.cs index 0d0b33ed55569e..1bfc80fcfca492 100644 --- a/src/installer/managed/Microsoft.NET.HostModel/AppHost/PEUtils.cs +++ b/src/installer/managed/Microsoft.NET.HostModel/AppHost/PEUtils.cs @@ -1,8 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Buffers.Binary; using System.IO; using System.IO.MemoryMappedFiles; +using System.Reflection.PortableExecutable; namespace Microsoft.NET.HostModel.AppHost { @@ -15,29 +18,13 @@ public static class PEUtils /// true if the accessor represents a PE image, false otherwise. internal static unsafe bool IsPEImage(MemoryMappedViewAccessor accessor) { - byte* pointer = null; + if (accessor.Capacity < PEOffsets.DosStub.PESignatureOffset + sizeof(uint)) + return false; - try - { - accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer); - byte* bytes = pointer + accessor.PointerOffset; - - // https://en.wikipedia.org/wiki/Portable_Executable - // Validate that we're looking at Windows PE file - if (((ushort*)bytes)[0] != PEOffsets.DosImageSignature - || accessor.Capacity < PEOffsets.DosStub.PESignatureOffset + sizeof(uint)) - { - return false; - } - return true; - } - finally - { - if (pointer != null) - { - accessor.SafeMemoryMappedViewHandle.ReleasePointer(); - } - } + // https://en.wikipedia.org/wiki/Portable_Executable + // Validate that we're looking at Windows PE file + ushort signature = AsLittleEndian(accessor.ReadUInt16(0)); + return signature == PEOffsets.DosImageSignature; } public static bool IsPEImage(string filePath) @@ -60,40 +47,15 @@ public static bool IsPEImage(string filePath) /// The memory accessor which has the apphost file opened. internal static unsafe void SetWindowsGraphicalUserInterfaceBit(MemoryMappedViewAccessor accessor) { - byte* pointer = null; - - try - { - accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer); - byte* bytes = pointer + accessor.PointerOffset; - - // https://en.wikipedia.org/wiki/Portable_Executable - uint peHeaderOffset = ((uint*)(bytes + PEOffsets.DosStub.PESignatureOffset))[0]; - - if (accessor.Capacity < peHeaderOffset + PEOffsets.PEHeader.Subsystem + sizeof(ushort)) - { - throw new AppHostNotPEFileException("Subsystem offset out of file range."); - } - - ushort* subsystem = ((ushort*)(bytes + peHeaderOffset + PEOffsets.PEHeader.Subsystem)); - - // https://docs.microsoft.com/en-us/windows/desktop/Debug/pe-format#windows-subsystem - // The subsystem of the prebuilt apphost should be set to CUI - if (subsystem[0] != (ushort)PEOffsets.Subsystem.WindowsCui) - { - throw new AppHostNotCUIException(subsystem[0]); - } - - // Set the subsystem to GUI - subsystem[0] = (ushort)PEOffsets.Subsystem.WindowsGui; - } - finally - { - if (pointer != null) - { - accessor.SafeMemoryMappedViewHandle.ReleasePointer(); - } - } + // https://learn.microsoft.com/windows/win32/debug/pe-format#windows-subsystem + // The subsystem of the prebuilt apphost should be set to CUI + uint peHeaderOffset; + ushort subsystem = GetWindowsSubsystem(accessor, out peHeaderOffset); + if (subsystem != (ushort)Subsystem.WindowsCui) + throw new AppHostNotCUIException(subsystem); + + // Set the subsystem to GUI + accessor.Write(peHeaderOffset + PEOffsets.PEHeader.Subsystem, AsLittleEndian((ushort)Subsystem.WindowsGui)); } public static unsafe void SetWindowsGraphicalUserInterfaceBit(string filePath) @@ -113,32 +75,7 @@ public static unsafe void SetWindowsGraphicalUserInterfaceBit(string filePath) /// The memory accessor which has the apphost file opened. internal static unsafe ushort GetWindowsGraphicalUserInterfaceBit(MemoryMappedViewAccessor accessor) { - byte* pointer = null; - - try - { - accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer); - byte* bytes = pointer + accessor.PointerOffset; - - // https://en.wikipedia.org/wiki/Portable_Executable - uint peHeaderOffset = ((uint*)(bytes + PEOffsets.DosStub.PESignatureOffset))[0]; - - if (accessor.Capacity < peHeaderOffset + PEOffsets.PEHeader.Subsystem + sizeof(ushort)) - { - throw new AppHostNotPEFileException("Subsystem offset out of file range."); - } - - ushort* subsystem = ((ushort*)(bytes + peHeaderOffset + PEOffsets.PEHeader.Subsystem)); - - return subsystem[0]; - } - finally - { - if (pointer != null) - { - accessor.SafeMemoryMappedViewHandle.ReleasePointer(); - } - } + return GetWindowsSubsystem(accessor, out _); } public static unsafe ushort GetWindowsGraphicalUserInterfaceBit(string filePath) @@ -151,5 +88,25 @@ public static unsafe ushort GetWindowsGraphicalUserInterfaceBit(string filePath) } } } + + private static ushort GetWindowsSubsystem(MemoryMappedViewAccessor accessor, out uint peHeaderOffset) + { + // https://en.wikipedia.org/wiki/Portable_Executable + if (accessor.Capacity < PEOffsets.DosStub.PESignatureOffset + sizeof(uint)) + throw new AppHostNotPEFileException("PESignature offset out of file range."); + + peHeaderOffset = AsLittleEndian(accessor.ReadUInt32(PEOffsets.DosStub.PESignatureOffset)); + if (accessor.Capacity < peHeaderOffset + PEOffsets.PEHeader.Subsystem + sizeof(ushort)) + throw new AppHostNotPEFileException("Subsystem offset out of file range."); + + // https://learn.microsoft.com/windows/win32/debug/pe-format#windows-subsystem + return AsLittleEndian(accessor.ReadUInt16(peHeaderOffset + PEOffsets.PEHeader.Subsystem)); + } + + private static ushort AsLittleEndian(ushort value) + => BitConverter.IsLittleEndian ? value : BinaryPrimitives.ReverseEndianness(value); + + private static uint AsLittleEndian(uint value) + => BitConverter.IsLittleEndian ? value : BinaryPrimitives.ReverseEndianness(value); } } diff --git a/src/installer/tests/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.AppHost.Tests/AppHostUpdateTests.cs b/src/installer/tests/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.AppHost.Tests/AppHostUpdateTests.cs index 232410be8f2596..b4d038b99b5ce3 100644 --- a/src/installer/tests/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.AppHost.Tests/AppHostUpdateTests.cs +++ b/src/installer/tests/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.AppHost.Tests/AppHostUpdateTests.cs @@ -11,6 +11,7 @@ using Microsoft.NET.HostModel.AppHost; using Microsoft.DotNet.CoreSetup.Test; using System.Diagnostics; +using System.Reflection.PortableExecutable; namespace Microsoft.NET.HostModel.Tests { @@ -111,7 +112,9 @@ public void ItCanSetWindowsGUISubsystem() BitConverter .ToUInt16(File.ReadAllBytes(destinationFilePath), SubsystemOffset) .Should() - .Be(2); + .Be((ushort)Subsystem.WindowsGui); + + Assert.Equal((ushort)Subsystem.WindowsGui, PEUtils.GetWindowsGraphicalUserInterfaceBit(destinationFilePath)); } } @@ -153,6 +156,7 @@ public void ItFailsToSetGUISubsystemWithWrongDefault() string destinationFilePath = Path.Combine(testDirectory.Path, "DestinationAppHost.exe.mock"); string appBinaryFilePath = "Test/App/Binary/Path.dll"; + Assert.Equal(42, PEUtils.GetWindowsGraphicalUserInterfaceBit(sourceAppHostMock)); Assert.Throws(() => HostWriter.CreateAppHost( sourceAppHostMock, From 78a61f99614cbbe6eca330e4005764d488e11338 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 10:44:12 -0500 Subject: [PATCH 306/783] Update dependencies from https://github.com/dotnet/source-build-externals build 20230921.2 (#92476) Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.23469.1 -> To Version 8.0.0-alpha.1.23471.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e40acd650b02cb..4ff6b9f311612d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -100,9 +100,9 @@ d825c6693d4e26f63aaa93c3c1d057faa098e347 - + https://github.com/dotnet/source-build-externals - c42a7ce3b6fa02957e7b4ef995c5c2a9a23d294c + 6dbf3aaa0fc9664df86462f5c70b99800934fccd diff --git a/eng/Versions.props b/eng/Versions.props index 50c7ee67b3e1bf..0cc312c22fe154 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,7 +10,8 @@ 7.0.11 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) rtm - + + false release From fed0f788e7c0e24a78e11d708279eaa242098a11 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 08:45:56 -0700 Subject: [PATCH 307/783] Update dependencies from https://github.com/dotnet/emsdk build 20230921.3 (#92454) Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rc.2.23469.4 -> To Version 8.0.0-rc.2.23471.3 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9bedd07535a17d..2582a60b745fef 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,9 +90,9 @@ 89be445dd4936157533ad96bafb95f701430653a - + https://github.com/dotnet/emsdk - ea0e8e8214e9acc0cba7e78a836ed6656f788d11 + 190be5fe0709de5a3507448151c7fc84abff8628 diff --git a/eng/Versions.props b/eng/Versions.props index a7d36117e12b76..38c9e5fd4f1ab9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -238,7 +238,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.0-rc.2.23469.4 + 8.0.0-rc.2.23471.3 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda From 1564797c4895bfcc30e67c1c94a04712544b19a3 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 09:11:13 -0700 Subject: [PATCH 308/783] [release/8.0] Update dependencies from dotnet/roslyn (#92418) * Update dependencies from https://github.com/dotnet/roslyn build 20230921.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23471.2 -> To Version 4.8.0-3.23471.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230921.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23471.2 -> To Version 4.8.0-3.23471.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230921.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23471.2 -> To Version 4.8.0-3.23471.5 * Update dependencies from https://github.com/dotnet/roslyn build 20230921.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23471.2 -> To Version 4.8.0-3.23471.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230921.7 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23471.2 -> To Version 4.8.0-3.23471.7 * Update dependencies from https://github.com/dotnet/roslyn build 20230921.9 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23471.2 -> To Version 4.8.0-3.23471.9 * Update dependencies from https://github.com/dotnet/roslyn build 20230921.10 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23471.2 -> To Version 4.8.0-3.23471.10 * Update dependencies from https://github.com/dotnet/roslyn build 20230921.11 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23471.2 -> To Version 4.8.0-3.23471.11 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4ff6b9f311612d..dc1ad8042a4d83 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - 9f6f97debe7fe8121a2249f807343d12ef1e4ac6 + bdd9c5ba66b00beebdc3516acc5e29b83efd89af - + https://github.com/dotnet/roslyn - 9f6f97debe7fe8121a2249f807343d12ef1e4ac6 + bdd9c5ba66b00beebdc3516acc5e29b83efd89af - + https://github.com/dotnet/roslyn - 9f6f97debe7fe8121a2249f807343d12ef1e4ac6 + bdd9c5ba66b00beebdc3516acc5e29b83efd89af https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index c0270374896a36..c6a6b57ec67fa2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -44,9 +44,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23471.2 - 4.8.0-3.23471.2 - 4.8.0-3.23471.2 + 4.8.0-3.23471.11 + 4.8.0-3.23471.11 + 4.8.0-3.23471.11 diff --git a/eng/Versions.props b/eng/Versions.props index c6a6b57ec67fa2..196aed74ec290a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23465.3 - 1.0.0-prerelease.23465.3 - 1.0.0-prerelease.23465.3 - 1.0.0-prerelease.23465.3 - 1.0.0-prerelease.23465.3 - 1.0.0-prerelease.23465.3 + 1.0.0-prerelease.23471.3 + 1.0.0-prerelease.23471.3 + 1.0.0-prerelease.23471.3 + 1.0.0-prerelease.23471.3 + 1.0.0-prerelease.23471.3 + 1.0.0-prerelease.23471.3 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From 0717e52526d8a45907f07cf7860d1290f8064558 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 10:14:27 -0700 Subject: [PATCH 311/783] [release/8.0-rc2] Ensure that embedded broadcast checks the base type of the parent node (#92459) * Ensure that embedded broadcast checks the base type of the parent node * Ensure the regression test exits if AVX2 is not supported * Also handle embedded broadcasts for mismatched memory sizes --------- Co-authored-by: Tanner Gooding --- src/coreclr/jit/lowerxarch.cpp | 19 ++++++-- .../JitBlue/Runtime_92357/Runtime_92357.cs | 47 +++++++++++++++++++ .../Runtime_92357/Runtime_92357.csproj | 8 ++++ 3 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.csproj diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 30c2a832b94fc1..319238aaec628f 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -8202,10 +8202,12 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_AVX2_BroadcastScalarToVector256: case NI_AVX512F_BroadcastScalarToVector512: { - var_types baseType = hwintrinsic->GetSimdBaseType(); - if (varTypeIsSmall(baseType)) + var_types parentBaseType = parentNode->GetSimdBaseType(); + var_types childBaseType = hwintrinsic->GetSimdBaseType(); + + if (varTypeIsSmall(parentBaseType) || (genTypeSize(parentBaseType) != genTypeSize(childBaseType))) { - // early return if the base type is not embedded broadcast compatible. + // early return if either base type is not embedded broadcast compatible. return false; } @@ -8213,7 +8215,7 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre if (intrinsicId == NI_SSE3_MoveAndDuplicate) { // NI_SSE3_MoveAndDuplicate is for Vector128 only. - assert(baseType == TYP_DOUBLE); + assert(childBaseType == TYP_DOUBLE); } if (comp->compOpportunisticallyDependsOn(InstructionSet_AVX512F_VL) && @@ -8246,6 +8248,15 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_AVX_BroadcastScalarToVector128: case NI_AVX_BroadcastScalarToVector256: { + var_types parentBaseType = parentNode->GetSimdBaseType(); + var_types childBaseType = hwintrinsic->GetSimdBaseType(); + + if (varTypeIsSmall(parentBaseType) || (genTypeSize(parentBaseType) != genTypeSize(childBaseType))) + { + // early return if either base type is not embedded broadcast compatible. + return false; + } + return parentNode->OperIsEmbBroadcastCompatible(); } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.cs b/src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.cs new file mode 100644 index 00000000000000..4704441bacce6c --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using Xunit; + +public static class Runtime_92357 +{ + [Fact] + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + public static void Problem() + { + if (!Avx2.IsSupported) + { + return; + } + + int y1 = 5; + + Vector256 actual1 = Test1(Vector256.Create((short)1), ref y1); + Vector256 expected1 = Vector256.Create(10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0); + + Assert.Equal(expected1, actual1); + + long y2 = 5; + + Vector256 actual2 = Test2(Vector256.Create((int)1), ref y2); + Vector256 expected2 = Vector256.Create(10, 0, 10, 0, 10, 0, 10, 0); + + Assert.Equal(expected2, actual2); + } + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + public static Vector256 Test1(Vector256 x, ref int y) + { + return Avx2.MultiplyLow(x + x, Vector256.Create(y).AsInt16()); + } + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + public static Vector256 Test2(Vector256 x, ref long y) + { + return Avx2.MultiplyLow(x + x, Vector256.Create(y).AsInt32()); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From 873b3cca0a6ac461f1f6df70622e3b4703e6e493 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 10:16:16 -0700 Subject: [PATCH 312/783] [release/8.0-rc2] Do not call SignalSession on invalid session IDs (#92444) * Update EventPipeEventDispatcher.cs * Update EventPipeEventDispatcher.cs --------- Co-authored-by: David Mason --- .../Tracing/EventPipeEventDispatcher.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventDispatcher.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventDispatcher.cs index efd4b8cfb656dd..708c5afc1bc70e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventDispatcher.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventDispatcher.cs @@ -142,12 +142,15 @@ private void SetStopDispatchTask() { Debug.Assert(Monitor.IsEntered(m_dispatchControlLock)); - if (m_dispatchTask != null) + if (m_dispatchTaskCancellationSource?.IsCancellationRequested ?? true) { - Debug.Assert(m_dispatchTaskCancellationSource != null); - m_dispatchTaskCancellationSource?.Cancel(); - EventPipeInternal.SignalSession(m_sessionID); + return; } + + Debug.Assert(m_sessionID != 0); + m_dispatchTaskCancellationSource.Cancel(); + EventPipeInternal.SignalSession(m_sessionID); + m_sessionID = 0; } private unsafe void DispatchEventsToEventListeners(ulong sessionID, DateTime syncTimeUtc, long syncTimeQPC, long timeQPCFrequency, Task? previousDispatchTask, CancellationToken token) @@ -187,8 +190,12 @@ private unsafe void DispatchEventsToEventListeners(ulong sessionID, DateTime syn } } - // Disable the old session. This can happen asynchronously since we aren't using the old session anymore - EventPipeInternal.Disable(sessionID); + lock (m_dispatchControlLock) + { + // Disable the old session. This can happen asynchronously since we aren't using the old session + // anymore. We take the lock to make sure we don't call SignalSession on an invalid session ID. + EventPipeInternal.Disable(sessionID); + } } /// From 974edf97294f3fb1b74cfddaf0275a657886224b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 10:25:30 -0700 Subject: [PATCH 313/783] [release/8.0-rc2] Ensure Bind can handle null from GetSection (#92477) * Ensure Bind can handle null from GetSection IConfiguration instances may return a null value from GetSection. We were not handling this and would throw a NullReferenceException. * Address feedback * Remove Moq from ConfigBinder tests --------- Co-authored-by: Eric StJohn --- .../src/ConfigurationBinder.cs | 5 +++ .../ConfigurationBinderTests.TestClasses.cs | 6 +++ .../tests/Common/ConfigurationBinderTests.cs | 38 ++++++++++++++++++- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs index 74365d8084aa3d..dfc35d80208553 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs @@ -298,6 +298,11 @@ private static void BindInstance( return; } + if (config is null) + { + return; + } + var section = config as IConfigurationSection; string? configValue = section?.Value; if (configValue != null && TryConvertValue(type, configValue, section?.Path, out object? convertedValue, out Exception? error)) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs index f47cdbe6dbbb54..48474033ec1f8e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs @@ -888,5 +888,11 @@ public int MyIntProperty } } + public class SimplePoco + { + public string A { get; set; } + public string B { get; set; } + } + } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs index 7c955e789184c8..7e635c1f0bdaa0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs @@ -11,6 +11,7 @@ #if BUILDING_SOURCE_GENERATOR_TESTS using Microsoft.Extensions.Configuration; #endif +using Microsoft.Extensions.Configuration.Memory; using Microsoft.Extensions.Configuration.Test; using Xunit; @@ -1767,7 +1768,7 @@ public void EnsureCallingThePropertySetter() Assert.Equal(0, options.OtherCodeNullable); Assert.Equal("default", options.OtherCodeString); Assert.Null(options.OtherCodeNull); - Assert.Null(options.OtherCodeUri); + Assert.Null(options.OtherCodeUri); } [Fact] @@ -2238,7 +2239,7 @@ void TestUntypedOverloads(IConfiguration? configuration, string? key) Assert.Throws(() => configuration.GetValue(typeof(GeolocationClass), key, new GeolocationClass())); Assert.Throws(() => configuration.GetValue(typeof(Geolocation), key)); Assert.Throws(() => configuration.GetValue(typeof(Geolocation), key, defaultValue: null)); - Assert.Throws(() => configuration.GetValue(typeof(Geolocation), key, default(Geolocation))); + Assert.Throws(() => configuration.GetValue(typeof(Geolocation), key, default(Geolocation))); } } @@ -2404,5 +2405,38 @@ public void SharedChildInstance() config.GetSection("A").Bind(instance); Assert.Equal("localhost", instance.ConnectionString); } + + [Fact] + public void CanBindToMockConfigurationSection() + { + const string expectedA = "hello"; + + var configSource = new MemoryConfigurationSource() + { + InitialData = new Dictionary() + { + [$":{nameof(SimplePoco.A)}"] = expectedA, + } + }; + var configRoot = new MockConfigurationRoot(new[] { configSource.Build(null) }); + var configSection = new ConfigurationSection(configRoot, string.Empty); + + SimplePoco result = new(); + configSection.Bind(result); + + Assert.Equal(expectedA, result.A); + Assert.Equal(default(string), result.B); + } + + // a mock configuration root that will return null for undefined Sections, + // as is common when Configuration interfaces are mocked + class MockConfigurationRoot : ConfigurationRoot, IConfigurationRoot + { + public MockConfigurationRoot(IList providers) : base(providers) + { } + + IConfigurationSection IConfiguration.GetSection(string key) => + this[key] is null ? null : new ConfigurationSection(this, key); + } } } From 4f51a33e6fb22b88a05e20593072f83bc71a445a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 13:04:25 -0700 Subject: [PATCH 314/783] Update dependencies from https://github.com/dotnet/roslyn build 20230922.2 (#92488) Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23471.11 -> To Version 4.8.0-3.23472.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c768ef801d3b43..3894120b6e9cf6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - bdd9c5ba66b00beebdc3516acc5e29b83efd89af + aa7e4da5341196be494ca4bb0c719d7bef3e396a - + https://github.com/dotnet/roslyn - bdd9c5ba66b00beebdc3516acc5e29b83efd89af + aa7e4da5341196be494ca4bb0c719d7bef3e396a - + https://github.com/dotnet/roslyn - bdd9c5ba66b00beebdc3516acc5e29b83efd89af + aa7e4da5341196be494ca4bb0c719d7bef3e396a https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index 196aed74ec290a..1f94efa53a6898 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -44,9 +44,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23471.11 - 4.8.0-3.23471.11 - 4.8.0-3.23471.11 + 4.8.0-3.23472.2 + 4.8.0-3.23472.2 + 4.8.0-3.23472.2 - 3.11.0-beta1.23468.1 - 8.0.0-preview.23468.1 + 3.11.0-beta1.23472.1 + 8.0.0-preview.23472.1 - 3.11.0-beta1.23468.1 - 8.0.0-preview.23468.1 + 3.11.0-beta1.23472.1 + 8.0.0-preview.23472.1 8.0.0-rc.1.23406.6 8.0.0-preview.7.23325.2 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 6.0.0 1.1.1 @@ -220,38 +220,38 @@ 2.2.2 8.0.0-alpha.1.23468.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 - 8.0.0-rc.2.23471.3 + 8.0.0-rc.2.23473.3 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda 1.0.0-v3.14.0.5722 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 3.1.7 1.0.406601 From a3d5300baee03169bf737cfc4e9b1f7dbece4d05 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 11:11:14 -0500 Subject: [PATCH 319/783] Update dependencies from https://github.com/dotnet/emsdk build 20230923.1 (#92532) Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rtm.23470.1 -> To Version 8.0.0-rtm.23473.1 Dependency coherency updates runtime.linux-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.win-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.win-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.osx-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.osx-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.win-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.win-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.osx-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.osx-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.osx-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.osx-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.osx-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.osx-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools From Version 16.0.5-alpha.1.23423.1 -> To Version 16.0.5-alpha.1.23472.2 (parent: Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 124 ++++++++++++++++++++-------------------- eng/Versions.props | 62 ++++++++++---------- 2 files changed, 93 insertions(+), 93 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8a39a384f4ad5e..30dcddeebd5e40 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -12,69 +12,69 @@ https://github.com/dotnet/wcf 7f504aabb1988e9a093c1e74d8040bd52feb2f01 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 https://github.com/dotnet/command-line-api @@ -90,9 +90,9 @@ 89be445dd4936157533ad96bafb95f701430653a - + https://github.com/dotnet/emsdk - 446eeb331fcbf2f48c14a377601a8ab950ec942e + 41db2322780b16e4ddadcebca41dc86c7806ed9a @@ -233,61 +233,61 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 - + https://github.com/dotnet/llvm-project - 08a449c9a9bf593b29fc05de2f424e6882320e5d + 2e6bfc3d59a6c80e3fa90a703e23bd4dab707756 https://github.com/dotnet/runtime diff --git a/eng/Versions.props b/eng/Versions.props index 01481f4c419ac5..772c606514e126 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -110,14 +110,14 @@ 8.0.0-rc.1.23406.6 8.0.0-preview.7.23325.2 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 6.0.0 1.1.1 @@ -222,38 +222,38 @@ 2.2.2 8.0.0-alpha.1.23468.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 - 8.0.0-rtm.23470.1 + 8.0.0-rtm.23473.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda 1.0.0-v3.14.0.5722 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 - 16.0.5-alpha.1.23423.1 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23472.2 3.1.7 1.0.406601 From 7778148a7fbfe4d05a85a181b54054a02a182607 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 14:04:51 -0700 Subject: [PATCH 320/783] Update dependencies from https://github.com/dotnet/source-build-externals build 20230925.1 (#92641) Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.23471.2 -> To Version 8.0.0-alpha.1.23475.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 30dcddeebd5e40..ecea0bfbd34317 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -100,9 +100,9 @@ 7b55da982fc6e71c1776c4de89111aee0eecb45a - + https://github.com/dotnet/source-build-externals - 6dbf3aaa0fc9664df86462f5c70b99800934fccd + e04156dbe14f882a80d4499dbebd45ab156b6c3c From 849fc57e8810723fc991460ef954b496ffdf366c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 14:52:34 -0700 Subject: [PATCH 321/783] [release/8.0] Update dependencies from dotnet/emsdk dotnet/hotreload-utils (#92606) * Update dependencies from https://github.com/dotnet/emsdk build 20230925.3 Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rtm.23473.1 -> To Version 8.0.0-rtm.23475.3 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20230925.1 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23461.1 -> To Version 8.0.0-alpha.0.23475.1 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ecea0bfbd34317..a4ab920e969679 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,9 +90,9 @@ 89be445dd4936157533ad96bafb95f701430653a - + https://github.com/dotnet/emsdk - 41db2322780b16e4ddadcebca41dc86c7806ed9a + 0a2aae889f5ce2803fa227e13963b3fbf3ccb6b0 @@ -350,9 +350,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization ee166d79f3a269d2a1c6b7d400df7e284b1aa67b - + https://github.com/dotnet/hotreload-utils - 4b29cfaccdab45442e15f3b84f75bc9c10ee79b3 + 6c20c1d568568b9b2da84f878ac9cb4a48aaa4e5 https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index 772c606514e126..0a745db24ef032 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -186,7 +186,7 @@ 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 - 8.0.0-alpha.0.23468.2 + 8.0.0-alpha.0.23475.1 2.4.2 1.0.0 2.4.5 @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.0-rtm.23473.1 + 8.0.0-rtm.23475.3 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda From 0933e300f0c0647a15a0433f1a3b07bcab9882f4 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 26 Sep 2023 22:45:35 -0400 Subject: [PATCH 322/783] [release/8.0][wasm] Fix regressed file sizes for blazor (#92627) * [wasm] Add getters for __indirect_function_table, and wasmMemory .. so that can work even if they get renamed during minimization. * [wasm] build: Revert to older behavior for WasmNativeStrip The earlier change was done in 678fd6a73756f8438be115898cdd4fe0500e3d18, which changed to pass `-g` to the link step also. But that resulted in increased native file sizes. Changed sizes for the `minimum blazor template - publish` scenario: ``` | Last rc1 run | With the change ----------------------------------------------------------|----------------- |------------------ SOD - Minimum Blazor Template - Publish |8590723.000 bytes |7889806.000 bytes Total Uncompressed _framework |4304274.000 bytes |4202273.000 bytes pub/wwwroot/_framework/dotnet.js |35722.000 bytes |35838.000 bytes pub/wwwroot/_framework/dotnet.native.8.0.0-VERSION.js |239307.000 bytes |134566.000 bytes pub/wwwroot/_framework/dotnet.native.wasm |1174394.000 bytes |1148841.000 bytes pub/wwwroot/_framework/dotnet.runtime.8.0.0-VERSION.js |221356.000 bytes |221712.000 bytes ``` * [wasm] cleanup corresponding tests * [wasm] Remove WasmNativeStrip from wasm.proj as it will have no effect --- .../WasmNativeDefaultsTests.cs | 107 +++++++++++------- src/mono/wasm/build/WasmApp.Native.targets | 28 +++-- src/mono/wasm/runtime/es6/dotnet.es6.pre.js | 4 +- src/mono/wasm/runtime/jiterpreter-jit-call.ts | 2 +- src/mono/wasm/runtime/jiterpreter-support.ts | 7 +- src/mono/wasm/runtime/types/internal.ts | 2 + src/mono/wasm/wasm.proj | 1 - 7 files changed, 91 insertions(+), 60 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmNativeDefaultsTests.cs b/src/mono/wasm/Wasm.Build.Tests/WasmNativeDefaultsTests.cs index 5efd84085b8863..4bbea5dff8a926 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmNativeDefaultsTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmNativeDefaultsTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; +using System.Text.RegularExpressions; using Xunit; using Xunit.Abstractions; @@ -12,6 +13,7 @@ namespace Wasm.Build.Tests { public class WasmNativeDefaultsTests : TestMainJsTestBase { + private static Regex s_regex = new("\\*\\* WasmBuildNative:.*"); public WasmNativeDefaultsTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) : base(output, buildContext) { @@ -39,19 +41,20 @@ public static TheoryData SettingDifferentFromV // Config=Release always causes relinking when publishing bool publishValue = forPublish && config == "Release" ? true : false; // Setting the default value from the runtime pack shouldn't trigger relinking - data.Add(config, $"<{defaultPair.propertyName}>{defaultPair.defaultValueInRuntimePack}", + data.Add(config, $"<{defaultPair.propertyName}>{defaultPair.defaultValueInRuntimePack.ToString().ToLower()}", /*aot*/ false, /*build*/ false, /*publish*/ publishValue); // Leaving the property unset, so checking the default data.Add(config, "", /*aot*/ false, /*build*/ false, /*publish*/ publishValue); // Setting the !default value should trigger relinking - data.Add(config, $"<{defaultPair.propertyName}>{!defaultPair.defaultValueInRuntimePack}", + data.Add(config, $"<{defaultPair.propertyName}>{(!defaultPair.defaultValueInRuntimePack).ToString().ToLower()}", /*aot*/ false, /*build*/ true, /*publish*/ true); } } return data; } + public static TheoryData DefaultsTestData(bool forPublish) { TheoryData data = new() @@ -93,45 +96,34 @@ public static TheoryData DefaultsTestData(bool return data; } +#pragma warning disable xUnit1026 // For unused *buildValue*, and *publishValue* parameters [Theory] [MemberData(nameof(DefaultsTestData), parameters: false)] [MemberData(nameof(SettingDifferentFromValuesInRuntimePack), parameters: false)] public void DefaultsWithBuild(string config, string extraProperties, bool aot, bool expectWasmBuildNativeForBuild, bool expectWasmBuildNativeForPublish) { - string output = CheckWasmNativeDefaultValue("native_defaults_build", config, extraProperties, aot, dotnetWasmFromRuntimePack: !expectWasmBuildNativeForPublish, publish: false); - - bool expectedWasmNativeStripValue = true; - if (/*isBuild && */ expectWasmBuildNativeForBuild && config == "Debug") - expectedWasmNativeStripValue = false; + (string output, string? line) = CheckWasmNativeDefaultValue("native_defaults_build", config, extraProperties, aot, dotnetWasmFromRuntimePack: !expectWasmBuildNativeForBuild, publish: false); - // bool expectedWasmNativeStripValue = !(wasmBuildNativeForBuild && config == "Debug"); - // for build - Assert.Contains($"** WasmBuildNative: '{expectWasmBuildNativeForBuild.ToString().ToLower()}', WasmNativeStrip: '{expectedWasmNativeStripValue.ToString().ToLower()}', WasmBuildingForNestedPublish: ''", output); - Assert.Contains("Stopping the build", output); + InferAndCheckPropertyValues(line, isPublish: false, wasmBuildNative: expectWasmBuildNativeForBuild, config: config); } -#pragma warning disable xUnit1026 // For unused *buildValue* parameter [Theory] [MemberData(nameof(DefaultsTestData), parameters: true)] [MemberData(nameof(SettingDifferentFromValuesInRuntimePack), parameters: true)] public void DefaultsWithPublish(string config, string extraProperties, bool aot, bool expectWasmBuildNativeForBuild, bool expectWasmBuildNativeForPublish) { - string output = CheckWasmNativeDefaultValue("native_defaults_publish", config, extraProperties, aot, dotnetWasmFromRuntimePack: !expectWasmBuildNativeForPublish, publish: true); + (string output, string? line) = CheckWasmNativeDefaultValue("native_defaults_publish", config, extraProperties, aot, dotnetWasmFromRuntimePack: !expectWasmBuildNativeForPublish, publish: true); - // for build - // Assert.DoesNotContain($"** WasmBuildNative: '{buildValue.ToString().ToLower()}', WasmNativeStrip: 'true', WasmBuildingForNestedPublish: ''", output); - // for publish - Assert.Contains($"** WasmBuildNative: '{expectWasmBuildNativeForPublish.ToString().ToLower()}', WasmNativeStrip: 'true', WasmBuildingForNestedPublish: 'true'", output); - Assert.Contains("Stopping the build", output); + InferAndCheckPropertyValues(line, isPublish: true, wasmBuildNative: expectWasmBuildNativeForPublish, config: config); } #pragma warning restore xunit1026 public static TheoryData SetWasmNativeStripExplicitlyTestData(bool publish) => new() { - {"Debug", "true", false, true }, - {"Release", "true", publish, true }, - {"Debug", "false", true, false }, - {"Release", "false", true, false } + {"Debug", "true", /*wasmBuildNative*/ false, /*wasmNativeStrip*/ true }, + {"Release", "true", /*wasmBuildNative*/ publish, /*wasmNativeStrip*/ true }, + {"Debug", "false", /*wasmBuildNative*/ true, /*wasmNativeStrip*/ false }, + {"Release", "false", /*wasmBuildNative*/ true, /*wasmNativeStrip*/ false } }; public static TheoryData SetWasmNativeStripExplicitlyWithWasmBuildNativeTestData() => new() @@ -147,10 +139,13 @@ public void DefaultsWithPublish(string config, string extraProperties, bool aot, [MemberData(nameof(SetWasmNativeStripExplicitlyWithWasmBuildNativeTestData))] public void WasmNativeStripDefaultWithBuild(string config, string extraProperties, bool expectedWasmBuildNativeValue, bool expectedWasmNativeStripValue) { - string output = CheckWasmNativeDefaultValue("native_strip_defaults", config, extraProperties, aot: false, dotnetWasmFromRuntimePack: !expectedWasmBuildNativeValue, publish: false); + (string output, string? line) = CheckWasmNativeDefaultValue("native_strip_defaults", config, extraProperties, aot: false, dotnetWasmFromRuntimePack: !expectedWasmBuildNativeValue, publish: false); - Assert.Contains($"** WasmBuildNative: '{expectedWasmBuildNativeValue.ToString().ToLower()}', WasmNativeStrip: '{expectedWasmNativeStripValue.ToString().ToLower()}', WasmBuildingForNestedPublish: ''", output); - Assert.Contains("Stopping the build", output); + CheckPropertyValues(line, + wasmBuildNative: expectedWasmBuildNativeValue, + wasmNativeStrip: expectedWasmNativeStripValue, + wasmNativeDebugSymbols: true, + wasmBuildingForNestedPublish: null); } [Theory] @@ -158,37 +153,38 @@ public void WasmNativeStripDefaultWithBuild(string config, string extraPropertie [MemberData(nameof(SetWasmNativeStripExplicitlyWithWasmBuildNativeTestData))] public void WasmNativeStripDefaultWithPublish(string config, string extraProperties, bool expectedWasmBuildNativeValue, bool expectedWasmNativeStripValue) { - string output = CheckWasmNativeDefaultValue("native_strip_defaults", config, extraProperties, aot: false, dotnetWasmFromRuntimePack: !expectedWasmBuildNativeValue, publish: true); + (string output, string? line) = CheckWasmNativeDefaultValue("native_strip_defaults", config, extraProperties, aot: false, dotnetWasmFromRuntimePack: !expectedWasmBuildNativeValue, publish: true); - Assert.Contains($"** WasmBuildNative: '{expectedWasmBuildNativeValue.ToString().ToLower()}', WasmNativeStrip: '{expectedWasmNativeStripValue.ToString().ToLower()}', WasmBuildingForNestedPublish: 'true'", output); - Assert.Contains("Stopping the build", output); + CheckPropertyValues(line, + wasmBuildNative: expectedWasmBuildNativeValue, + wasmNativeStrip: expectedWasmNativeStripValue, + wasmNativeDebugSymbols: true, + wasmBuildingForNestedPublish: true); } [Theory] /* always relink */ - [InlineData("Debug", "", /*build*/ true, /*publish*/ true)] - [InlineData("Release", "", /*build*/ true, /*publish*/ true)] - [InlineData("Release", "false", /*build*/ true, /*publish*/ true)] - public void WithNativeReference(string config, string extraProperties, bool buildValue, bool publishValue) + [InlineData("Debug", "", /*publish*/ false)] + [InlineData("Debug", "", /*publish*/ true)] + [InlineData("Release", "", /*publish*/ false)] + [InlineData("Release", "", /*publish*/ true)] + [InlineData("Release", "false", /*publish*/ true)] + public void WithNativeReference(string config, string extraProperties, bool publish) { string nativeLibPath = Path.Combine(BuildEnvironment.TestAssetsPath, "native-libs", "native-lib.o"); string nativeRefItem = @$""; - string output = CheckWasmNativeDefaultValue("native_defaults_publish", + (string output, string? line) = CheckWasmNativeDefaultValue("native_defaults_publish", config, extraProperties, aot: false, - dotnetWasmFromRuntimePack: !publishValue, - publish: true, + dotnetWasmFromRuntimePack: !publish, + publish: publish, extraItems: nativeRefItem); - // for build - FIXME: - Assert.DoesNotContain($"** WasmBuildNative: '{buildValue.ToString().ToLower()}', WasmBuildingForNestedPublish: ''", output); - // for publish - Assert.Contains($"** WasmBuildNative: '{publishValue.ToString().ToLower()}', WasmNativeStrip: 'true', WasmBuildingForNestedPublish: 'true'", output); - Assert.Contains("Stopping the build", output); + InferAndCheckPropertyValues(line, isPublish: publish, wasmBuildNative: true, config: config); } - private string CheckWasmNativeDefaultValue(string projectName, + private (string, string?) CheckWasmNativeDefaultValue(string projectName, string config, string extraProperties, bool aot, @@ -201,7 +197,7 @@ private string CheckWasmNativeDefaultValue(string projectName, string printValueTarget = @" - + " + (publish ? @"" : @"") @@ -223,7 +219,32 @@ private string CheckWasmNativeDefaultValue(string projectName, BuildOnlyAfterPublish: false, Publish: publish)); - return output; + Assert.Contains("Stopping the build", output); + + Match m = s_regex.Match(output); + Assert.Equal(1, m.Groups.Count); + return (output, m.Success ? m.Groups[0]?.ToString() : null); + } + + private void InferAndCheckPropertyValues(string? line, bool isPublish, bool wasmBuildNative, string config) + { + bool expectedWasmNativeStripValue; + if (!isPublish && wasmBuildNative && config == "Debug") + expectedWasmNativeStripValue = false; + else + expectedWasmNativeStripValue = true; + + CheckPropertyValues(line, wasmBuildNative, expectedWasmNativeStripValue, /*wasmNativeDebugSymbols*/true, isPublish); + } + + private void CheckPropertyValues(string? line, bool wasmBuildNative, bool wasmNativeStrip, bool wasmNativeDebugSymbols, bool? wasmBuildingForNestedPublish) + { + Assert.NotNull(line); + Assert.Contains($"** WasmBuildNative: '{wasmBuildNative.ToString().ToLower()}', " + + $"WasmNativeStrip: '{wasmNativeStrip.ToString().ToLower()}', " + + $"WasmNativeDebugSymbols: '{wasmNativeDebugSymbols.ToString().ToLower()}', " + + $"WasmBuildingForNestedPublish: '{(wasmBuildingForNestedPublish.HasValue && wasmBuildingForNestedPublish == true ? "true" : "")}'", + line); } } } diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index 295474566a14a0..73e5720abb01ed 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -22,7 +22,6 @@ $(_BeforeWasmBuildAppDependsOn); _SetupEmscripten; _SetWasmBuildNativeDefaults; - _SetWasmNativeStripDefault; _ReadEmccProps @@ -119,6 +118,7 @@ <_BoolPropertiesThatTriggerRelinking Include="InvariantTimezone" DefaultValueInRuntimePack="false" /> <_BoolPropertiesThatTriggerRelinking Include="InvariantGlobalization" DefaultValueInRuntimePack="false" /> <_BoolPropertiesThatTriggerRelinking Include="WasmNativeStrip" DefaultValueInRuntimePack="true" /> + @@ -133,7 +133,6 @@ true true - false @@ -147,10 +146,23 @@ true + + false + + + true + false + + + + true + true + + @@ -160,14 +172,6 @@ - - - - false - true - - - @@ -178,7 +182,6 @@ <_MonoAotCrossCompilerPath>@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','browser-wasm')) <_EmccDefaultFlagsRsp>$([MSBuild]::NormalizePath($(_WasmRuntimePackSrcDir), 'emcc-default.rsp')) <_EmccDefaultLinkFlagsRsp>$([MSBuild]::NormalizePath($(_WasmRuntimePackSrcDir), 'emcc-link.rsp')) - true $(WasmBuildNative) <_WasmICallTablePath>$(_WasmIntermediateOutputPath)icall-table.h @@ -221,7 +224,7 @@ <_EmccCommonFlags Include="$(_DefaultEmccFlags)" /> <_EmccCommonFlags Include="$(EmccFlags)" /> - <_EmccCommonFlags Include="-g" Condition="'$(WasmNativeDebugSymbols)' == 'true'" /> + <_EmccCommonFlags Include="-g" Condition="'$(WasmNativeStrip)' == 'false'" /> <_EmccCommonFlags Include="-v" Condition="'$(EmccVerbose)' != 'false'" /> <_EmccCommonFlags Include="-s DISABLE_EXCEPTION_CATCHING=0" Condition="'$(WasmEnableExceptionHandling)' == 'false'" /> <_EmccCommonFlags Include="-fwasm-exceptions" Condition="'$(WasmEnableExceptionHandling)' == 'true'" /> @@ -249,6 +252,7 @@ <_EmccCFlags Include="-emit-llvm" /> <_EmccCFlags Include=""-I%(_EmccIncludePaths.Identity)"" /> + <_EmccCFlags Include="-g" Condition="'$(WasmNativeDebugSymbols)' == 'true'" /> <_EmccLDFlags Include="$(EmccLinkOptimizationFlag)" /> diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.pre.js b/src/mono/wasm/runtime/es6/dotnet.es6.pre.js index 9eb9b1c6b99e7d..490935d5ca0284 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.pre.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.pre.js @@ -1,3 +1,5 @@ if (_nativeModuleLoaded) throw new Error("Native module already loaded"); _nativeModuleLoaded = true; -createDotnetRuntime = Module = createDotnetRuntime(Module); \ No newline at end of file +createDotnetRuntime = Module = createDotnetRuntime(Module); +Module["getWasmIndirectFunctionTable"] = function () { return wasmTable; } +Module["getMemory"] = function () { return wasmMemory; } diff --git a/src/mono/wasm/runtime/jiterpreter-jit-call.ts b/src/mono/wasm/runtime/jiterpreter-jit-call.ts index eba38843de57ef..af918bedb0cf9c 100644 --- a/src/mono/wasm/runtime/jiterpreter-jit-call.ts +++ b/src/mono/wasm/runtime/jiterpreter-jit-call.ts @@ -281,7 +281,7 @@ export function mono_jiterp_do_jit_call_indirect( jit_call_cb: jitCallCb, }, m: { - h: (Module).asm.memory + h: (Module).getMemory() }, }); const impl = instance.exports.do_jit_call_indirect; diff --git a/src/mono/wasm/runtime/jiterpreter-support.ts b/src/mono/wasm/runtime/jiterpreter-support.ts index 5ce5759b2a6a4b..0589c28d5bd06e 100644 --- a/src/mono/wasm/runtime/jiterpreter-support.ts +++ b/src/mono/wasm/runtime/jiterpreter-support.ts @@ -239,9 +239,12 @@ export class WasmBuilder { } getWasmImports(): WebAssembly.Imports { + const memory = (Module).getMemory(); + mono_assert(memory instanceof WebAssembly.Memory, () => `expected heap import to be WebAssembly.Memory but was ${memory}`); + const result: any = { c: this.getConstants(), - m: { h: (Module).asm.memory }, + m: { h: memory }, // f: { f: getWasmFunctionTable() }, }; @@ -1589,7 +1592,7 @@ export function copyIntoScratchBuffer(src: NativePointer, size: number): NativeP export function getWasmFunctionTable() { if (!wasmTable) - wasmTable = (Module)["asm"]["__indirect_function_table"]; + wasmTable = Module.getWasmIndirectFunctionTable(); if (!wasmTable) throw new Error("Module did not export the indirect function table"); return wasmTable; diff --git a/src/mono/wasm/runtime/types/internal.ts b/src/mono/wasm/runtime/types/internal.ts index aedf803aceff1f..a91b21973c8d5e 100644 --- a/src/mono/wasm/runtime/types/internal.ts +++ b/src/mono/wasm/runtime/types/internal.ts @@ -454,6 +454,8 @@ export declare interface EmscriptenModuleInternal { ready: Promise; asm: { memory?: WebAssembly.Memory }; wasmMemory?: WebAssembly.Memory; + getWasmIndirectFunctionTable: any; + getMemory: WebAssembly.Memory; getWasmTableEntry(index: number): any; removeRunDependency(id: string): void; addRunDependency(id: string): void; diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 66bc509910571a..3b75fa9feeb1f0 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -33,7 +33,6 @@ <_EmccDefaultsRspPath>$(NativeBinDir)src\emcc-default.rsp <_EmccCompileRspPath>$(NativeBinDir)src\emcc-compile.rsp <_EmccLinkRspPath>$(NativeBinDir)src\emcc-link.rsp - false $(EMSDK_PATH)\upstream\bin\llvm-ar $(EmSdkLLVMAr).exe From 8c682063553fc744be2b2dfa82d131d03f8b6b23 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 03:13:09 -0700 Subject: [PATCH 323/783] [release/8.0] JIT: Fixed containment of STOREIND of HW intrinsics ConvertTo*/Extract* (#92513) * Added OperIsHWIntrinsicSIMDScalar. Do not remove CAST on SIMD scalar operations for stores. * Minor cleanup * Minor cleanup * Feedback * Added test case * Update Runtime_92349.cs * Update Runtime_92349.cs * Update Runtime_92349.cs * Update Runtime_92349.cs * JIT: Fix containment of extract intrinsics as STOREIND sources Fix #92590 --------- Co-authored-by: TIHan Co-authored-by: Jakob Botsch Nielsen --- src/coreclr/jit/lowerxarch.cpp | 5 +- .../JitBlue/Runtime_92349/Runtime_92349.cs | 29 +++++++++ .../Runtime_92349/Runtime_92349.csproj | 9 +++ .../JitBlue/Runtime_92590/Runtime_92590.cs | 63 +++++++++++++++++++ .../Runtime_92590/Runtime_92590.csproj | 8 +++ 5 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_92349/Runtime_92349.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_92349/Runtime_92349.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_92590/Runtime_92590.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_92590/Runtime_92590.csproj diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 319238aaec628f..150ad04a55d99f 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -6504,7 +6504,7 @@ void Lowering::ContainCheckStoreIndir(GenTreeStoreInd* node) case NI_AVX2_ConvertToUInt32: { // These intrinsics are "ins reg/mem, xmm" - isContainable = varTypeIsIntegral(simdBaseType); + isContainable = varTypeIsIntegral(simdBaseType) && (genTypeSize(src) == genTypeSize(node)); break; } @@ -6568,7 +6568,8 @@ void Lowering::ContainCheckStoreIndir(GenTreeStoreInd* node) size_t numArgs = hwintrinsic->GetOperandCount(); GenTree* lastOp = hwintrinsic->Op(numArgs); - isContainable = HWIntrinsicInfo::isImmOp(intrinsicId, lastOp) && lastOp->IsCnsIntOrI(); + isContainable = HWIntrinsicInfo::isImmOp(intrinsicId, lastOp) && lastOp->IsCnsIntOrI() && + (genTypeSize(simdBaseType) == genTypeSize(node)); if (isContainable && (intrinsicId == NI_SSE2_Extract)) { diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92349/Runtime_92349.cs b/src/tests/JIT/Regression/JitBlue/Runtime_92349/Runtime_92349.cs new file mode 100644 index 00000000000000..5de0a28895b268 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_92349/Runtime_92349.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; +using System.Runtime.CompilerServices; +using System.Threading; +using Xunit; + +public static class Runtime_92349 +{ + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + unsafe static void Test(byte* pValue) + { + *pValue = (byte)Sse2.ConvertToInt32(Vector128.Create(-10, 0, 0, 0)); + } + + [Fact] + public unsafe static void EntryPoint() + { + if (Sse2.IsSupported) + { + ulong value = 0; + Test((byte*)Unsafe.AsPointer(ref value)); + Assert.True(value == 246); + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92349/Runtime_92349.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_92349/Runtime_92349.csproj new file mode 100644 index 00000000000000..6bb210527e0797 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_92349/Runtime_92349.csproj @@ -0,0 +1,9 @@ + + + True + True + + + + + \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92590/Runtime_92590.cs b/src/tests/JIT/Regression/JitBlue/Runtime_92590/Runtime_92590.cs new file mode 100644 index 00000000000000..99a5ef2ee5d18d --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_92590/Runtime_92590.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using Xunit; + +public class Runtime_92590 +{ + [Fact] + public static void TestEntryPoint() + { + Span bytes = stackalloc byte[4]; + bytes.Fill(0xff); + TestByteByte(ref bytes[0], 0, Vector256.Create((byte)1)); + + Assert.True(bytes.SequenceEqual(stackalloc byte[] { 0x2, 0xff, 0xff, 0xff })); + + bytes.Fill(0xff); + TestByteInt(ref bytes[0], 0, Vector256.Create(1)); + + Assert.True(bytes.SequenceEqual(stackalloc byte[] { 0x2, 0xff, 0xff, 0xff })); + + int i = int.MaxValue; + TestIntByte(ref i, 0, Vector256.Create((byte)1)); + + Assert.Equal(2, i); + + i = int.MaxValue; + TestIntInt(ref i, 0, Vector256.Create(1)); + + Assert.Equal(2, i); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void TestByteByte(ref byte b, int x, Vector256 vin) + { + Vector256 v = vin + vin; + Unsafe.Add(ref b, x) = v[3]; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void TestByteInt(ref byte b, int x, Vector256 vin) + { + Vector256 v = vin + vin; + Unsafe.Add(ref b, x) = (byte)v[3]; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void TestIntByte(ref int b, int x, Vector256 vin) + { + Vector256 v = vin + vin; + Unsafe.Add(ref b, x) = v[3]; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void TestIntInt(ref int b, int x, Vector256 vin) + { + Vector256 v = vin + vin; + Unsafe.Add(ref b, x) = v[3]; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92590/Runtime_92590.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_92590/Runtime_92590.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_92590/Runtime_92590.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From 7027ff1a3090fd901495d94ef73708ce08747c5c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 03:13:21 -0700 Subject: [PATCH 324/783] define bool as Interop.BOOL to prevent upper bytes setting native bool (#92681) Co-authored-by: yowl --- .../Runtime.Base/src/System/Runtime/InternalCalls.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs index 3c9d6c86ffc323..5c11243bbad99b 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs @@ -62,12 +62,12 @@ internal static class InternalCalls [RuntimeExport("RhCollect")] internal static void RhCollect(int generation, InternalGCCollectionMode mode, bool lowMemoryP = false) { - RhpCollect(generation, mode, lowMemoryP); + RhpCollect(generation, mode, lowMemoryP ? Interop.BOOL.TRUE : Interop.BOOL.FALSE); } [DllImport(Redhawk.BaseName)] [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - private static extern void RhpCollect(int generation, InternalGCCollectionMode mode, bool lowMemoryP); + private static extern void RhpCollect(int generation, InternalGCCollectionMode mode, Interop.BOOL lowMemoryP); [RuntimeExport("RhGetGcTotalMemory")] internal static long RhGetGcTotalMemory() From 8c898a9350f66ee4dd1986249e33625a61d1bd71 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 09:27:17 -0700 Subject: [PATCH 325/783] [release/8.0] Make CoreCLR/NativeAOT assembly compile with .subsections_via_symbols on Apple platforms (#92544) * Make CoreCLR/NativeAOT assembly compile with .subsections_via_symbols on Apple platforms * Fix build with LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT --------- Co-authored-by: Filip Navara Co-authored-by: Jan Kotas --- .../nativeaot/Runtime/arm64/AllocFast.S | 30 +++++---- .../Runtime/arm64/ExceptionHandling.S | 66 +++++++++---------- src/coreclr/nativeaot/Runtime/arm64/GcProbe.S | 12 ++-- .../nativeaot/Runtime/arm64/WriteBarriers.S | 40 +++++------ .../nativeaot/Runtime/unix/unixasmmacros.inc | 5 ++ src/coreclr/pal/inc/unixasmmacros.inc | 5 ++ src/coreclr/vm/arm64/asmhelpers.S | 4 +- 7 files changed, 92 insertions(+), 70 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/arm64/AllocFast.S b/src/coreclr/nativeaot/Runtime/arm64/AllocFast.S index 2bab323e65abca..79ffed2b05210d 100644 --- a/src/coreclr/nativeaot/Runtime/arm64/AllocFast.S +++ b/src/coreclr/nativeaot/Runtime/arm64/AllocFast.S @@ -46,7 +46,7 @@ OFFSETOF__Thread__m_alloc_context__alloc_limit = OFFSETOF__Thread__m_rgbAll add x2, x2, x12 ldr x13, [x1, #OFFSETOF__Thread__m_alloc_context__alloc_limit] cmp x2, x13 - bhi RhpNewFast_RarePath + bhi LOCAL_LABEL(RhpNewFast_RarePath) // Update the alloc pointer to account for the allocation. str x2, [x1, #OFFSETOF__Thread__m_alloc_context__alloc_ptr] @@ -57,7 +57,7 @@ OFFSETOF__Thread__m_alloc_context__alloc_limit = OFFSETOF__Thread__m_rgbAll mov x0, x12 ret -RhpNewFast_RarePath: +LOCAL_LABEL(RhpNewFast_RarePath): mov x1, #0 b C_FUNC(RhpNewObject) LEAF_END RhpNewFast, _TEXT @@ -88,12 +88,12 @@ RhpNewFast_RarePath: bl C_FUNC(RhpGcAlloc) // Set the new objects MethodTable pointer on success. - cbz x0, NewOutOfMemory + cbz x0, LOCAL_LABEL(NewOutOfMemory) POP_COOP_PINVOKE_FRAME EPILOG_RETURN -NewOutOfMemory: +LOCAL_LABEL(NewOutOfMemory): // This is the OOM failure path. We are going to tail-call to a managed helper that will throw // an out of memory exception that the caller of this allocator understands. @@ -113,7 +113,7 @@ NewOutOfMemory: movz x2, MAX_STRING_LENGTH & 0xFFFF movk x2, MAX_STRING_LENGTH >> 16, lsl 16 cmp x1, x2 - bhi StringSizeOverflow + bhi LOCAL_LABEL(StringSizeOverflow) // Compute overall allocation size (align(base size + (element size * elements), 8)). mov w2, #STRING_COMPONENT_SIZE @@ -139,7 +139,7 @@ NewOutOfMemory: add x2, x2, x12 ldr x12, [x3, #OFFSETOF__Thread__m_alloc_context__alloc_limit] cmp x2, x12 - bhi C_FUNC(RhpNewArrayRare) + bhi LOCAL_LABEL(RhNewString_Rare) // Reload new object address into r12. ldr x12, [x3, #OFFSETOF__Thread__m_alloc_context__alloc_ptr] @@ -156,7 +156,7 @@ NewOutOfMemory: ret -StringSizeOverflow: +LOCAL_LABEL(StringSizeOverflow): // We get here if the length of the final string object can not be represented as an unsigned // 32-bit value. We are going to tail-call to a managed helper that will throw // an OOM exception that the caller of this allocator understands. @@ -164,6 +164,9 @@ StringSizeOverflow: // x0 holds MethodTable pointer already mov x1, #1 // Indicate that we should throw OverflowException b C_FUNC(RhExceptionHandling_FailedAllocation) + +LOCAL_LABEL(RhNewString_Rare): + b C_FUNC(RhpNewArrayRare) LEAF_END RhNewString, _Text // Allocate one dimensional, zero based array (SZARRAY). @@ -177,7 +180,7 @@ StringSizeOverflow: // case (32 dimensional MdArray) is less than 0xffff, and thus the product fits in 64 bits. mov x2, #0x7FFFFFFF cmp x1, x2 - bhi ArraySizeOverflow + bhi LOCAL_LABEL(ArraySizeOverflow) ldrh w2, [x0, #OFFSETOF__MethodTable__m_usComponentSize] umull x2, w1, w2 @@ -204,7 +207,7 @@ StringSizeOverflow: add x2, x2, x12 ldr x12, [x3, #OFFSETOF__Thread__m_alloc_context__alloc_limit] cmp x2, x12 - bhi C_FUNC(RhpNewArrayRare) + bhi LOCAL_LABEL(RhpNewArray_Rare) // Reload new object address into x12. ldr x12, [x3, #OFFSETOF__Thread__m_alloc_context__alloc_ptr] @@ -221,7 +224,7 @@ StringSizeOverflow: ret -ArraySizeOverflow: +LOCAL_LABEL(ArraySizeOverflow): // We get here if the size of the final array object can not be represented as an unsigned // 32-bit value. We are going to tail-call to a managed helper that will throw // an overflow exception that the caller of this allocator understands. @@ -229,6 +232,9 @@ ArraySizeOverflow: // x0 holds MethodTable pointer already mov x1, #1 // Indicate that we should throw OverflowException b C_FUNC(RhExceptionHandling_FailedAllocation) + +LOCAL_LABEL(RhpNewArray_Rare): + b C_FUNC(RhpNewArrayRare) LEAF_END RhpNewArray, _TEXT // Allocate one dimensional, zero based array (SZARRAY) using the slow path that calls a runtime helper. @@ -254,12 +260,12 @@ ArraySizeOverflow: bl C_FUNC(RhpGcAlloc) // Set the new objects MethodTable pointer and length on success. - cbz x0, ArrayOutOfMemory + cbz x0, LOCAL_LABEL(ArrayOutOfMemory) POP_COOP_PINVOKE_FRAME EPILOG_RETURN -ArrayOutOfMemory: +LOCAL_LABEL(ArrayOutOfMemory): // This is the OOM failure path. We are going to tail-call to a managed helper that will throw // an out of memory exception that the caller of this allocator understands. diff --git a/src/coreclr/nativeaot/Runtime/arm64/ExceptionHandling.S b/src/coreclr/nativeaot/Runtime/arm64/ExceptionHandling.S index d0425171e1d191..7c04f15ad3b858 100644 --- a/src/coreclr/nativeaot/Runtime/arm64/ExceptionHandling.S +++ b/src/coreclr/nativeaot/Runtime/arm64/ExceptionHandling.S @@ -275,7 +275,7 @@ // where the tail-calling thread had saved LR, which may not match where we have saved LR. ldr x1, [x2, #OFFSETOF__Thread__m_pvHijackedReturnAddress] - cbz x1, NotHijacked + cbz x1, LOCAL_LABEL(NotHijacked) ldr x3, [x2, #OFFSETOF__Thread__m_ppvHijackedReturnAddressLocation] @@ -286,13 +286,13 @@ add x12, sp, #(STACKSIZEOF_ExInfo + SIZEOF__PAL_LIMITED_CONTEXT) // re-compute SP at callsite cmp x3, x12 // if (m_ppvHijackedReturnAddressLocation < SP at callsite) - blo TailCallWasHijacked + blo LOCAL_LABEL(TailCallWasHijacked) // normal case where a valid return address location is hijacked str x1, [x3] - b ClearThreadState + b LOCAL_LABEL(ClearThreadState) -TailCallWasHijacked: +LOCAL_LABEL(TailCallWasHijacked): // Abnormal case where the return address location is now invalid because we ended up here via a tail // call. In this case, our hijacked return address should be the correct caller of this method. @@ -302,13 +302,13 @@ TailCallWasHijacked: str lr, [sp, #(rsp_offsetof_Context + OFFSETOF__PAL_LIMITED_CONTEXT__LR)] str lr, [sp, #(rsp_offsetof_Context + OFFSETOF__PAL_LIMITED_CONTEXT__IP)] -ClearThreadState: +LOCAL_LABEL(ClearThreadState): // clear the Thread's hijack state str xzr, [x2, #OFFSETOF__Thread__m_ppvHijackedReturnAddressLocation] str xzr, [x2, #OFFSETOF__Thread__m_pvHijackedReturnAddress] -NotHijacked: +LOCAL_LABEL(NotHijacked): add x1, sp, #rsp_offsetof_ExInfo // x1 <- ExInfo* str xzr, [x1, #OFFSETOF__ExInfo__m_exception] // pExInfo->m_exception = null @@ -429,13 +429,13 @@ NotHijacked: add x12, x5, #OFFSETOF__Thread__m_ThreadStateFlags -ClearRetry_Catch: +LOCAL_LABEL(ClearRetry_Catch): ldxr w4, [x12] bic w4, w4, #TSF_DoNotTriggerGc stxr w6, w4, [x12] - cbz w6, ClearSuccess_Catch - b ClearRetry_Catch -ClearSuccess_Catch: + cbz w6, LOCAL_LABEL(ClearSuccess_Catch) + b LOCAL_LABEL(ClearRetry_Catch) +LOCAL_LABEL(ClearSuccess_Catch): // // set preserved regs to the values expected by the funclet @@ -487,21 +487,21 @@ ClearSuccess_Catch: ldr x3, [sp, #rsp_offset_x3] // x3 <- current ExInfo* ldr x2, [x2, #OFFSETOF__REGDISPLAY__SP] // x2 <- resume SP value -PopExInfoLoop: +LOCAL_LABEL(PopExInfoLoop): ldr x3, [x3, #OFFSETOF__ExInfo__m_pPrevExInfo] // x3 <- next ExInfo - cbz x3, DonePopping // if (pExInfo == null) { we're done } + cbz x3, LOCAL_LABEL(DonePopping) // if (pExInfo == null) { we're done } cmp x3, x2 - blt PopExInfoLoop // if (pExInfo < resume SP} { keep going } + blt LOCAL_LABEL(PopExInfoLoop) // if (pExInfo < resume SP} { keep going } -DonePopping: +LOCAL_LABEL(DonePopping): str x3, [x1, #OFFSETOF__Thread__m_pExInfoStackHead] // store the new head on the Thread PREPARE_EXTERNAL_VAR_INDIRECT_W RhpTrapThreads, 3 - tbz x3, #TrapThreadsFlags_AbortInProgress_Bit, NoAbort + tbz x3, #TrapThreadsFlags_AbortInProgress_Bit, LOCAL_LABEL(NoAbort) ldr x3, [sp, #rsp_offset_is_not_handling_thread_abort] - cbnz x3, NoAbort + cbnz x3, LOCAL_LABEL(NoAbort) // It was the ThreadAbortException, so rethrow it // reset SP @@ -510,7 +510,7 @@ DonePopping: mov sp, x2 b C_FUNC(RhpThrowHwEx) -NoAbort: +LOCAL_LABEL(NoAbort): // reset SP and jump to continuation address mov sp, x2 br x0 @@ -564,13 +564,13 @@ NoAbort: add x12, x2, #OFFSETOF__Thread__m_ThreadStateFlags -ClearRetry: +LOCAL_LABEL(ClearRetry): ldxr w4, [x12] bic w4, w4, #TSF_DoNotTriggerGc stxr w3, w4, [x12] - cbz w3, ClearSuccess - b ClearRetry -ClearSuccess: + cbz w3, LOCAL_LABEL(ClearSuccess) + b LOCAL_LABEL(ClearRetry) +LOCAL_LABEL(ClearSuccess): // // set preserved regs to the values expected by the funclet @@ -602,13 +602,13 @@ ClearSuccess: ldr x2, [sp, rsp_FinallyFunclet_offset_thread] add x12, x2, #OFFSETOF__Thread__m_ThreadStateFlags -SetRetry: +LOCAL_LABEL(SetRetry): ldxr w1, [x12] orr w1, w1, #TSF_DoNotTriggerGc stxr w3, w1, [x12] - cbz w3, SetSuccess - b SetRetry -SetSuccess: + cbz w3, LOCAL_LABEL(SetSuccess) + b LOCAL_LABEL(SetRetry) +LOCAL_LABEL(SetSuccess): ldp d8, d9, [sp, #0x00] ldp d10, d11, [sp, #0x10] @@ -707,13 +707,13 @@ SetSuccess: add x12, x5, #OFFSETOF__Thread__m_ThreadStateFlags -ClearRetry_Propagate: +LOCAL_LABEL(ClearRetry_Propagate): ldxr w4, [x12] bic w4, w4, #TSF_DoNotTriggerGc stxr w6, w4, [x12] - cbz w6, ClearSuccess_Propagate - b ClearRetry_Propagate -ClearSuccess_Propagate: + cbz w6, LOCAL_LABEL(ClearSuccess_Propagate) + b LOCAL_LABEL(ClearRetry_Propagate) +LOCAL_LABEL(ClearSuccess_Propagate): // // set preserved regs to the values expected by the funclet @@ -749,13 +749,13 @@ ClearSuccess_Propagate: ldr x3, [sp, #rsp_offset_x3] // x3 <- current ExInfo* ldr x2, [x2, #OFFSETOF__REGDISPLAY__SP] // x2 <- resume SP value -Propagate_PopExInfoLoop: +LOCAL_LABEL(Propagate_PopExInfoLoop): ldr x3, [x3, #OFFSETOF__ExInfo__m_pPrevExInfo] // x3 <- next ExInfo - cbz x3, Propagate_DonePopping // if (pExInfo == null) { we're done } + cbz x3, LOCAL_LABEL(Propagate_DonePopping) // if (pExInfo == null) { we're done } cmp x3, x2 - blt Propagate_PopExInfoLoop // if (pExInfo < resume SP} { keep going } + blt LOCAL_LABEL(Propagate_PopExInfoLoop) // if (pExInfo < resume SP} { keep going } -Propagate_DonePopping: +LOCAL_LABEL(Propagate_DonePopping): str x3, [x1, #OFFSETOF__Thread__m_pExInfoStackHead] // store the new head on the Thread // restore preemptive mode diff --git a/src/coreclr/nativeaot/Runtime/arm64/GcProbe.S b/src/coreclr/nativeaot/Runtime/arm64/GcProbe.S index e27834bae6fedd..abe7555b761134 100644 --- a/src/coreclr/nativeaot/Runtime/arm64/GcProbe.S +++ b/src/coreclr/nativeaot/Runtime/arm64/GcProbe.S @@ -127,10 +127,10 @@ NESTED_ENTRY RhpGcProbeHijack, _TEXT, NoHandler FixupHijackedCallstack PREPARE_EXTERNAL_VAR_INDIRECT_W RhpTrapThreads, 3 - tbnz x3, #TrapThreadsFlags_TrapThreads_Bit, WaitForGC + tbnz x3, #TrapThreadsFlags_TrapThreads_Bit, LOCAL_LABEL(WaitForGC) ret -WaitForGC: +LOCAL_LABEL(WaitForGC): orr x12, x12, DEFAULT_FRAME_SAVE_FLAGS + PTFF_SAVE_X0 + PTFF_SAVE_X1 b C_FUNC(RhpWaitForGC) NESTED_END RhpGcProbeHijack @@ -144,11 +144,11 @@ NESTED_ENTRY RhpWaitForGC, _TEXT, NoHandler bl C_FUNC(RhpWaitForGC2) ldr x2, [sp, #OFFSETOF__PInvokeTransitionFrame__m_Flags] - tbnz x2, #PTFF_THREAD_ABORT_BIT, ThrowThreadAbort + tbnz x2, #PTFF_THREAD_ABORT_BIT, LOCAL_LABEL(ThrowThreadAbort) POP_PROBE_FRAME EPILOG_RETURN -ThrowThreadAbort: +LOCAL_LABEL(ThrowThreadAbort): POP_PROBE_FRAME mov w0, #STATUS_REDHAWK_THREAD_ABORT mov x1, lr // return address as exception PC @@ -159,8 +159,10 @@ NESTED_END RhpWaitForGC LEAF_ENTRY RhpGcPoll PREPARE_EXTERNAL_VAR_INDIRECT_W RhpTrapThreads, 0 - cbnz w0, C_FUNC(RhpGcPollRare) // TrapThreadsFlags_None = 0 + cbnz w0, LOCAL_LABEL(RhpGcPoll_Rare) // TrapThreadsFlags_None = 0 ret +LOCAL_LABEL(RhpGcPoll_Rare): + b C_FUNC(RhpGcPollRare) LEAF_END RhpGcPoll NESTED_ENTRY RhpGcPollRare, _TEXT, NoHandler diff --git a/src/coreclr/nativeaot/Runtime/arm64/WriteBarriers.S b/src/coreclr/nativeaot/Runtime/arm64/WriteBarriers.S index d00ffb3a4a9978..835466c3b9e7e4 100644 --- a/src/coreclr/nativeaot/Runtime/arm64/WriteBarriers.S +++ b/src/coreclr/nativeaot/Runtime/arm64/WriteBarriers.S @@ -224,9 +224,11 @@ LEAF_END RhpByRefAssignRefArm64, _TEXT PREPARE_EXTERNAL_VAR_INDIRECT g_highest_address, x12 ccmp x14, x12, #0x2, hs - blo C_FUNC(RhpAssignRefArm64) + bhs LOCAL_LABEL(NotInHeap) -NotInHeap: + b C_FUNC(RhpAssignRefArm64) + +LOCAL_LABEL(NotInHeap): ALTERNATE_ENTRY RhpCheckedAssignRefAVLocation str x15, [x14], 8 ret @@ -293,44 +295,44 @@ LEAF_END RhpAssignRef, _TEXT #ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT PREPARE_EXTERNAL_VAR_INDIRECT_W g_cpuFeatures, 16 - tbz w16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, CmpXchgRetry + tbz w16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, LOCAL_LABEL(CmpXchgRetry) #endif mov x10, x2 ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation casal x10, x1, [x0] // exchange cmp x2, x10 - bne CmpXchgNoUpdate + bne LOCAL_LABEL(CmpXchgNoUpdate) #ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT - b DoCardsCmpXchg -CmpXchgRetry: + b LOCAL_LABEL(DoCardsCmpXchg) +LOCAL_LABEL(CmpXchgRetry): // Check location value is what we expect. ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation2 ldaxr x10, [x0] cmp x10, x2 - bne CmpXchgNoUpdate + bne LOCAL_LABEL(CmpXchgNoUpdate) // Current value matches comparand, attempt to update with the new value. stlxr w12, x1, [x0] - cbnz w12, CmpXchgRetry + cbnz w12, LOCAL_LABEL(CmpXchgRetry) #endif -DoCardsCmpXchg: +LOCAL_LABEL(DoCardsCmpXchg): // We have successfully updated the value of the objectref so now we need a GC write barrier. // The following barrier code takes the destination in x0 and the value in x1 so the arguments are // already correctly set up. INSERT_CHECKED_WRITE_BARRIER_CORE x0, x1 -CmpXchgNoUpdate: +LOCAL_LABEL(CmpXchgNoUpdate): // x10 still contains the original value. mov x0, x10 #ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT - tbnz w16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, NoBarrierCmpXchg + tbnz w16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, LOCAL_LABEL(NoBarrierCmpXchg) InterlockedOperationBarrier -NoBarrierCmpXchg: +LOCAL_LABEL(NoBarrierCmpXchg): #endif ret lr @@ -357,25 +359,25 @@ NoBarrierCmpXchg: #ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT PREPARE_EXTERNAL_VAR_INDIRECT_W g_cpuFeatures, 16 - tbz w16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, ExchangeRetry + tbz w16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, LOCAL_LABEL(ExchangeRetry) #endif ALTERNATE_ENTRY RhpCheckedXchgAVLocation swpal x1, x10, [x0] // exchange #ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT - b DoCardsXchg -ExchangeRetry: + b LOCAL_LABEL(DoCardsXchg) +LOCAL_LABEL(ExchangeRetry): // Read the existing memory location. ALTERNATE_ENTRY RhpCheckedXchgAVLocation2 ldaxr x10, [x0] // Attempt to update with the new value. stlxr w12, x1, [x0] - cbnz w12, ExchangeRetry + cbnz w12, LOCAL_LABEL(ExchangeRetry) #endif -DoCardsXchg: +LOCAL_LABEL(DoCardsXchg): // We have successfully updated the value of the objectref so now we need a GC write barrier. // The following barrier code takes the destination in x0 and the value in x1 so the arguments are // already correctly set up. @@ -386,9 +388,9 @@ DoCardsXchg: mov x0, x10 #ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT - tbnz w16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, NoBarrierXchg + tbnz w16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, LOCAL_LABEL(NoBarrierXchg) InterlockedOperationBarrier -NoBarrierXchg: +LOCAL_LABEL(NoBarrierXchg): #endif ret diff --git a/src/coreclr/nativeaot/Runtime/unix/unixasmmacros.inc b/src/coreclr/nativeaot/Runtime/unix/unixasmmacros.inc index ef6d393fd248b1..bde1d517b7e823 100644 --- a/src/coreclr/nativeaot/Runtime/unix/unixasmmacros.inc +++ b/src/coreclr/nativeaot/Runtime/unix/unixasmmacros.inc @@ -3,6 +3,11 @@ #define INVALIDGCVALUE 0xCCCCCCCD +// Enforce subsections via symbols to workaround bugs in Xcode 15 linker. +#if defined(__APPLE__) +.subsections_via_symbols +#endif + #if defined(__APPLE__) #define C_FUNC(name) _##name #define EXTERNAL_C_FUNC(name) C_FUNC(name) diff --git a/src/coreclr/pal/inc/unixasmmacros.inc b/src/coreclr/pal/inc/unixasmmacros.inc index 658a65bb4b35aa..120b26543e3faa 100644 --- a/src/coreclr/pal/inc/unixasmmacros.inc +++ b/src/coreclr/pal/inc/unixasmmacros.inc @@ -3,6 +3,11 @@ #define INVALIDGCVALUE 0xCCCCCCCD +// Enforce subsections via symbols to workaround bugs in Xcode 15 linker. +#if defined(__APPLE__) +.subsections_via_symbols +#endif + #if defined(__APPLE__) #define C_FUNC(name) _##name #define EXTERNAL_C_FUNC(name) C_FUNC(name) diff --git a/src/coreclr/vm/arm64/asmhelpers.S b/src/coreclr/vm/arm64/asmhelpers.S index cdbe24ec427a98..89dab80461c356 100644 --- a/src/coreclr/vm/arm64/asmhelpers.S +++ b/src/coreclr/vm/arm64/asmhelpers.S @@ -329,7 +329,9 @@ WRITE_BARRIER_ENTRY JIT_CheckedWriteBarrier // branch below is not taken. ccmp x14, x12, #0x2, hs - blo C_FUNC(JIT_WriteBarrier) + bhs LOCAL_LABEL(NotInHeap) + + b C_FUNC(JIT_WriteBarrier) LOCAL_LABEL(NotInHeap): str x15, [x14], 8 From 56749c5b8dac62e96cba794499f363ab310f3530 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 12:13:53 -0700 Subject: [PATCH 326/783] [release/8.0] Fix LLVMAOT Mono runtime variant official build to produce correctly named runtime packs (#92737) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix LLVMAOT Mono runtime variant official build to produce correctly named runtime packs In https://github.com/dotnet/runtime/commit/75ee623b8f0350a4b4be86fa71745a74beb059d1 the condition in src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.props got changed from checking `MonoBundleLLVMOptimizer` to `MonoAOTEnableLLVM` but we weren't setting that property in runtime-official.yml so both jobs produced runtime packs with the same suffix, resulting in the artifact uploads randomly overwriting each other. * Fix more places that need MonoAOTEnableLLVM=true --------- Co-authored-by: Alexander Köplinger --- eng/pipelines/runtime-llvm.yml | 4 ++-- eng/pipelines/runtime-official.yml | 2 +- eng/pipelines/runtime.yml | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/pipelines/runtime-llvm.yml b/eng/pipelines/runtime-llvm.yml index e31e623a0353c8..9d358e5f793086 100644 --- a/eng/pipelines/runtime-llvm.yml +++ b/eng/pipelines/runtime-llvm.yml @@ -119,7 +119,7 @@ extends: testGroup: innerloop nameSuffix: AllSubsets_Mono_LLVMAOT buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) - /p:MonoEnableLLVM=true /p:MonoBundleLLVMOptimizer=true + /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true condition: >- or( eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), @@ -138,7 +138,7 @@ extends: testGroup: innerloop nameSuffix: AllSubsets_Mono_LLVMAOT buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) - /p:MonoEnableLLVM=true /p:MonoBundleLLVMOptimizer=true + /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true condition: >- or( eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index 9c341a04791289..3a9fd8d89ac4b0 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -334,7 +334,7 @@ extends: runtimeFlavor: mono jobParameters: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) - /p:MonoEnableLLVM=true /p:MonoBundleLLVMOptimizer=true + /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true nameSuffix: AllSubsets_Mono_LLVMAOT runtimeVariant: LLVMAOT isOfficialBuild: ${{ variables.isOfficialBuild }} diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 050fc9037db965..3aa0b6504819a7 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -780,7 +780,7 @@ extends: testGroup: innerloop nameSuffix: AllSubsets_Mono_LLVMAOT buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) - /p:MonoEnableLLVM=true /p:MonoBundleLLVMOptimizer=true + /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true condition: >- or( eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), @@ -799,7 +799,7 @@ extends: testGroup: innerloop nameSuffix: AllSubsets_Mono_LLVMAOT buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) - /p:MonoEnableLLVM=true /p:MonoBundleLLVMOptimizer=true + /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true condition: >- or( eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), @@ -1318,7 +1318,7 @@ extends: testGroup: innerloop nameSuffix: AllSubsets_Mono_LLVMAot_RuntimeTests runtimeVariant: llvmaot - buildArgs: -s mono+libs+clr.hosts+clr.iltools -c Release /p:MonoEnableLLVM=true /p:MonoBundleLLVMOptimizer=true + buildArgs: -s mono+libs+clr.hosts+clr.iltools -c Release /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true timeoutInMinutes: 180 condition: >- From 885100b00bc944cbb698bc4cc2ec3ec18007534f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 12:14:48 -0700 Subject: [PATCH 327/783] [release/8.0] Remove all PGO assets except for the runtime PGO archive. (#92735) * Remove all PGO assets except for the runtime PGO archive. * Don't produce a NuGet package for the runtime pack when PGO instrumenting --------- Co-authored-by: Jeremy Koritzinsky Co-authored-by: Jeremy Koritzinsky --- eng/Subsets.props | 4 ++-- .../Microsoft.NETCore.App.Runtime.sfxproj | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Subsets.props b/eng/Subsets.props index 77268ffa7b5d09..eb4151f3a185d6 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -502,7 +502,7 @@ - + @@ -512,7 +512,7 @@ - + diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.sfxproj b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.sfxproj index ba597425bcfc1d..979432e74e5fa8 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.sfxproj +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.sfxproj @@ -7,8 +7,8 @@ dotnet-runtime-internal dotnet-runtime dotnet-runtime-internal - $(SharedFrameworkName).PGO true + false dotnet-runtime-symbols NetCore.SharedFramework true From 29cdcc1a41a4ac00ec1a45f03e70fe95a23215d5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 15:38:12 -0700 Subject: [PATCH 328/783] [release/8.0] Put HasNativeCodeReJITAware into GetFunctionAddress (#92665) * Put HasNativeCodeReJITAware into GetFunctionAddress * get rid of unused code * reverting GetFunctionAddress to previous behavior * removing if statement * clarify method names * add comments * use BreakpointData.codeStartAddress * dac cast * address code review * the method has not been jitted yet --------- Co-authored-by: Mikelle --- src/coreclr/debug/daccess/dacimpl.h | 11 ------ src/coreclr/debug/daccess/task.cpp | 4 +- src/coreclr/debug/di/breakpoint.cpp | 2 + src/coreclr/debug/ee/controller.cpp | 24 ++---------- src/coreclr/debug/ee/debugger.cpp | 56 ++++++--------------------- src/coreclr/debug/ee/debugger.h | 4 +- src/coreclr/debug/ee/functioninfo.cpp | 10 +---- src/coreclr/debug/inc/dbgipcevents.h | 1 + src/coreclr/vm/dbginterface.h | 7 +--- src/coreclr/vm/eedbginterfaceimpl.cpp | 1 - src/coreclr/vm/encee.cpp | 4 +- src/coreclr/vm/method.cpp | 19 +++++---- src/coreclr/vm/method.hpp | 8 ++-- 13 files changed, 41 insertions(+), 110 deletions(-) diff --git a/src/coreclr/debug/daccess/dacimpl.h b/src/coreclr/debug/daccess/dacimpl.h index ddf61370f416e9..8de684a5dae9a2 100644 --- a/src/coreclr/debug/daccess/dacimpl.h +++ b/src/coreclr/debug/daccess/dacimpl.h @@ -1253,17 +1253,6 @@ class ClrDataAccess /* [out] */ union STUB_BUF* outBuffer, /* [out] */ ULONG32* outFlags); - DebuggerJitInfo* GetDebuggerJitInfo(MethodDesc* methodDesc, - TADDR addr) - { - if (g_pDebugger) - { - return g_pDebugger->GetJitInfo(methodDesc, (PBYTE)addr, NULL); - } - - return NULL; - } - HRESULT GetMethodExtents(MethodDesc* methodDesc, METH_EXTENTS** extents); HRESULT GetMethodVarInfo(MethodDesc* methodDesc, diff --git a/src/coreclr/debug/daccess/task.cpp b/src/coreclr/debug/daccess/task.cpp index 9e428e81adef2b..ddbf251b7b9825 100644 --- a/src/coreclr/debug/daccess/task.cpp +++ b/src/coreclr/debug/daccess/task.cpp @@ -5225,7 +5225,7 @@ EnumMethodInstances::Next(ClrDataAccess* dac, } } - if (!m_methodIter.Current()->HasNativeCodeReJITAware()) + if (!m_methodIter.Current()->HasNativeCodeAnyVersion()) { goto NextMethod; } @@ -5243,7 +5243,7 @@ EnumMethodInstances::CdStart(MethodDesc* methodDesc, CLRDATA_ENUM* handle) { if (!methodDesc->HasClassOrMethodInstantiation() && - !methodDesc->HasNativeCodeReJITAware()) + !(methodDesc->HasNativeCodeAnyVersion())) { *handle = 0; return S_FALSE; diff --git a/src/coreclr/debug/di/breakpoint.cpp b/src/coreclr/debug/di/breakpoint.cpp index ad45df5c618ace..568d7fc9fc66ad 100644 --- a/src/coreclr/debug/di/breakpoint.cpp +++ b/src/coreclr/debug/di/breakpoint.cpp @@ -211,11 +211,13 @@ HRESULT CordbFunctionBreakpoint::Activate(BOOL fActivate) if (codeIsIL) { pEvent->BreakpointData.nativeCodeMethodDescToken = pEvent->BreakpointData.nativeCodeMethodDescToken.NullPtr(); + pEvent->BreakpointData.codeStartAddress = 0; } else { pEvent->BreakpointData.nativeCodeMethodDescToken = (m_code.GetValue()->AsNativeCode())->GetVMNativeCodeMethodDescToken().ToLsPtr(); + pEvent->BreakpointData.codeStartAddress = (m_code.GetValue()->AsNativeCode())->GetAddress(); } // Note: we're sending a two-way event, so it blocks here diff --git a/src/coreclr/debug/ee/controller.cpp b/src/coreclr/debug/ee/controller.cpp index 7dd186b4113d44..58e63ab399db2c 100644 --- a/src/coreclr/debug/ee/controller.cpp +++ b/src/coreclr/debug/ee/controller.cpp @@ -1247,26 +1247,8 @@ bool DebuggerController::BindPatch(DebuggerControllerPatch *patch, startAddr = (CORDB_ADDRESS_TYPE *) CORDB_ADDRESS_TO_PTR(patch->GetDJI()->m_addrOfCode); _ASSERTE(startAddr != NULL); } - if (startAddr == NULL) - { - // Should not be trying to place patches on MethodDecs's for stubs. - // These stubs will never get jitted. - CONSISTENCY_CHECK_MSGF(!pMD->IsWrapperStub(), ("Can't place patch at stub md %p, %s::%s", - pMD, pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); - - startAddr = (CORDB_ADDRESS_TYPE *)g_pEEInterface->GetFunctionAddress(pMD); - // - // Code is not available yet to patch. The prestub should - // notify us when it is executed. - // - if (startAddr == NULL) - { - LOG((LF_CORDB, LL_INFO10000, - "DC::BP: Patch at 0x%zx not bindable yet.\n", patch->offset)); - - return false; - } - } + //We should never be calling this function with both a NULL startAddr and a DJI that doesn't have code. + _ASSERTE(startAddr != NULL); } _ASSERTE(!g_pEEInterface->IsStub((const BYTE *)startAddr)); @@ -8656,7 +8638,7 @@ bool DebuggerFuncEvalComplete::SendEvent(Thread *thread, bool fIpChanged) // DebuggerEnCBreakpoint constructor - creates and activates a new EnC breakpoint // // Arguments: -// offset - native offset in the function to place the patch +// offset - IL offset in the function to place the patch // jitInfo - identifies the function in which the breakpoint is being placed // fTriggerType - breakpoint type: either REMAP_PENDING or REMAP_COMPLETE // pAppDomain - the breakpoint applies to the specified AppDomain only diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index a44a9e235f36cd..d58a987244a8ea 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -2841,6 +2841,8 @@ HRESULT Debugger::GetILToNativeMapping(PCODE pNativeCodeStartAddress, ULONG32 cM } CONTRACTL_END; + _ASSERTE(pNativeCodeStartAddress != NULL); + #ifdef PROFILING_SUPPORTED // At this point, we're pulling in the debugger. if (!HasLazyData()) @@ -3007,6 +3009,7 @@ HRESULT Debugger::GetILToNativeMappingIntoArrays( _ASSERTE(pcMap != NULL); _ASSERTE(prguiILOffset != NULL); _ASSERTE(prguiNativeOffset != NULL); + _ASSERTE(pNativeCodeStartAddress != NULL); // Any caller of GetILToNativeMappingIntoArrays had better call // InitializeLazyDataIfNecessary first! @@ -5411,28 +5414,6 @@ void Debugger::ReleaseAllRuntimeThreads(AppDomain *pAppDomain) g_pEEInterface->ResumeFromDebug(pAppDomain); } -// Given a method, get's its EnC version number. 1 if the method is not EnCed. -// Note that MethodDescs are reused between versions so this will give us -// the most recent EnC number. -int Debugger::GetMethodEncNumber(MethodDesc * pMethod) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - } - CONTRACTL_END; - - DebuggerJitInfo * dji = GetLatestJitInfoFromMethodDesc(pMethod); - if (dji == NULL) - { - // If there's no DJI, couldn't have been EnCed. - return 1; - } - return (int) dji->m_encVersion; -} - - bool Debugger::IsJMCMethod(Module* pModule, mdMethodDef tkMethod) { CONTRACTL @@ -6219,25 +6200,6 @@ void Debugger::LockAndSendEnCRemapCompleteEvent(MethodDesc *pMD) Thread *thread = g_pEEInterface->GetThread(); // Note that the debugger lock is reentrant, so we may or may not hold it already. SENDIPCEVENT_BEGIN(this, thread); - - EX_TRY - { - // Ensure the DJI for the latest version of this method has been pre-created. - // It's not clear whether this is necessary or not, but it shouldn't hurt since - // we're going to need to create it anyway since we'll be debugging inside it. - DebuggerJitInfo *dji = g_pDebugger->GetLatestJitInfoFromMethodDesc(pMD); - (void)dji; //prevent "unused variable" error from GCC - _ASSERTE( dji != NULL ); - } - EX_CATCH - { - // GetLatestJitInfo could throw on OOM, but the debugger isn't resiliant to OOM. - // I'm not aware of any other legitimate reason why it may throw, so we'll ASSERT - // if it fails. - _ASSERTE(!"Unexpected exception from Debugger::GetLatestJitInfoFromMethodDesc on EnC remap complete"); - } - EX_END_CATCH(RethrowTerminalExceptions); - // Send an EnC remap complete event to the Right Side. DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer(); InitIPCEvent(ipce, @@ -7865,6 +7827,7 @@ void Debugger::FirstChanceManagedExceptionCatcherFound(Thread *pThread, // Implements DebugInterface // Call by EE/exception. Must be on managed thread _ASSERTE(GetThreadNULLOk() != NULL); + _ASSERTE(pMethodAddr != NULL); // Quick check. if (!CORDebuggerAttached()) @@ -10498,7 +10461,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) DebuggerJitInfo * pDJI = NULL; if ((pMethodDesc != NULL) && (pDMI != NULL)) { - pDJI = pDMI->FindOrCreateInitAndAddJitInfo(pMethodDesc, NULL /* startAddr */); + pDJI = pDMI->FindOrCreateInitAndAddJitInfo(pMethodDesc, PINSTRToPCODE(dac_cast(pEvent->BreakpointData.codeStartAddress))); } { @@ -12625,7 +12588,7 @@ DWORD Debugger::GetThreadIdHelper(Thread *pThread) // does not own the memory provided via vars outparameter. //----------------------------------------------------------------------------- void Debugger::GetVarInfo(MethodDesc * fd, // [IN] method of interest - void *DebuggerVersionToken, // [IN] which edit version + CORDB_ADDRESS nativeCodeAddress, // [IN] which edit version SIZE_T * cVars, // [OUT] size of 'vars' const ICorDebugInfo::NativeVarInfo **vars // [OUT] map telling where local vars are stored ) @@ -12637,7 +12600,7 @@ void Debugger::GetVarInfo(MethodDesc * fd, // [IN] method of interest } CONTRACTL_END; - DebuggerJitInfo * ji = (DebuggerJitInfo *)DebuggerVersionToken; + DebuggerJitInfo * ji = g_pDebugger->GetJitInfo(fd, (const BYTE *)nativeCodeAddress); // If we didn't supply a DJI, then we're asking for the most recent version. if (ji == NULL) @@ -12961,6 +12924,11 @@ HRESULT Debugger::UpdateFunction(MethodDesc* pMD, SIZE_T encVersion) // For each offset in the IL->Native map, set a new EnC breakpoint on the // ones that we know could be remap points. + + // Depending on which DJI was picked, the code might compute different IL offsets. The JIT may not guarantee it produces + // the same set of sequence points for every generic instantiation. + // Inside ENCSequencePointHelper there is logic that skips IL offsets that map to the same native offset. + // Its possible that one version of the code maps two IL offsets to the same native offset but another version of the code maps them to different offsets. PTR_DebuggerILToNativeMap seqMap = pJitInfo->GetSequenceMap(); for (unsigned int i = 0; i < pJitInfo->GetSequenceMapCount(); i++) { diff --git a/src/coreclr/debug/ee/debugger.h b/src/coreclr/debug/ee/debugger.h index 26edd26a96140b..2c2440ddaf6977 100644 --- a/src/coreclr/debug/ee/debugger.h +++ b/src/coreclr/debug/ee/debugger.h @@ -1933,8 +1933,6 @@ class Debugger : public DebugInterface bool IsJMCMethod(Module* pModule, mdMethodDef tkMethod); - int GetMethodEncNumber(MethodDesc * pMethod); - bool FirstChanceManagedException(Thread *pThread, SIZE_T currentIP, SIZE_T currentSP); @@ -1980,7 +1978,7 @@ class Debugger : public DebugInterface #endif // EnC_SUPPORTED void GetVarInfo(MethodDesc * fd, // [IN] method of interest - void *DebuggerVersionToken, // [IN] which edit version + CORDB_ADDRESS nativeCodeAddress, // [IN] which edit version SIZE_T * cVars, // [OUT] size of 'vars' const ICorDebugInfo::NativeVarInfo **vars // [OUT] map telling where local vars are stored ); diff --git a/src/coreclr/debug/ee/functioninfo.cpp b/src/coreclr/debug/ee/functioninfo.cpp index 76d4be3ab232f2..6eaa02d2c6de6f 100644 --- a/src/coreclr/debug/ee/functioninfo.cpp +++ b/src/coreclr/debug/ee/functioninfo.cpp @@ -1565,9 +1565,7 @@ DebuggerJitInfo *DebuggerMethodInfo::FindOrCreateInitAndAddJitInfo(MethodDesc* f GC_NOTRIGGER; } CONTRACTL_END; - _ASSERTE(fd != NULL); - // The debugger doesn't track Lightweight-codegen methods b/c they have no metadata. if (fd->IsDynamicMethod()) { @@ -1576,15 +1574,11 @@ DebuggerJitInfo *DebuggerMethodInfo::FindOrCreateInitAndAddJitInfo(MethodDesc* f if (startAddr == NULL) { - // This will grab the start address for the current code version. startAddr = g_pEEInterface->GetFunctionAddress(fd); if (startAddr == NULL) { - startAddr = fd->GetNativeCodeReJITAware(); - if (startAddr == NULL) - { - return NULL; - } + //The only case this should happen is if we are trying to get the DJI for a method that has not been jitted yet. + return NULL; } } else diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h index 9fe1afd31a54ba..e9643e50f480a2 100644 --- a/src/coreclr/debug/inc/dbgipcevents.h +++ b/src/coreclr/debug/inc/dbgipcevents.h @@ -2011,6 +2011,7 @@ struct MSLAYOUT DebuggerIPCEvent SIZE_T offset; SIZE_T encVersion; LSPTR_METHODDESC nativeCodeMethodDescToken; // points to the MethodDesc if !isIL + CORDB_ADDRESS codeStartAddress; } BreakpointData; struct MSLAYOUT diff --git a/src/coreclr/vm/dbginterface.h b/src/coreclr/vm/dbginterface.h index daa57d25c86cf3..85b9785bccbb9b 100644 --- a/src/coreclr/vm/dbginterface.h +++ b/src/coreclr/vm/dbginterface.h @@ -203,7 +203,7 @@ class DebugInterface // Get debugger variable information for a specific version of a method virtual void GetVarInfo(MethodDesc * fd, // [IN] method of interest - void *DebuggerVersionToken, // [IN] which edit version + CORDB_ADDRESS nativeCodeAddress, // [IN] which edit version SIZE_T * cVars, // [OUT] size of 'vars' const ICorDebugInfo::NativeVarInfo **vars // [OUT] map telling where local vars are stored ) = 0; @@ -262,11 +262,6 @@ class DebugInterface virtual bool IsJMCMethod(Module* pModule, mdMethodDef tkMethod) = 0; - // Given a method, get's its EnC version number. 1 if the method is not EnCed. - // Note that MethodDescs are reused between versions so this will give us - // the most recent EnC number. - virtual int GetMethodEncNumber(MethodDesc * pMethod) = 0; - virtual void SendLogSwitchSetting (int iLevel, int iReason, _In_z_ LPCWSTR pLogSwitchName, diff --git a/src/coreclr/vm/eedbginterfaceimpl.cpp b/src/coreclr/vm/eedbginterfaceimpl.cpp index 792c608918a61d..352a534d5c1a88 100644 --- a/src/coreclr/vm/eedbginterfaceimpl.cpp +++ b/src/coreclr/vm/eedbginterfaceimpl.cpp @@ -630,7 +630,6 @@ PCODE EEDbgInterfaceImpl::GetFunctionAddress(MethodDesc *pFD) SUPPORTS_DAC; } CONTRACTL_END; - return pFD->GetNativeCode(); } diff --git a/src/coreclr/vm/encee.cpp b/src/coreclr/vm/encee.cpp index 1dcfb8bf091f4c..3339462ad7fe77 100644 --- a/src/coreclr/vm/encee.cpp +++ b/src/coreclr/vm/encee.cpp @@ -806,8 +806,8 @@ NOINLINE void EditAndContinueModule::FixContextAndResume( // Get the var info which the codemanager will use for updating // enregistered variables correctly, or variables whose lifetimes differ // at the update point - g_pDebugInterface->GetVarInfo(pMD, oldDebuggerFuncHandle, &oldVarInfoCount, &pOldVarInfo); - g_pDebugInterface->GetVarInfo(pMD, NULL, &newVarInfoCount, &pNewVarInfo); + g_pDebugInterface->GetVarInfo(pMD, oldCodeInfo.GetCodeAddress(), &oldVarInfoCount, &pOldVarInfo); + g_pDebugInterface->GetVarInfo(pMD, newCodeInfo.GetCodeAddress(), &newVarInfoCount, &pNewVarInfo); #ifdef TARGET_X86 // save the frame pointer as FixContextForEnC might step on it. diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 62b24e3dc091c6..29910d6cb4c1c3 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -913,7 +913,6 @@ PCODE MethodDesc::GetNativeCode() WRAPPER_NO_CONTRACT; SUPPORTS_DAC; _ASSERTE(!IsDefaultInterfaceMethod() || HasNativeCodeSlot()); - if (HasNativeCodeSlot()) { // When profiler is enabled, profiler may ask to rejit a code even though we @@ -935,7 +934,7 @@ PCODE MethodDesc::GetNativeCode() return GetStableEntryPoint(); } -PCODE MethodDesc::GetNativeCodeReJITAware() +PCODE MethodDesc::GetNativeCodeAnyVersion() { WRAPPER_NO_CONTRACT; SUPPORTS_DAC; @@ -946,19 +945,23 @@ PCODE MethodDesc::GetNativeCodeReJITAware() return pDefaultCode; } + else { CodeVersionManager *pCodeVersionManager = GetCodeVersionManager(); CodeVersionManager::LockHolder codeVersioningLockHolder; - ILCodeVersion ilVersion = pCodeVersionManager->GetActiveILCodeVersion(PTR_MethodDesc(this)); - if (!ilVersion.IsDefaultVersion()) + ILCodeVersionCollection ilVersionCollection = pCodeVersionManager->GetILCodeVersions(PTR_MethodDesc(this)); + for (ILCodeVersionIterator curIL = ilVersionCollection.Begin(), endIL = ilVersionCollection.End(); curIL != endIL; curIL++) { - NativeCodeVersion activeNativeCodeVersion = ilVersion.GetActiveNativeCodeVersion(PTR_MethodDesc(this)); - if (!activeNativeCodeVersion.IsNull()) + NativeCodeVersionCollection nativeCollection = curIL->GetNativeCodeVersions(PTR_MethodDesc(this)); + for (NativeCodeVersionIterator curNative = nativeCollection.Begin(), endNative = nativeCollection.End(); curNative != endNative; curNative++) { - return activeNativeCodeVersion.GetNativeCode(); + PCODE native = curNative->GetNativeCode(); + if(native != NULL) + { + return native; + } } } - return NULL; } } diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index e51d9f7453d35e..12b3c86e0f7414 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -1373,11 +1373,11 @@ class MethodDesc } // Perf warning: takes the CodeVersionManagerLock on every call - BOOL HasNativeCodeReJITAware() + BOOL HasNativeCodeAnyVersion() { LIMITED_METHOD_DAC_CONTRACT; - return GetNativeCodeReJITAware() != NULL; + return GetNativeCodeAnyVersion() != NULL; } BOOL SetNativeCodeInterlocked(PCODE addr, PCODE pExpected = NULL); @@ -1437,9 +1437,9 @@ class MethodDesc PCODE GetNativeCode(); // Returns GetNativeCode() if it exists, but also checks to see if there - // is a non-default IL code version and returns that. + // is a non-default code version that is populated with a code body and returns that. // Perf warning: takes the CodeVersionManagerLock on every call - PCODE GetNativeCodeReJITAware(); + PCODE GetNativeCodeAnyVersion(); #if defined(FEATURE_JIT_PITCHING) bool IsPitchable(); From 65496c87aa24dd2c4929414f255aaed95b0c183b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 17:20:26 -0700 Subject: [PATCH 329/783] [release/8.0] Update dependencies from dotnet/cecil dotnet/emsdk (#92702) * Update dependencies from https://github.com/dotnet/cecil build 20230926.1 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23468.2 -> To Version 0.11.4-alpha.23476.1 * Update dependencies from https://github.com/dotnet/emsdk build 20230927.1 Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rtm.23475.3 -> To Version 8.0.0-rtm.23477.1 * [wasm] WBT: Update skiasharp reference `blz_deploy_on_build_Debug_True_npl3f0nk_qee.csproj : error NU1903: Package 'SkiaSharp' 2.88.4-preview.76 has a known high severity vulnerability` --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Ankit Jain --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a4ab920e969679..05b333df6f0a03 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -85,14 +85,14 @@ 02fe27cd6a9b001c8feb7938e6ef4b3799745759b - + https://github.com/dotnet/cecil - 89be445dd4936157533ad96bafb95f701430653a + 13d6536e2dc92404da76d61d248badc040eb0de0 - + https://github.com/dotnet/emsdk - 0a2aae889f5ce2803fa227e13963b3fbf3ccb6b0 + ae4eaab4a9415d7f87ca7c6dc0b41ea482fa6337 diff --git a/eng/Versions.props b/eng/Versions.props index 0a745db24ef032..d3895c15f20726 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -213,7 +213,7 @@ 8.0.0-rc.1.23406.6 - 0.11.4-alpha.23468.2 + 0.11.4-alpha.23476.1 8.0.0-rc.1.23406.6 @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.0-rtm.23475.3 + 8.0.0-rtm.23477.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda diff --git a/src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs index fa15c7bef6d817..9633d22701cf0d 100644 --- a/src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs @@ -588,8 +588,8 @@ internal BuildPaths GetBuildPaths(BuildArgs buildArgs, bool forPublish = true) } protected static string GetSkiaSharpReferenceItems() - => @" - + => @" + "; protected static string s_mainReturns42 = @" From 5ab27e3a38f76476a11bc4d7bb4ad4087699e204 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Wed, 27 Sep 2023 21:34:51 -0400 Subject: [PATCH 330/783] [wasm] WBT: Update skiasharp reference (#92747) `blz_deploy_on_build_Debug_True_npl3f0nk_qee.csproj : error NU1903: Package 'SkiaSharp' 2.88.4-preview.76 has a known high severity vulnerability` From 228f2a4132d5dd23309ba81a98f20f1d9e645d59 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 28 Sep 2023 16:53:01 -0400 Subject: [PATCH 331/783] Update dependencies from dotnet/installer (#92745) Updating 'Microsoft.Dotnet.Sdk.Internal': '8.0.100-rc.2.23470.7' => '8.0.100-rtm.23477.25' (from build '202309 27.25' of 'https://github.com/dotnet/installer') --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 05b333df6f0a03..03bccd20386b46 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -398,9 +398,9 @@ https://github.com/NuGet/NuGet.Client 8fef55f5a55a3b4f2c96cd1a9b5ddc51d4b927f8 - + https://github.com/dotnet/installer - dbeae1ac71d95355452952059f35960991cb3fd2 + 744d4d634443834750b5c10cc3029123a6fd975e diff --git a/eng/Versions.props b/eng/Versions.props index d3895c15f20726..ca343d399f9cec 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -258,7 +258,7 @@ 3.1.7 1.0.406601 - 8.0.100-rc.2.23470.7 + 8.0.100-rtm.23477.25 $(MicrosoftDotnetSdkInternalVersion) From 2227dc804850baee5cf5b10a6b58d22f2667740e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 28 Sep 2023 17:58:38 -0700 Subject: [PATCH 332/783] [release/8.0] Bring back CopyOutputSymbolsToPublishDirectory (#92369) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Bring back CopyOutputSymbolsToPublishDirectory I accidentally removed this property from AOT compilation when adding support for Mac dsym bundles. This change re-enables support for suppressing debugging symbols in the output. Fixes #92188 * Update src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets Co-authored-by: Michal Strehovský --------- Co-authored-by: Andy Gocke Co-authored-by: Andy Gocke Co-authored-by: Michal Strehovský --- .../BuildIntegration/Microsoft.NETCore.Native.Publish.targets | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets index caee0777b30ddd..da6c90642f6f13 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets @@ -95,7 +95,10 @@ + + From 575ddd203c232a6bd6f1e3dc0a7aa13660094265 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 28 Sep 2023 20:59:07 -0400 Subject: [PATCH 333/783] Update dependencies from `dotnet/installer` (#92795) Updating 'Microsoft.Dotnet.Sdk.Internal': '8.0.100-rtm.23477.25' => '8.0.100-rtm.23478.7' (from build '20230928.7' of 'https://github.com/dotnet/installer') --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 03bccd20386b46..a9b02fff630165 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -398,9 +398,9 @@ https://github.com/NuGet/NuGet.Client 8fef55f5a55a3b4f2c96cd1a9b5ddc51d4b927f8 - + https://github.com/dotnet/installer - 744d4d634443834750b5c10cc3029123a6fd975e + 46a7370763921ded24dcb70c585ee97883c615d4 diff --git a/eng/Versions.props b/eng/Versions.props index ca343d399f9cec..ef222884b7cd94 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -258,7 +258,7 @@ 3.1.7 1.0.406601 - 8.0.100-rtm.23477.25 + 8.0.100-rtm.23478.7 $(MicrosoftDotnetSdkInternalVersion) From b20f704cc00f390e5560a137deb8f0e64e863e1d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 28 Sep 2023 18:17:11 -0700 Subject: [PATCH 334/783] Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230927.3 (#92762) optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23471.3 -> To Version 1.0.0-prerelease.23477.3 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a9b02fff630165..9896dec90d5913 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -334,21 +334,21 @@ https://github.com/dotnet/arcade 1d451c32dda2314c721adbf8829e1c0cd4e681ff - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - ee166d79f3a269d2a1c6b7d400df7e284b1aa67b + a268dec2bc8ad282a525897b428cf014d5181f77 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - ee166d79f3a269d2a1c6b7d400df7e284b1aa67b + a268dec2bc8ad282a525897b428cf014d5181f77 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - ee166d79f3a269d2a1c6b7d400df7e284b1aa67b + a268dec2bc8ad282a525897b428cf014d5181f77 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - ee166d79f3a269d2a1c6b7d400df7e284b1aa67b + a268dec2bc8ad282a525897b428cf014d5181f77 https://github.com/dotnet/hotreload-utils @@ -384,13 +384,13 @@ d10b02ae5cc670609d920a672985ed4456bdd6b6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - ee166d79f3a269d2a1c6b7d400df7e284b1aa67b + a268dec2bc8ad282a525897b428cf014d5181f77 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - ee166d79f3a269d2a1c6b7d400df7e284b1aa67b + a268dec2bc8ad282a525897b428cf014d5181f77 diff --git a/eng/Versions.props b/eng/Versions.props index ef222884b7cd94..216a4a7406b946 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23471.3 - 1.0.0-prerelease.23471.3 - 1.0.0-prerelease.23471.3 - 1.0.0-prerelease.23471.3 - 1.0.0-prerelease.23471.3 - 1.0.0-prerelease.23471.3 + 1.0.0-prerelease.23477.3 + 1.0.0-prerelease.23477.3 + 1.0.0-prerelease.23477.3 + 1.0.0-prerelease.23477.3 + 1.0.0-prerelease.23477.3 + 1.0.0-prerelease.23477.3 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From f1e4e90e2c125c6066d96bb0b8d64163b1def1a7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 29 Sep 2023 16:38:07 -0700 Subject: [PATCH 335/783] Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20230928.3 (#92816) optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23477.3 -> To Version 1.0.0-prerelease.23478.3 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9896dec90d5913..cfcc40d6319b9d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -334,21 +334,21 @@ https://github.com/dotnet/arcade 1d451c32dda2314c721adbf8829e1c0cd4e681ff - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - a268dec2bc8ad282a525897b428cf014d5181f77 + 492f7464d31d9599531fab2a67bc2422046f5133 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - a268dec2bc8ad282a525897b428cf014d5181f77 + 492f7464d31d9599531fab2a67bc2422046f5133 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - a268dec2bc8ad282a525897b428cf014d5181f77 + 492f7464d31d9599531fab2a67bc2422046f5133 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - a268dec2bc8ad282a525897b428cf014d5181f77 + 492f7464d31d9599531fab2a67bc2422046f5133 https://github.com/dotnet/hotreload-utils @@ -384,13 +384,13 @@ d10b02ae5cc670609d920a672985ed4456bdd6b6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - a268dec2bc8ad282a525897b428cf014d5181f77 + 492f7464d31d9599531fab2a67bc2422046f5133 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - a268dec2bc8ad282a525897b428cf014d5181f77 + 492f7464d31d9599531fab2a67bc2422046f5133 diff --git a/eng/Versions.props b/eng/Versions.props index 216a4a7406b946..ccc6ce33edf6c6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23477.3 - 1.0.0-prerelease.23477.3 - 1.0.0-prerelease.23477.3 - 1.0.0-prerelease.23477.3 - 1.0.0-prerelease.23477.3 - 1.0.0-prerelease.23477.3 + 1.0.0-prerelease.23478.3 + 1.0.0-prerelease.23478.3 + 1.0.0-prerelease.23478.3 + 1.0.0-prerelease.23478.3 + 1.0.0-prerelease.23478.3 + 1.0.0-prerelease.23478.3 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From 8632a7572473caeab7c4eb29d2a1b82fc31a1fc1 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Tue, 3 Oct 2023 04:34:52 +0200 Subject: [PATCH 336/783] Changes from https://github.com/dotnet/runtime/pull/92630 (#92753) --- .../BrowserDebugProxy/EvaluateExpression.cs | 4 +- .../MemberReferenceResolver.cs | 120 ++++++++++++------ .../EvaluateOnCallFrame2Tests.cs | 18 +++ .../EvaluateOnCallFrameTests.cs | 4 +- .../debugger-test/debugger-evaluate-test.cs | 6 +- 5 files changed, 106 insertions(+), 46 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs b/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs index c384f74e9c7223..45d700e122ea7f 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs @@ -387,12 +387,14 @@ private static async Task> ResolveElementAccess(ExpressionSyntaxR { var values = new List(); JObject index = null; + List nestedIndexers = new(); IEnumerable elementAccesses = replacer.elementAccess; foreach (ElementAccessExpressionSyntax elementAccess in elementAccesses.Reverse()) { - index = await resolver.Resolve(elementAccess, replacer.memberAccessValues, index, replacer.variableDefinitions, token); + index = await resolver.Resolve(elementAccess, replacer.memberAccessValues, nestedIndexers, replacer.variableDefinitions, token); if (index == null) throw new ReturnAsErrorException($"Failed to resolve element access for {elementAccess}", "ReferenceError"); + nestedIndexers.Add(index); } values.Add(index); return values; diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 650583a9dc7bf2..e1b9583ddbe3e1 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -366,7 +366,12 @@ async Task ResolveAsInstanceMember(ArraySegment parts, JObject } } - public async Task Resolve(ElementAccessExpressionSyntax elementAccess, Dictionary memberAccessValues, JObject indexObject, List variableDefinitions, CancellationToken token) + public async Task Resolve( + ElementAccessExpressionSyntax elementAccess, + Dictionary memberAccessValues, + List nestedIndexObject, + List variableDefinitions, + CancellationToken token) { try { @@ -376,12 +381,13 @@ public async Task Resolve(ElementAccessExpressionSyntax elementAccess, if (rootObject == null) { - // it might be a jagged array where indexObject should be treated as a new rootObject - rootObject = indexObject; - indexObject = null; + // it might be a jagged array where the previously added nestedIndexObject should be treated as a new rootObject + rootObject = nestedIndexObject.LastOrDefault(); + if (rootObject != null) + nestedIndexObject.RemoveAt(nestedIndexObject.Count - 1); } - ElementIndexInfo elementIdxInfo = await GetElementIndexInfo(); + ElementIndexInfo elementIdxInfo = await GetElementIndexInfo(nestedIndexObject); if (elementIdxInfo is null) return null; @@ -394,6 +400,7 @@ public async Task Resolve(ElementAccessExpressionSyntax elementAccess, if (!DotnetObjectId.TryParse(rootObject?["objectId"]?.Value(), out DotnetObjectId objectId)) throw new InvalidOperationException($"Cannot apply indexing with [] to a primitive object of type '{type}'"); + bool isMultidimensional = elementIdxInfo.DimensionsCount != 1; switch (objectId.Scheme) { case "valuetype": //can be an inlined array @@ -407,7 +414,7 @@ public async Task Resolve(ElementAccessExpressionSyntax elementAccess, } case "array": rootObject["value"] = await context.SdbAgent.GetArrayValues(objectId.Value, token); - if (!elementIdxInfo.IsMultidimensional) + if (!isMultidimensional) { int.TryParse(elementIdxInfo.ElementIdxStr, out elementIdx); return (JObject)rootObject["value"][elementIdx]["value"]; @@ -417,10 +424,8 @@ public async Task Resolve(ElementAccessExpressionSyntax elementAccess, return (JObject)(((JArray)rootObject["value"]).FirstOrDefault(x => x["name"].Value() == elementIdxInfo.ElementIdxStr)["value"]); } case "object": - if (elementIdxInfo.IsMultidimensional) - throw new InvalidOperationException($"Cannot apply indexing with [,] to an object of type '{type}'"); // ToDo: try to use the get_Item for string as well - if (type == "string") + if (!isMultidimensional && type == "string") { var eaExpressionFormatted = elementAccessStrExpression.Replace('.', '_'); // instance_str variableDefinitions.Add(new (eaExpressionFormatted, rootObject, ExpressionEvaluator.ConvertJSToCSharpLocalVariableAssignment(eaExpressionFormatted, rootObject))); @@ -428,7 +433,7 @@ public async Task Resolve(ElementAccessExpressionSyntax elementAccess, var variableDef = await ExpressionEvaluator.GetVariableDefinitions(this, variableDefinitions, invokeToStringInObject: false, token); return await ExpressionEvaluator.EvaluateSimpleExpression(this, eaFormatted, elementAccessStr, variableDef, logger, token); } - if (indexObject is null && elementIdxInfo.IndexingExpression is null) + if (elementIdxInfo.Indexers is null || elementIdxInfo.Indexers.Count == 0) throw new InternalErrorException($"Unable to write index parameter to invoke the method in the runtime."); var typeIds = await context.SdbAgent.GetTypeIdsForObject(objectId.Value, true, token); @@ -441,15 +446,13 @@ public async Task Resolve(ElementAccessExpressionSyntax elementAccess, { MethodInfoWithDebugInformation methodInfo = await context.SdbAgent.GetMethodInfo(methodIds[i], token); ParameterInfo[] paramInfo = methodInfo.GetParametersInfo(); - if (paramInfo.Length == 1) + if (paramInfo.Length == elementIdxInfo.DimensionsCount) { try { - if (indexObject != null && !CheckParametersCompatibility(paramInfo[0].TypeCode, indexObject)) + if (!CheckParametersCompatibility(paramInfo, elementIdxInfo.Indexers)) continue; - ArraySegment buffer = indexObject is null ? - await WriteLiteralExpressionAsIndex(objectId, elementIdxInfo.IndexingExpression, elementIdxInfo.ElementIdxStr) : - await WriteJObjectAsIndex(objectId, indexObject, elementIdxInfo.ElementIdxStr, paramInfo[0].TypeCode); + ArraySegment buffer = await WriteIndexObjectAsIndices(objectId, elementIdxInfo.Indexers, paramInfo); JObject getItemRetObj = await context.SdbAgent.InvokeMethod(buffer, methodIds[i], token); return (JObject)getItemRetObj["value"]; } @@ -470,31 +473,32 @@ await WriteLiteralExpressionAsIndex(objectId, elementIdxInfo.IndexingExpression, throw new ReturnAsErrorException($"Unable to evaluate element access '{elementAccess}': {ex.Message}", ex.GetType().Name); } - async Task GetElementIndexInfo() + async Task GetElementIndexInfo(List nestedIndexers) { - // e.g. x[a[0]], x[a[b[1]]] etc. - if (indexObject is not null) - return new ElementIndexInfo(ElementIdxStr: indexObject["value"].ToString() ); - if (elementAccess.ArgumentList is null) return null; - StringBuilder elementIdxStr = new StringBuilder(); - var multiDimensionalArray = false; + int dimCnt = elementAccess.ArgumentList.Arguments.Count; LiteralExpressionSyntax indexingExpression = null; - for (int i = 0; i < elementAccess.ArgumentList.Arguments.Count; i++) + StringBuilder elementIdxStr = new StringBuilder(); + List indexers = new(); + // nesting should be resolved in reverse order + int nestedIndexersCnt = nestedIndexers.Count - 1; + for (int i = 0; i < dimCnt; i++) { + JObject indexObject; var arg = elementAccess.ArgumentList.Arguments[i]; if (i != 0) { elementIdxStr.Append(", "); - multiDimensionalArray = true; } // e.g. x[1] if (arg.Expression is LiteralExpressionSyntax) { indexingExpression = arg.Expression as LiteralExpressionSyntax; - elementIdxStr.Append(indexingExpression.ToString()); + string expression = indexingExpression.ToString(); + elementIdxStr.Append(expression); + indexers.Add(indexingExpression); } // e.g. x[a] or x[a.b] @@ -508,6 +512,18 @@ async Task GetElementIndexInfo() // x[a] indexObject ??= await Resolve(argParm.Identifier.Text, token); elementIdxStr.Append(indexObject["value"].ToString()); + indexers.Add(indexObject); + } + // nested indexing, e.g. x[a[0]], x[a[b[1]]], x[a[0], b[1]] + else if (arg.Expression is ElementAccessExpressionSyntax) + { + if (nestedIndexers == null || nestedIndexersCnt < 0) + throw new InvalidOperationException($"Cannot resolve nested indexing"); + JObject nestedIndexObject = nestedIndexers[nestedIndexersCnt]; + nestedIndexers.RemoveAt(nestedIndexersCnt); + elementIdxStr.Append(nestedIndexObject["value"].ToString()); + indexers.Add(nestedIndexObject); + nestedIndexersCnt--; } // indexing with expressions, e.g. x[a + 1] else @@ -519,36 +535,57 @@ async Task GetElementIndexInfo() if (idxType != "number") throw new InvalidOperationException($"Cannot index with an object of type '{idxType}'"); elementIdxStr.Append(indexObject["value"].ToString()); + indexers.Add(indexObject); } } return new ElementIndexInfo( + DimensionsCount: dimCnt, ElementIdxStr: elementIdxStr.ToString(), - IsMultidimensional: multiDimensionalArray, - IndexingExpression: indexingExpression); + Indexers: indexers); } - async Task> WriteJObjectAsIndex(DotnetObjectId rootObjId, JObject indexObject, string elementIdxStr, ElementType? expectedType) + async Task> WriteIndexObjectAsIndices(DotnetObjectId rootObjId, List indexObjects, ParameterInfo[] paramInfo) { using var writer = new MonoBinaryWriter(); writer.WriteObj(rootObjId, context.SdbAgent); - writer.Write(1); // number of method args - if (!await writer.WriteJsonValue(indexObject, context.SdbAgent, expectedType, token)) - throw new InternalErrorException($"Parsing index of type {indexObject["type"].Value()} to write it into the buffer failed."); + writer.Write(indexObjects.Count); // number of method args + foreach ((ParameterInfo pi, object indexObject) in paramInfo.Zip(indexObjects)) + { + if (indexObject is JObject indexJObject) + { + // indexed by an identifier name syntax + if (!await writer.WriteJsonValue(indexJObject, context.SdbAgent, pi.TypeCode, token)) + throw new InternalErrorException($"Parsing index of type {indexJObject["type"].Value()} to write it into the buffer failed."); + } + else if (indexObject is LiteralExpressionSyntax expression) + { + // indexed by a literal expression syntax + if (!await writer.WriteConst(expression, context.SdbAgent, token)) + throw new InternalErrorException($"Parsing literal expression index = {expression} to write it into the buffer failed."); + } + else + { + throw new InternalErrorException($"Unexpected index type."); + } + } return writer.GetParameterBuffer(); } + } - async Task> WriteLiteralExpressionAsIndex(DotnetObjectId rootObjId, LiteralExpressionSyntax indexingExpression, string elementIdxStr) + private static bool CheckParametersCompatibility(ParameterInfo[] paramInfos, List indexObjects) + { + if (paramInfos.Length != indexObjects.Count) + return false; + foreach ((ParameterInfo paramInfo, object indexObj) in paramInfos.Zip(indexObjects)) { - using var writer = new MonoBinaryWriter(); - writer.WriteObj(rootObjId, context.SdbAgent); - writer.Write(1); // number of method args - if (!await writer.WriteConst(indexingExpression, context.SdbAgent, token)) - throw new InternalErrorException($"Parsing index of type {indexObject["type"].Value()} to write it into the buffer failed."); - return writer.GetParameterBuffer(); + // shouldn't we check LiteralExpressionSyntax for compatibility as well? + if (indexObj is JObject indexJObj && !CheckParameterCompatibility(paramInfo.TypeCode, indexJObj)) + return false; } + return true; } - private static bool CheckParametersCompatibility(ElementType? paramTypeCode, JObject value) + private static bool CheckParameterCompatibility(ElementType? paramTypeCode, JObject value) { if (!paramTypeCode.HasValue) return true; @@ -871,7 +908,8 @@ public JObject TryGetEvaluationResult(string id) private sealed record ElementIndexInfo( string ElementIdxStr, - bool IsMultidimensional = false, - LiteralExpressionSyntax IndexingExpression = null); + // keeps JObjects and LiteralExpressionSyntaxes: + List Indexers, + int DimensionsCount = 1); } } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs index 051da33469ce2d..b1a79b28ceeefe 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs @@ -731,5 +731,23 @@ await CheckEvaluateFail(id, ("dt+1", "Cannot evaluate '(dt+1\n)': (2,9): error CS0019: Operator '+' cannot be applied to operands of type 'object' and 'int'") ); }); + + [Fact] + public async Task EvaluateObjectIndexingMultidimensional() => await CheckInspectLocalsAtBreakpointSite( + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 12, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); })", + wait_for_event_fn: async (pause_location) => + { + var id = pause_location["callFrames"][0]["callFrameId"].Value(); + await EvaluateOnCallFrameAndCheck(id, + ("f[j, aDouble]", TNumber("3.34")), //only IdentifierNameSyntaxes + ("f[1, aDouble]", TNumber("3.34")), //IdentifierNameSyntax with LiteralExpressionSyntax + ("f[aChar, \"&\", longString]", TString("9-&-longString")), + ("f[f.numArray[j], aDouble]", TNumber("4.34")), //ElementAccessExpressionSyntax + ("f[f.numArray[j], f.numArray[0]]", TNumber("3")), //multiple ElementAccessExpressionSyntaxes + ("f[f.numArray[f.numList[0]], f.numArray[i]]", TNumber("3")), + ("f[f.numArray[f.numList[0]], f.numArray[f.numArray[i]]]", TNumber("4")) + ); + }); } } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index 2ff9bd26a28272..2d0fb87822758a 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -585,7 +585,7 @@ public async Task EvaluateIndexingNegative() => await CheckInspectLocalsAtBreakp Assert.Equal("Unable to evaluate element access 'f.idx0[2]': Cannot apply indexing with [] to a primitive object of type 'number'", res.Error["result"]?["description"]?.Value()); var exceptionDetailsStack = res.Error["exceptionDetails"]?["stackTrace"]?["callFrames"]?[0]; Assert.Equal("DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", exceptionDetailsStack?["functionName"]?.Value()); - Assert.Equal(556, exceptionDetailsStack?["lineNumber"]?.Value()); + Assert.Equal(558, exceptionDetailsStack?["lineNumber"]?.Value()); Assert.Equal(12, exceptionDetailsStack?["columnNumber"]?.Value()); (_, res) = await EvaluateOnCallFrame(id, "f[1]", expect_ok: false ); Assert.Equal( "Unable to evaluate element access 'f[1]': Cannot apply indexing with [] to an object of type 'DebuggerTests.EvaluateLocalsWithIndexingTests.TestEvaluate'", res.Error["result"]?["description"]?.Value()); @@ -722,7 +722,7 @@ public async Task EvaluateIndexingByExpressionNegative() => await CheckInspectLo Assert.Equal("Unable to evaluate element access 'f.numList[\"a\" + 1]': Cannot index with an object of type 'string'", res.Error["result"]?["description"]?.Value()); var exceptionDetailsStack = res.Error["exceptionDetails"]?["stackTrace"]?["callFrames"]?[0]; Assert.Equal("DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", exceptionDetailsStack?["functionName"]?.Value()); - Assert.Equal(556, exceptionDetailsStack?["lineNumber"]?.Value()); + Assert.Equal(558, exceptionDetailsStack?["lineNumber"]?.Value()); Assert.Equal(12, exceptionDetailsStack?["columnNumber"]?.Value()); }); diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs index 480dc30115c430..e46177ecc925b5 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs @@ -522,7 +522,6 @@ public class TestEvaluate public int idx0; public int idx1; - // ToDo: add 2d indexing - https://github.com/dotnet/runtime/issues/76062 public string this[char key] => "res_" + key; public string this[bool key] => key.ToString(); public bool this[string key] => key.Length > 3; @@ -530,11 +529,14 @@ public class TestEvaluate public int this[float key] => (int)key; public int this[decimal key] => (int)key; + public double this[int key1, double key2] => key1 + key2; + public string this[char key1, string key2, string key3] => $"{key1}-{key2}-{key3}"; + public void run() { numList = new List { 1, 2 }; textList = new List { "1", "2" }; - numArray = new int[] { 1, 2 }; + numArray = new int[] { 1, 2, 0 }; textArray = new string[] { "1", "2" }; numArrayOfArrays = new int[][] { numArray, numArray }; numListOfLists = new List> { numList, numList }; From 172d79a458e9468e74bba60dc061a5c94aa21eca Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 19:35:29 -0700 Subject: [PATCH 337/783] [release/8.0] [browser] Remove duplicated marshaling of return value for JSExport (#92886) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove duplicated marshaling of return value for JSExport * Move unmarshal and return value marshal into try block --------- Co-authored-by: Marek Fišera --- .../JSExportCodeGenerator.cs | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSExportCodeGenerator.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSExportCodeGenerator.cs index 0a18241ef7c767..a00fc9e4024f76 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSExportCodeGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSExportCodeGenerator.cs @@ -59,7 +59,7 @@ public JSExportCodeGenerator( public BlockSyntax GenerateJSExportBody() { - StatementSyntax invoke = InvokeSyntax(); + List invoke = InvokeSyntax(); GeneratedStatements statements = GeneratedStatements.Create(_marshallers, _context); bool shouldInitializeVariables = !statements.GuaranteedUnmarshal.IsEmpty || !statements.CleanupCallerAllocated.IsEmpty || !statements.CleanupCalleeAllocated.IsEmpty; VariableDeclarations declarations = VariableDeclarations.GenerateDeclarationsForUnmanagedToManaged(_marshallers, _context, shouldInitializeVariables); @@ -79,7 +79,7 @@ public BlockSyntax GenerateJSExportBody() var tryStatements = new List(); tryStatements.AddRange(statements.Unmarshal); - tryStatements.Add(invoke); + tryStatements.AddRange(invoke); if (!(statements.GuaranteedUnmarshal.IsEmpty && statements.CleanupCalleeAllocated.IsEmpty)) { @@ -93,6 +93,18 @@ public BlockSyntax GenerateJSExportBody() tryStatements.AddRange(statements.Marshal); List allStatements = setupStatements; + + // Wrap unmarshall, invocation and return value marshalling in try-catch. + // In case of exception, marshal exception instead of return value. + var tryInvokeAndMarshal = TryStatement(SingletonList(CatchClause() + .WithDeclaration(CatchDeclaration(IdentifierName(Constants.ExceptionGlobal)).WithIdentifier(Identifier("ex"))) + .WithBlock(Block(SingletonList( + ExpressionStatement(InvocationExpression( + MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, + IdentifierName(Constants.ArgumentException), IdentifierName(Constants.ToJSMethod))) + .WithArgumentList(ArgumentList(SingletonSeparatedList(Argument(IdentifierName("ex"))))))))))) + .WithBlock(Block(tryStatements)); + List finallyStatements = new List(); if (!(statements.GuaranteedUnmarshal.IsEmpty && statements.CleanupCalleeAllocated.IsEmpty)) { @@ -100,16 +112,14 @@ public BlockSyntax GenerateJSExportBody() } finallyStatements.AddRange(statements.CleanupCallerAllocated); + if (finallyStatements.Count > 0) { - allStatements.Add( - TryStatement(Block(tryStatements), default, FinallyClause(Block(finallyStatements)))); - } - else - { - allStatements.AddRange(tryStatements); + tryInvokeAndMarshal = TryStatement(Block(tryInvokeAndMarshal), default, FinallyClause(Block(finallyStatements))); } + allStatements.Add(tryInvokeAndMarshal); + return Block(allStatements); } @@ -175,7 +185,7 @@ private void SetupSyntax(List statementsToUpdate) Argument(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(1))))))))))))); } - private TryStatementSyntax InvokeSyntax() + private List InvokeSyntax() { var statements = new List(); var arguments = new List(); @@ -205,16 +215,8 @@ private TryStatementSyntax InvokeSyntax() IdentifierName(nativeIdentifier), invocation)); statements.Add(statement); - statements.AddRange(_marshallers.ManagedReturnMarshaller.Generator.Generate(_marshallers.ManagedReturnMarshaller.TypeInfo, _context with { CurrentStage = StubCodeContext.Stage.Marshal })); } - return TryStatement(SingletonList(CatchClause() - .WithDeclaration(CatchDeclaration(IdentifierName(Constants.ExceptionGlobal)).WithIdentifier(Identifier("ex"))) - .WithBlock(Block(SingletonList( - ExpressionStatement(InvocationExpression( - MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, - IdentifierName(Constants.ArgumentException), IdentifierName(Constants.ToJSMethod))) - .WithArgumentList(ArgumentList(SingletonSeparatedList(Argument(IdentifierName("ex"))))))))))) - .WithBlock(Block(statements)); + return statements; } From 8e365ee9e1c1b4da3300b0ecb672ea7c85b1f220 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 19:35:48 -0700 Subject: [PATCH 338/783] fix https://github.com/dotnet/runtime/issues/92713 (#92890) Co-authored-by: pavelsavara --- src/mono/wasm/runtime/startup.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index d8eab74d8b2500..c385844dfd30bb 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -5,7 +5,7 @@ import MonoWasmThreads from "consts:monoWasmThreads"; import WasmEnableLegacyJsInterop from "consts:wasmEnableLegacyJsInterop"; import { DotnetModuleInternal, CharPtrNull } from "./types/internal"; -import { linkerDisableLegacyJsInterop, ENVIRONMENT_IS_PTHREAD, exportedRuntimeAPI, INTERNAL, loaderHelpers, Module, runtimeHelpers, createPromiseController, mono_assert, linkerWasmEnableSIMD, linkerWasmEnableEH } from "./globals"; +import { linkerDisableLegacyJsInterop, ENVIRONMENT_IS_PTHREAD, exportedRuntimeAPI, INTERNAL, loaderHelpers, Module, runtimeHelpers, createPromiseController, mono_assert, linkerWasmEnableSIMD, linkerWasmEnableEH, ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_WORKER } from "./globals"; import cwraps, { init_c_exports } from "./cwraps"; import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug"; import { toBase64StringImpl } from "./base64"; @@ -273,6 +273,10 @@ async function onRuntimeInitializedAsync(userOnRuntimeInitialized: () => void) { bindings_init(); runtimeHelpers.runtimeReady = true; + if (ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER) { + Module.runtimeKeepalivePush(); + } + if (MonoWasmThreads) { runtimeHelpers.javaScriptExports.install_synchronization_context(); runtimeHelpers.jsSynchronizationContextInstalled = true; From ef6283ac0a14c78d9e9fef4841545099bd7ad12b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 19:39:16 -0700 Subject: [PATCH 339/783] [release/8.0] Update dependencies from dotnet/roslyn (#92503) * Update dependencies from https://github.com/dotnet/roslyn build 20230922.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23472.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230922.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23472.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230922.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23472.5 * Update dependencies from https://github.com/dotnet/roslyn build 20230922.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23472.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230922.7 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23472.7 * Update dependencies from https://github.com/dotnet/roslyn build 20230922.8 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23472.8 * Update dependencies from https://github.com/dotnet/roslyn build 20230922.9 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23472.9 * Update dependencies from https://github.com/dotnet/roslyn build 20230922.10 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23472.10 * Update dependencies from https://github.com/dotnet/roslyn build 20230923.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23473.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230923.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23473.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230923.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23473.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230923.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23473.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230924.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23474.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230924.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23474.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230924.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23474.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230925.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23475.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230925.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23475.2 * Update dependencies from https://github.com/dotnet/roslyn build 20230925.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23475.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230925.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23475.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230925.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23475.5 * Update dependencies from https://github.com/dotnet/roslyn build 20230925.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23475.6 * Update dependencies from https://github.com/dotnet/roslyn build 20230925.7 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23475.7 * Update dependencies from https://github.com/dotnet/roslyn build 20230925.8 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23475.8 * Update dependencies from https://github.com/dotnet/roslyn build 20230925.10 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23475.10 * Update dependencies from https://github.com/dotnet/roslyn build 20230926.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23476.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230926.6 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23476.6 * Small refactor to BuildElement to address NRT changes * Update dependencies from https://github.com/dotnet/roslyn build 20230926.13 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23476.13 * Update dependencies from https://github.com/dotnet/roslyn build 20230926.14 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23476.14 * Update dependencies from https://github.com/dotnet/roslyn build 20230926.15 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23476.15 * Update dependencies from https://github.com/dotnet/roslyn build 20230926.21 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23476.21 * Update dependencies from https://github.com/dotnet/roslyn build 20230926.22 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23476.22 * Update dependencies from https://github.com/dotnet/roslyn build 20230927.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23477.1 * Update dependencies from https://github.com/dotnet/roslyn build 20230927.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23477.4 * Update dependencies from https://github.com/dotnet/roslyn build 20230928.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23478.3 * Update dependencies from https://github.com/dotnet/roslyn build 20230928.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23478.4 * Update dependencies from https://github.com/dotnet/roslyn build 20231001.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23472.2 -> To Version 4.8.0-3.23501.1 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Levi Broderick Co-authored-by: Fred Silberberg --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- .../X509Certificates/ChainPal.Apple.cs | 16 +++++++--------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cfcc40d6319b9d..1f220ede26d087 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - aa7e4da5341196be494ca4bb0c719d7bef3e396a + 0d735148bbb4cb511be547fbc1db63a2c81a821d - + https://github.com/dotnet/roslyn - aa7e4da5341196be494ca4bb0c719d7bef3e396a + 0d735148bbb4cb511be547fbc1db63a2c81a821d - + https://github.com/dotnet/roslyn - aa7e4da5341196be494ca4bb0c719d7bef3e396a + 0d735148bbb4cb511be547fbc1db63a2c81a821d https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index ccc6ce33edf6c6..1663485ec06805 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -44,9 +44,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23472.2 - 4.8.0-3.23472.2 - 4.8.0-3.23472.2 + 4.8.0-3.23501.1 + 4.8.0-3.23501.1 + 4.8.0-3.23501.1 @@ -17,15 +22,19 @@ - - - + + + + + + + @@ -38,20 +47,20 @@ - + + - - + + + - - diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/BinderInvocation.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/BinderInvocation.cs index ad7c4c09204d4b..b1cf51acb3b4a6 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/BinderInvocation.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/BinderInvocation.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; @@ -9,8 +9,17 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { - internal sealed record BinderInvocation(IInvocationOperation Operation, Location Location) + internal sealed class BinderInvocation { + private BinderInvocation(IInvocationOperation operation, Location location) + { + Operation = operation; + Location = location; + } + + public IInvocationOperation Operation { get; } + public Location Location { get; } + public static BinderInvocation? Create(GeneratorSyntaxContext context, CancellationToken cancellationToken) { Debug.Assert(IsCandidateSyntaxNode(context.Node)); @@ -35,8 +44,8 @@ public static bool IsCandidateSyntaxNode(SyntaxNode node) } && IsCandidateBindingMethodName(memberName); static bool IsCandidateBindingMethodName(string name) => - IsCandidateMethodName_ConfigurationBinder(name) || - IsCandidateMethodName_OptionsBuilderConfigurationExtensions(name) || + IsValidMethodName_ConfigurationBinder(name) || + IsValidMethodName_OptionsBuilderConfigurationExtensions(name) || IsValidMethodName_OptionsConfigurationServiceCollectionExtensions(name); } @@ -62,10 +71,10 @@ public static bool IsBindingOperation(IInvocationOperation operation) { "ConfigurationBinder" => containingNamespaceName is "Microsoft.Extensions.Configuration" && - IsCandidateMethodName_ConfigurationBinder(methodName), + IsValidMethodName_ConfigurationBinder(methodName), "OptionsBuilderConfigurationExtensions" => containingNamespaceName is "Microsoft.Extensions.DependencyInjection" && - IsCandidateMethodName_OptionsBuilderConfigurationExtensions(methodName), + IsValidMethodName_OptionsBuilderConfigurationExtensions(methodName), "OptionsConfigurationServiceCollectionExtensions" => containingNamespaceName is "Microsoft.Extensions.DependencyInjection" && IsValidMethodName_OptionsConfigurationServiceCollectionExtensions(methodName), @@ -73,16 +82,10 @@ containingNamespaceName is "Microsoft.Extensions.DependencyInjection" && }; } - private static bool IsCandidateMethodName_ConfigurationBinder(string name) => name is - nameof(MethodsToGen_ConfigurationBinder.Bind) or - nameof(MethodsToGen_ConfigurationBinder.Get) or - nameof(MethodsToGen_ConfigurationBinder.GetValue); + private static bool IsValidMethodName_ConfigurationBinder(string name) => name is "Bind" or "Get" or "GetValue"; - private static bool IsCandidateMethodName_OptionsBuilderConfigurationExtensions(string name) => name is - nameof(MethodsToGen_Extensions_OptionsBuilder.Bind) or - nameof(MethodsToGen_Extensions_OptionsBuilder.BindConfiguration); + private static bool IsValidMethodName_OptionsBuilderConfigurationExtensions(string name) => name is "Bind" or "BindConfiguration"; - private static bool IsValidMethodName_OptionsConfigurationServiceCollectionExtensions(string name) => name is - nameof(MethodsToGen_Extensions_ServiceCollection.Configure); + private static bool IsValidMethodName_OptionsConfigurationServiceCollectionExtensions(string name) => name is "Configure"; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/ConfigurationBinder.cs index 3996142adf9089..645786e35c1c55 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/ConfigurationBinder.cs @@ -6,28 +6,29 @@ using System.Linq; using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis; +using System.Diagnostics; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { public sealed partial class ConfigurationBindingGenerator { - private sealed partial class Parser + internal sealed partial class Parser { private void ParseInvocation_ConfigurationBinder(BinderInvocation invocation) { switch (invocation.Operation.TargetMethod.Name) { - case nameof(MethodsToGen_ConfigurationBinder.Bind): + case "Bind": { ParseBindInvocation_ConfigurationBinder(invocation); } break; - case nameof(MethodsToGen_ConfigurationBinder.Get): + case "Get": { ParseGetInvocation(invocation); } break; - case nameof(MethodsToGen_ConfigurationBinder.GetValue): + case "GetValue": { ParseGetValueInvocation(invocation); } @@ -46,39 +47,39 @@ private void ParseBindInvocation_ConfigurationBinder(BinderInvocation invocation return; } - MethodsToGen_ConfigurationBinder overload = MethodsToGen_ConfigurationBinder.None; + MethodsToGen overload = MethodsToGen.None; if (paramCount is 2) { - overload = MethodsToGen_ConfigurationBinder.Bind_instance; + overload = MethodsToGen.ConfigBinder_Bind_instance; } else if (paramCount is 3) { if (@params[1].Type.SpecialType is SpecialType.System_String) { - overload = MethodsToGen_ConfigurationBinder.Bind_key_instance; + overload = MethodsToGen.ConfigBinder_Bind_key_instance; } else if (SymbolEqualityComparer.Default.Equals(@params[2].Type, _typeSymbols.ActionOfBinderOptions)) { - overload = MethodsToGen_ConfigurationBinder.Bind_instance_BinderOptions; + overload = MethodsToGen.ConfigBinder_Bind_instance_BinderOptions; } } - if (overload is MethodsToGen_ConfigurationBinder.None) + if (overload is MethodsToGen.None) { return; } int instanceIndex = overload switch { - MethodsToGen_ConfigurationBinder.Bind_instance => 1, - MethodsToGen_ConfigurationBinder.Bind_instance_BinderOptions => 1, - MethodsToGen_ConfigurationBinder.Bind_key_instance => 2, + MethodsToGen.ConfigBinder_Bind_instance => 1, + MethodsToGen.ConfigBinder_Bind_instance_BinderOptions => 1, + MethodsToGen.ConfigBinder_Bind_key_instance => 2, _ => throw new InvalidOperationException() }; IArgumentOperation instanceArg = GetArgumentForParameterAtIndex(operation.Arguments, instanceIndex); - if (instanceArg.Parameter.Type.SpecialType != SpecialType.System_Object) + if (instanceArg.Parameter?.Type.SpecialType is not SpecialType.System_Object) { return; } @@ -87,20 +88,17 @@ private void ParseBindInvocation_ConfigurationBinder(BinderInvocation invocation if (!IsValidRootConfigType(type)) { - _context.ReportDiagnostic(Diagnostic.Create(Diagnostics.CouldNotDetermineTypeInfo, invocation.Location)); + RecordDiagnostic(DiagnosticDescriptors.CouldNotDetermineTypeInfo, invocation.Location); return; } - if (type!.IsValueType) + if (type.IsValueType) { - _context.ReportDiagnostic(Diagnostic.Create(Diagnostics.ValueTypesInvalidForBind, invocation.Location, type)); + RecordDiagnostic(DiagnosticDescriptors.ValueTypesInvalidForBind, invocation.Location, messageArgs: new object[] { type }); return; } - if (GetTargetTypeForRootInvocationCore(type, invocation.Location) is TypeSpec typeSpec) - { - RegisterInterceptor(overload, typeSpec, invocation.Operation); - } + EnqueueTargetTypeForRootInvocation(type, overload, invocation); static ITypeSymbol? ResolveType(IOperation conversionOperation) => conversionOperation switch @@ -144,7 +142,7 @@ private void ParseGetInvocation(BinderInvocation invocation) return; } - MethodsToGen_ConfigurationBinder overload = MethodsToGen_ConfigurationBinder.None; + MethodsToGen overload = MethodsToGen.None; ITypeSymbol? type; if (targetMethod.IsGenericMethod) @@ -158,11 +156,11 @@ private void ParseGetInvocation(BinderInvocation invocation) if (paramCount is 1) { - overload = MethodsToGen_ConfigurationBinder.Get_T; + overload = MethodsToGen.ConfigBinder_Get_T; } else if (paramCount is 2 && SymbolEqualityComparer.Default.Equals(@params[1].Type, _typeSymbols.ActionOfBinderOptions)) { - overload = MethodsToGen_ConfigurationBinder.Get_T_BinderOptions; + overload = MethodsToGen.ConfigBinder_Get_T_BinderOptions; } } else if (paramCount > 3) @@ -176,20 +174,15 @@ private void ParseGetInvocation(BinderInvocation invocation) if (paramCount is 2) { - overload = MethodsToGen_ConfigurationBinder.Get_TypeOf; + overload = MethodsToGen.ConfigBinder_Get_TypeOf; } else if (paramCount is 3 && SymbolEqualityComparer.Default.Equals(@params[2].Type, _typeSymbols.ActionOfBinderOptions)) { - overload = MethodsToGen_ConfigurationBinder.Get_TypeOf_BinderOptions; + overload = MethodsToGen.ConfigBinder_Get_TypeOf_BinderOptions; } } - if (GetTargetTypeForRootInvocation(type, invocation.Location) is TypeSpec typeSpec) - { - RegisterInvocation(overload, invocation.Operation); - RegisterTypeForGetCoreGen(typeSpec); - } - + EnqueueTargetTypeForRootInvocation(type, overload, invocation); } private void ParseGetValueInvocation(BinderInvocation invocation) @@ -199,7 +192,7 @@ private void ParseGetValueInvocation(BinderInvocation invocation) ImmutableArray @params = targetMethod.Parameters; int paramCount = @params.Length; - MethodsToGen_ConfigurationBinder overload = MethodsToGen_ConfigurationBinder.None; + MethodsToGen overload = MethodsToGen.None; ITypeSymbol? type; if (targetMethod.IsGenericMethod) @@ -213,11 +206,11 @@ private void ParseGetValueInvocation(BinderInvocation invocation) if (paramCount is 2) { - overload = MethodsToGen_ConfigurationBinder.GetValue_T_key; + overload = MethodsToGen.ConfigBinder_GetValue_T_key; } else if (paramCount is 3 && SymbolEqualityComparer.Default.Equals(@params[2].Type, type)) { - overload = MethodsToGen_ConfigurationBinder.GetValue_T_key_defaultValue; + overload = MethodsToGen.ConfigBinder_GetValue_T_key_defaultValue; } } else if (paramCount > 4) @@ -236,45 +229,56 @@ private void ParseGetValueInvocation(BinderInvocation invocation) if (paramCount is 3) { - overload = MethodsToGen_ConfigurationBinder.GetValue_TypeOf_key; + overload = MethodsToGen.ConfigBinder_GetValue_TypeOf_key; } else if (paramCount is 4 && @params[3].Type.SpecialType is SpecialType.System_Object) { - overload = MethodsToGen_ConfigurationBinder.GetValue_TypeOf_key_defaultValue; + overload = MethodsToGen.ConfigBinder_GetValue_TypeOf_key_defaultValue; } } - ITypeSymbol effectiveType = (IsNullable(type, out ITypeSymbol? underlyingType) ? underlyingType : type)!; - if (!IsValidRootConfigType(type)) { - _context.ReportDiagnostic(Diagnostic.Create(Diagnostics.CouldNotDetermineTypeInfo, invocation.Location)); + RecordDiagnostic(DiagnosticDescriptors.CouldNotDetermineTypeInfo, invocation.Location); return; } - if (IsParsableFromString(effectiveType, out _) && - GetTargetTypeForRootInvocationCore(type, invocation.Location) is TypeSpec typeSpec) + ITypeSymbol effectiveType = IsNullable(type, out ITypeSymbol? underlyingType) ? underlyingType : type; + + if (IsParsableFromString(effectiveType, out _)) { - RegisterInvocation(overload, invocation.Operation); - RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.GetValueCore, typeSpec); + EnqueueTargetTypeForRootInvocation(type, overload, invocation); } } - private void RegisterInvocation(MethodsToGen_ConfigurationBinder overload, IInvocationOperation operation) + private void RegisterInterceptor_ConfigurationBinder(TypeParseInfo typeParseInfo, TypeSpec typeSpec) { - _sourceGenSpec.MethodsToGen_ConfigurationBinder |= overload; - RegisterInterceptor(overload, operation); - } + MethodsToGen overload = typeParseInfo.BindingOverload; + IInvocationOperation invocationOperation = typeParseInfo.BinderInvocation!.Operation; + Debug.Assert((MethodsToGen.ConfigBinder_Any & overload) is not 0); - /// - /// Registers generated Bind methods as interceptors. This is done differently from other root - /// methods because we need to - /// explicitly account for the type to bind, to avoid type-check issues for polymorphic objects. - /// - private void RegisterInterceptor(MethodsToGen_ConfigurationBinder overload, TypeSpec typeSpec, IInvocationOperation operation) - { - _sourceGenSpec.MethodsToGen_ConfigurationBinder |= overload; - _sourceGenSpec.InterceptionInfo_ConfigBinder.RegisterOverloadInfo(overload, typeSpec, operation); + if ((MethodsToGen.ConfigBinder_Bind & overload) is not 0) + { + if (typeSpec is ComplexTypeSpec complexTypeSpec && + _helperInfoBuilder!.TryRegisterTransitiveTypesForMethodGen(complexTypeSpec.TypeRef)) + { + _interceptorInfoBuilder.RegisterInterceptor_ConfigBinder_Bind(overload, complexTypeSpec, invocationOperation); + } + } + else + { + Debug.Assert((MethodsToGen.ConfigBinder_Get & overload) is not 0 || + (MethodsToGen.ConfigBinder_GetValue & overload) is not 0); + + bool registered = (MethodsToGen.ConfigBinder_Get & overload) is not 0 + ? _helperInfoBuilder!.TryRegisterTypeForGetGen(typeSpec) + : _helperInfoBuilder!.TryRegisterTypeForGetValueGen(typeSpec); + + if (registered) + { + _interceptorInfoBuilder.RegisterInterceptor(overload, invocationOperation); + } + } } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/Diagnostics.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/DiagnosticDescriptors.cs similarity index 82% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/Diagnostics.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/DiagnosticDescriptors.cs index d6d816545bcd0a..3f694c78be8309 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/Diagnostics.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/DiagnosticDescriptors.cs @@ -9,9 +9,9 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { public sealed partial class ConfigurationBindingGenerator { - private sealed partial class Parser + internal sealed partial class Parser { - internal static class Diagnostics + private static class DiagnosticDescriptors { public static DiagnosticDescriptor TypeNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.TypeNotSupported)); public static DiagnosticDescriptor MissingPublicInstanceConstructor { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.MissingPublicInstanceConstructor)); @@ -62,6 +62,20 @@ private static DiagnosticDescriptor CreateTypeNotSupportedDescriptor(string name category: ProjectName, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true); + + public static DiagnosticDescriptor GetNotSupportedDescriptor(NotSupportedReason reason) => + reason switch + { + NotSupportedReason.UnknownType => TypeNotSupported, + NotSupportedReason.MissingPublicInstanceConstructor => MissingPublicInstanceConstructor, + NotSupportedReason.CollectionNotSupported => CollectionNotSupported, + NotSupportedReason.DictionaryKeyNotSupported => DictionaryKeyNotSupported, + NotSupportedReason.ElementTypeNotSupported => ElementTypeNotSupported, + NotSupportedReason.MultipleParameterizedConstructors => MultipleParameterizedConstructors, + NotSupportedReason.MultiDimArraysNotSupported => MultiDimArraysNotSupported, + NotSupportedReason.NullableUnderlyingTypeNotSupported => NullableUnderlyingTypeNotSupported, + _ => throw new InvalidOperationException() + }; } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/Extensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/Extensions.cs index fa0b3691ec4047..f685842639966a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/Extensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/Extensions.cs @@ -8,6 +8,54 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { + public sealed partial class ConfigurationBindingGenerator + { + internal sealed partial class Parser + { + private readonly struct TypeParseInfo + { + public ITypeSymbol TypeSymbol { get; private init; } + public string TypeName { get; private init; } + public MethodsToGen BindingOverload { get; private init; } + public BinderInvocation BinderInvocation { get; private init; } + public ContainingTypeDiagnosticInfo? ContainingTypeDiagnosticInfo { get; private init; } + + public static TypeParseInfo Create(ITypeSymbol typeSymbol, MethodsToGen overload, BinderInvocation invocation, ContainingTypeDiagnosticInfo? containingTypeDiagInfo = null) => + new TypeParseInfo + { + TypeSymbol = typeSymbol, + TypeName = typeSymbol.GetName(), + BindingOverload = overload, + BinderInvocation = invocation, + ContainingTypeDiagnosticInfo = containingTypeDiagInfo, + }; + + public TypeParseInfo ToTransitiveTypeParseInfo(ITypeSymbol memberType, DiagnosticDescriptor? diagDescriptor = null, string? memberName = null) + { + ContainingTypeDiagnosticInfo? diagnosticInfo = diagDescriptor is null + ? null + : new() + { + TypeName = TypeName, + Descriptor = diagDescriptor, + MemberName = memberName, + ContainingTypeInfo = ContainingTypeDiagnosticInfo, + }; + + return Create(memberType, BindingOverload, BinderInvocation, diagnosticInfo); + } + } + + private sealed class ContainingTypeDiagnosticInfo + { + public required string TypeName { get; init; } + public required string? MemberName { get; init; } + public required DiagnosticDescriptor Descriptor { get; init; } + public required ContainingTypeDiagnosticInfo? ContainingTypeInfo { get; init; } + } + } + } + internal static class ParserExtensions { private static readonly SymbolDisplayFormat s_identifierCompatibleFormat = new SymbolDisplayFormat( @@ -16,6 +64,12 @@ internal static class ParserExtensions genericsOptions: SymbolDisplayGenericsOptions.None, miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes); + private static readonly SymbolDisplayFormat s_minimalDisplayFormat = new SymbolDisplayFormat( + globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Omitted, + typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes, + genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, + miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes); + public static void RegisterCacheEntry(this Dictionary cache, TKey key, TEntry entry) where TKey : notnull where TValue : ICollection, new() @@ -28,12 +82,6 @@ public static void RegisterCacheEntry(this Dictionary> source, out ComplexTypeSpec Key, out List Value) - { - Key = (ComplexTypeSpec)source.Key; - Value = source.Value; - } - public static string ToIdentifierCompatibleSubstring(this ITypeSymbol type) { if (type is IArrayTypeSymbol arrayType) @@ -64,5 +112,15 @@ public static string ToIdentifierCompatibleSubstring(this ITypeSymbol type) return sb.ToString(); } + + public static (string? Namespace, string DisplayString, string Name) GetTypeName(this ITypeSymbol type) + { + string? @namespace = type.ContainingNamespace is { IsGlobalNamespace: false } containingNamespace ? containingNamespace.ToDisplayString() : null; + string displayString = type.ToDisplayString(s_minimalDisplayFormat); + string name = (@namespace is null ? string.Empty : @namespace + ".") + displayString.Replace(".", "+"); + return (@namespace, displayString, name); + } + + public static string GetName(this ITypeSymbol type) => GetTypeName(type).Name; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/KnownTypeSymbols.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/KnownTypeSymbols.cs similarity index 96% rename from src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/KnownTypeSymbols.cs rename to src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/KnownTypeSymbols.cs index e381dc9c7c43ee..07dae8689782e4 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/KnownTypeSymbols.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/KnownTypeSymbols.cs @@ -11,7 +11,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { - internal sealed record KnownTypeSymbols + internal sealed class KnownTypeSymbols { public CSharpCompilation Compilation { get; } @@ -37,7 +37,7 @@ internal sealed record KnownTypeSymbols public INamedTypeSymbol? OptionsConfigurationServiceCollectionExtensions { get; } public INamedTypeSymbol GenericIList_Unbound { get; } - public INamedTypeSymbol GenericICollection_Unbound { get; } + public INamedTypeSymbol? GenericICollection_Unbound { get; } public INamedTypeSymbol GenericICollection { get; } public INamedTypeSymbol GenericIEnumerable_Unbound { get; } public INamedTypeSymbol IEnumerable { get; } @@ -61,7 +61,8 @@ public KnownTypeSymbols(CSharpCompilation compilation) { Compilation = compilation; - // Primitives (needed because they are Microsoft.CodeAnalysis.SpecialType.None) + // Primitives + String = compilation.GetSpecialType(SpecialType.System_String); CultureInfo = compilation.GetBestTypeByMetadataName(typeof(CultureInfo)); DateOnly = compilation.GetBestTypeByMetadataName("System.DateOnly"); DateTimeOffset = compilation.GetBestTypeByMetadataName(typeof(DateTimeOffset)); @@ -103,7 +104,7 @@ public KnownTypeSymbols(CSharpCompilation compilation) // Used for type equivalency checks for unbound generics. The parameters of the types // retured by the Roslyn Get*Type* APIs are not unbound, so we construct unbound // generics to equal those corresponding to generic types in the input type graphs. - GenericICollection_Unbound = GenericICollection?.ConstructUnboundGenericType(); + GenericICollection_Unbound = GenericICollection.ConstructUnboundGenericType(); GenericIDictionary_Unbound = GenericIDictionary?.ConstructUnboundGenericType(); GenericIEnumerable_Unbound = compilation.GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T).ConstructUnboundGenericType(); GenericIList_Unbound = compilation.GetSpecialType(SpecialType.System_Collections_Generic_IList_T).ConstructUnboundGenericType(); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsBuilderConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsBuilderConfigurationExtensions.cs index 9cf59a120e1fdc..eb0ab086bcd588 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsBuilderConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsBuilderConfigurationExtensions.cs @@ -10,7 +10,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { public sealed partial class ConfigurationBindingGenerator { - private sealed partial class Parser + internal sealed partial class Parser { private void ParseInvocation_OptionsBuilderExt(BinderInvocation invocation) { @@ -29,22 +29,17 @@ private void ParseInvocation_OptionsBuilderExt(BinderInvocation invocation) // This would violate generic type constraint; any such invocation could not have been included in the initial parser. Debug.Assert(typeSymbol?.IsValueType is not true); - if (GetTargetTypeForRootInvocation(typeSymbol, invocation.Location) is not ComplexTypeSpec typeSpec) - { - return; - } - if (targetMethod.Name is "Bind") { - ParseBindInvocation_OptionsBuilderExt(invocation, typeSpec); + ParseBindInvocation_OptionsBuilderExt(invocation, typeSymbol); } else if (targetMethod.Name is "BindConfiguration") { - ParseBindConfigurationInvocation(invocation, typeSpec); + ParseBindConfigurationInvocation(invocation, typeSymbol); } } - private void ParseBindInvocation_OptionsBuilderExt(BinderInvocation invocation, ComplexTypeSpec typeSpec) + private void ParseBindInvocation_OptionsBuilderExt(BinderInvocation invocation, ITypeSymbol? type) { IInvocationOperation operation = invocation.Operation!; IMethodSymbol targetMethod = operation.TargetMethod; @@ -58,22 +53,21 @@ private void ParseBindInvocation_OptionsBuilderExt(BinderInvocation invocation, return; } - MethodsToGen_Extensions_OptionsBuilder overload = paramCount switch + MethodsToGen overload = paramCount switch { - 2 => MethodsToGen_Extensions_OptionsBuilder.Bind_T, + 2 => MethodsToGen.OptionsBuilderExt_Bind_T, 3 when SymbolEqualityComparer.Default.Equals(_typeSymbols.ActionOfBinderOptions, @params[2].Type) => - MethodsToGen_Extensions_OptionsBuilder.Bind_T_BinderOptions, - _ => MethodsToGen_Extensions_OptionsBuilder.None + MethodsToGen.OptionsBuilderExt_Bind_T_BinderOptions, + _ => MethodsToGen.None }; - if (overload is not MethodsToGen_Extensions_OptionsBuilder.None && - TryRegisterTypeForMethodGen(MethodsToGen_Extensions_ServiceCollection.Configure_T_name_BinderOptions, typeSpec)) + if (overload is not MethodsToGen.None) { - RegisterInvocation(overload, operation); + EnqueueTargetTypeForRootInvocation(type, overload, invocation); } } - private void ParseBindConfigurationInvocation(BinderInvocation invocation, ComplexTypeSpec typeSpec) + private void ParseBindConfigurationInvocation(BinderInvocation invocation, ITypeSymbol? type) { IMethodSymbol targetMethod = invocation.Operation.TargetMethod; ImmutableArray @params = targetMethod.Parameters; @@ -83,23 +77,41 @@ private void ParseBindConfigurationInvocation(BinderInvocation invocation, Compl if (paramCount is 3 && @params[1].Type.SpecialType is SpecialType.System_String && - SymbolEqualityComparer.Default.Equals(_typeSymbols.ActionOfBinderOptions, @params[2].Type) && - TryRegisterTypeForBindCoreMainGen(typeSpec)) + SymbolEqualityComparer.Default.Equals(_typeSymbols.ActionOfBinderOptions, @params[2].Type)) { - RegisterInvocation(MethodsToGen_Extensions_OptionsBuilder.BindConfiguration_T_path_BinderOptions, invocation.Operation); + EnqueueTargetTypeForRootInvocation(type, MethodsToGen.OptionsBuilderExt_BindConfiguration_T_path_BinderOptions, invocation); } } - private void RegisterInvocation(MethodsToGen_Extensions_OptionsBuilder overload, IInvocationOperation operation) + private void RegisterInterceptor_OptionsBuilderExt(TypeParseInfo typeParseInfo, TypeSpec typeSpec) { - _sourceGenSpec.MethodsToGen_OptionsBuilderExt |= overload; - RegisterInterceptor(overload, operation); + MethodsToGen overload = typeParseInfo.BindingOverload; + Debug.Assert((MethodsToGen.OptionsBuilderExt_Any & overload) is not 0); + + if (typeSpec is not ComplexTypeSpec complexTypeSpec) + { + return; + } + + if ((MethodsToGen.OptionsBuilderExt_Bind & overload) is not 0) + { + if (!TryRegisterTypeForOverloadGen_ServiceCollectionExt(MethodsToGen.ServiceCollectionExt_Configure_T_name_BinderOptions, complexTypeSpec)) + { + return; + } + } + else if (!_helperInfoBuilder!.TryRegisterTypeForBindCoreMainGen(complexTypeSpec)) + { + return; + } + + _interceptorInfoBuilder.RegisterInterceptor(typeParseInfo.BindingOverload, typeParseInfo.BinderInvocation.Operation); // Emitting refs to IOptionsChangeTokenSource, ConfigurationChangeTokenSource. - _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.Options"); + _helperInfoBuilder!.RegisterNamespace("Microsoft.Extensions.Options"); // Emitting refs to OptionsBuilder. - _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.DependencyInjection"); + _helperInfoBuilder!.RegisterNamespace("Microsoft.Extensions.DependencyInjection"); } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsConfigurationServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsConfigurationServiceCollectionExtensions.cs index e86231f32e42ab..1ccef24bc6b71f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsConfigurationServiceCollectionExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/OptionsConfigurationServiceCollectionExtensions.cs @@ -10,7 +10,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { public sealed partial class ConfigurationBindingGenerator { - private sealed partial class Parser + internal sealed partial class Parser { private void ParseInvocation_ServiceCollectionExt(BinderInvocation invocation) { @@ -30,11 +30,11 @@ private void ParseInvocation_ServiceCollectionExt(BinderInvocation invocation) return; } - MethodsToGen_Extensions_ServiceCollection overload; + MethodsToGen overload; if (paramCount is 2 && SymbolEqualityComparer.Default.Equals(_typeSymbols.IConfiguration, @params[1].Type)) { - overload = MethodsToGen_Extensions_ServiceCollection.Configure_T; + overload = MethodsToGen.ServiceCollectionExt_Configure_T; } else if (paramCount is 3) { @@ -44,12 +44,12 @@ private void ParseInvocation_ServiceCollectionExt(BinderInvocation invocation) if (secondParamType.SpecialType is SpecialType.System_String && SymbolEqualityComparer.Default.Equals(_typeSymbols.IConfiguration, thirdParamType)) { - overload = MethodsToGen_Extensions_ServiceCollection.Configure_T_name; + overload = MethodsToGen.ServiceCollectionExt_Configure_T_name; } else if (SymbolEqualityComparer.Default.Equals(_typeSymbols.IConfiguration, secondParamType) && SymbolEqualityComparer.Default.Equals(_typeSymbols.ActionOfBinderOptions, thirdParamType)) { - overload = MethodsToGen_Extensions_ServiceCollection.Configure_T_BinderOptions; + overload = MethodsToGen.ServiceCollectionExt_Configure_T_BinderOptions; } else { @@ -61,7 +61,7 @@ @params[1].Type.SpecialType is SpecialType.System_String && SymbolEqualityComparer.Default.Equals(_typeSymbols.IConfiguration, @params[2].Type) && SymbolEqualityComparer.Default.Equals(_typeSymbols.ActionOfBinderOptions, @params[3].Type)) { - overload = MethodsToGen_Extensions_ServiceCollection.Configure_T_name_BinderOptions; + overload = MethodsToGen.ServiceCollectionExt_Configure_T_name_BinderOptions; } else { @@ -73,25 +73,34 @@ @params[1].Type.SpecialType is SpecialType.System_String && // This would violate generic type constraint; any such invocation could not have been included in the initial parser. Debug.Assert(typeSymbol?.IsValueType is not true); - if (GetTargetTypeForRootInvocation(typeSymbol, invocation.Location) is ComplexTypeSpec typeSpec && - TryRegisterTypeForMethodGen(overload, typeSpec)) + EnqueueTargetTypeForRootInvocation(typeSymbol, overload, invocation); + } + + private void RegisterInterceptor_ServiceCollectionExt(TypeParseInfo typeParseInfo, TypeSpec typeSpec) + { + MethodsToGen overload = typeParseInfo.BindingOverload; + + if (typeSpec is ComplexTypeSpec complexTypeSpec && + TryRegisterTypeForOverloadGen_ServiceCollectionExt(overload, complexTypeSpec)) { - RegisterInterceptor(overload, operation); + _interceptorInfoBuilder.RegisterInterceptor(overload, typeParseInfo.BinderInvocation.Operation); } } - private bool TryRegisterTypeForMethodGen(MethodsToGen_Extensions_ServiceCollection overload, ComplexTypeSpec typeSpec) + private bool TryRegisterTypeForOverloadGen_ServiceCollectionExt(MethodsToGen overload, ComplexTypeSpec typeSpec) { - if (TryRegisterTypeForBindCoreMainGen(typeSpec)) + Debug.Assert((MethodsToGen.ServiceCollectionExt_Any & overload) is not 0); + + if (!_helperInfoBuilder!.TryRegisterTypeForBindCoreMainGen(typeSpec)) { - _sourceGenSpec.MethodsToGen_ServiceCollectionExt |= overload; - _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.DependencyInjection"); - // Emitting refs to IOptionsChangeTokenSource, ConfigurationChangeTokenSource, IConfigureOptions<>, ConfigureNamedOptions<>. - _sourceGenSpec.Namespaces.Add("Microsoft.Extensions.Options"); - return true; + return false; } - return false; + _interceptorInfoBuilder.MethodsToGen |= overload; + _helperInfoBuilder!.RegisterNamespace("Microsoft.Extensions.DependencyInjection"); + // Emitting refs to IOptionsChangeTokenSource, ConfigurationChangeTokenSource, IConfigureOptions<>, ConfigureNamedOptions<>. + _helperInfoBuilder!.RegisterNamespace("Microsoft.Extensions.Options"); + return true; } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/BindingHelperInfo.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/BindingHelperInfo.cs new file mode 100644 index 00000000000000..096c8410717ae7 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/BindingHelperInfo.cs @@ -0,0 +1,237 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using SourceGenerators; + +namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration +{ + public sealed record BindingHelperInfo + { + public required ImmutableEquatableArray Namespaces { get; init; } + public required bool EmitConfigurationKeyCaches { get; init; } + + public required MethodsToGen_CoreBindingHelper MethodsToGen { get; init; } + public required ImmutableEquatableArray? TypesForGen_BindCoreMain { get; init; } + public required ImmutableEquatableArray? TypesForGen_GetCore { get; init; } + public required ImmutableEquatableArray? TypesForGen_GetValueCore { get; init; } + public required ImmutableEquatableArray? TypesForGen_BindCore { get; init; } + public required ImmutableEquatableArray? TypesForGen_Initialize { get; init; } + public required ImmutableEquatableArray? TypesForGen_ParsePrimitive { get; init; } + + internal sealed class Builder(TypeIndex _typeIndex) + { + private readonly Dictionary _seenTransitiveTypes = new(); + + private MethodsToGen_CoreBindingHelper _methodsToGen; + private bool _emitConfigurationKeyCaches; + + private readonly Dictionary> _typesForGen = new(); + + private readonly SortedSet _namespaces = new() + { + "System", + "System.CodeDom.Compiler", + "System.Globalization", + "System.Runtime.CompilerServices", + "Microsoft.Extensions.Configuration", + }; + + public BindingHelperInfo ToIncrementalValue() + { + return new BindingHelperInfo + { + Namespaces = _namespaces.ToImmutableEquatableArray(), + EmitConfigurationKeyCaches = _emitConfigurationKeyCaches, + + MethodsToGen = _methodsToGen, + TypesForGen_GetCore = GetTypesForGen_CoreBindingHelper(MethodsToGen_CoreBindingHelper.GetCore), + TypesForGen_BindCoreMain = GetTypesForGen_CoreBindingHelper(MethodsToGen_CoreBindingHelper.BindCoreMain), + TypesForGen_GetValueCore = GetTypesForGen_CoreBindingHelper(MethodsToGen_CoreBindingHelper.GetValueCore), + TypesForGen_BindCore = GetTypesForGen_CoreBindingHelper(MethodsToGen_CoreBindingHelper.BindCore), + TypesForGen_Initialize = GetTypesForGen_CoreBindingHelper(MethodsToGen_CoreBindingHelper.Initialize), + TypesForGen_ParsePrimitive = GetTypesForGen_CoreBindingHelper(MethodsToGen_CoreBindingHelper.ParsePrimitive) + }; + + ImmutableEquatableArray? GetTypesForGen_CoreBindingHelper(MethodsToGen_CoreBindingHelper overload) + where TSpec : TypeSpec, IEquatable + { + _typesForGen.TryGetValue(overload, out HashSet? typesAsBase); + + if (typesAsBase is null) + { + return null; + } + + IEnumerable types = typeof(TSpec) == typeof(TypeSpec) + ? (HashSet)(object)typesAsBase + : typesAsBase.Select(t => (TSpec)t); + + return GetTypesForGen(types); + } + + static ImmutableEquatableArray GetTypesForGen(IEnumerable types) + where TSpec : TypeSpec, IEquatable => + types.ToImmutableEquatableArray(); + } + + public bool TryRegisterTypeForGetGen(TypeSpec type) + { + if (TryRegisterTransitiveTypesForMethodGen(type.TypeRef)) + { + RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.GetCore, type); + RegisterForGen_AsConfigWithChildrenHelper(); + return true; + } + + return false; + } + + public bool TryRegisterTypeForGetValueGen(TypeSpec typeSpec) + { + ParsableFromStringSpec effectiveType = (ParsableFromStringSpec)_typeIndex.GetEffectiveTypeSpec(typeSpec); + RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.GetValueCore, typeSpec); + RegisterStringParsableTypeIfApplicable(effectiveType); + return true; + } + + public bool TryRegisterTypeForBindCoreMainGen(ComplexTypeSpec type) + { + if (TryRegisterTransitiveTypesForMethodGen(type.TypeRef)) + { + RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.BindCoreMain, type); + RegisterForGen_AsConfigWithChildrenHelper(); + return true; + } + + return false; + } + + public bool TryRegisterTransitiveTypesForMethodGen(TypeRef typeRef) + { + return _seenTransitiveTypes.TryGetValue(typeRef, out bool isValid) + ? isValid + : (_seenTransitiveTypes[typeRef] = TryRegisterCore()); + + bool TryRegisterCore() + { + switch (_typeIndex.GetTypeSpec(typeRef)) + { + case NullableSpec nullableSpec: + { + return TryRegisterTransitiveTypesForMethodGen(nullableSpec.EffectiveTypeRef); + } + case ParsableFromStringSpec stringParsableSpec: + { + RegisterStringParsableTypeIfApplicable(stringParsableSpec); + return true; + } + case DictionarySpec dictionarySpec: + { + bool shouldRegister = _typeIndex.CanBindTo(typeRef) && + TryRegisterTransitiveTypesForMethodGen(dictionarySpec.KeyTypeRef) && + TryRegisterTransitiveTypesForMethodGen(dictionarySpec.ElementTypeRef) && + TryRegisterTypeForBindCoreGen(dictionarySpec); + + if (shouldRegister && dictionarySpec.InstantiationStrategy is CollectionInstantiationStrategy.LinqToDictionary) + { + _namespaces.Add("System.Linq"); + } + + return shouldRegister; + } + case CollectionSpec collectionSpec: + { + return TryRegisterTransitiveTypesForMethodGen(collectionSpec.ElementTypeRef) && + TryRegisterTypeForBindCoreGen(collectionSpec); + } + case ObjectSpec objectSpec: + { + // Base case to avoid stack overflow for recursive object graphs. + // Register all object types for gen; we need to throw runtime exceptions in some cases. + bool shouldRegister = true; + _seenTransitiveTypes.Add(typeRef, shouldRegister); + + // List is used in generated code as a temp holder for formatting + // an error for config properties that don't map to object properties. + _namespaces.Add("System.Collections.Generic"); + + if (_typeIndex.HasBindableMembers(objectSpec)) + { + foreach (PropertySpec property in objectSpec.Properties!) + { + TryRegisterTransitiveTypesForMethodGen(property.TypeRef); + + if (_typeIndex.GetTypeSpec(property.TypeRef) is ComplexTypeSpec) + { + RegisterForGen_AsConfigWithChildrenHelper(); + } + } + + bool registeredForBindCore = TryRegisterTypeForBindCoreGen(objectSpec); + Debug.Assert(registeredForBindCore); + + if (objectSpec is { InstantiationStrategy: ObjectInstantiationStrategy.ParameterizedConstructor, InitExceptionMessage: null }) + { + RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.Initialize, objectSpec); + } + } + + return true; + } + default: + { + return true; + } + } + } + } + + public void RegisterNamespace(string @namespace) => _namespaces.Add(@namespace); + + private bool TryRegisterTypeForBindCoreGen(ComplexTypeSpec type) + { + if (_typeIndex.HasBindableMembers(type)) + { + RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.BindCore, type); + _emitConfigurationKeyCaches = true; + return true; + } + + return false; + } + + private void RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper method, TypeSpec type) + { + if (!_typesForGen.TryGetValue(method, out HashSet? types)) + { + _typesForGen[method] = types = new HashSet(); + } + + if (types.Add(type)) + { + _methodsToGen |= method; + + if (type is { Namespace: string @namespace }) + { + _namespaces.Add(@namespace); + } + } + } + + private void RegisterStringParsableTypeIfApplicable(ParsableFromStringSpec type) + { + if (type.StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue) + { + _methodsToGen |= MethodsToGen_CoreBindingHelper.ParsePrimitive; + RegisterTypeForMethodGen(MethodsToGen_CoreBindingHelper.ParsePrimitive, type); + } + } + + private void RegisterForGen_AsConfigWithChildrenHelper() => _methodsToGen |= MethodsToGen_CoreBindingHelper.AsConfigWithChildren; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/InterceptorInfo.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/InterceptorInfo.cs new file mode 100644 index 00000000000000..999ed6514f99d7 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/InterceptorInfo.cs @@ -0,0 +1,202 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Operations; +using Microsoft.CodeAnalysis.Text; +using SourceGenerators; + +namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration +{ + public sealed record InterceptorInfo + { + public required MethodsToGen MethodsToGen { get; init; } + + public required ImmutableEquatableArray? ConfigBinder_Bind_instance { get; init; } + public required ImmutableEquatableArray? ConfigBinder_Bind_instance_BinderOptions { get; init; } + public required ImmutableEquatableArray? ConfigBinder_Bind_key_instance { get; init; } + + + public required ImmutableEquatableArray? ConfigBinder { get; init; } + public required ImmutableEquatableArray? OptionsBuilderExt { get; init; } + public required ImmutableEquatableArray? ServiceCollectionExt { get; init; } + + public IEnumerable? GetInfo(MethodsToGen interceptor) + { + Debug.Assert((MethodsToGen.ConfigBinder_Bind & interceptor) is 0); + + ImmutableEquatableArray? infoList; + if ((MethodsToGen.ConfigBinder_Any ^ MethodsToGen.ConfigBinder_Bind & interceptor) is not 0) + { + infoList = ConfigBinder; + } + else if ((MethodsToGen.OptionsBuilderExt_Any & interceptor) is not 0) + { + infoList = OptionsBuilderExt; + } + else + { + Debug.Assert((MethodsToGen.ServiceCollectionExt_Any & interceptor) is not 0); + infoList = ServiceCollectionExt; + } + + return infoList?.Where(i => i.Interceptor == interceptor); + } + + internal sealed class Builder + { + private TypedInterceptorInfoBuildler? _configBinder_InfoBuilder_Bind_instance; + private TypedInterceptorInfoBuildler? _configBinder_InfoBuilder_Bind_instance_BinderOptions; + private TypedInterceptorInfoBuildler? _configBinder_InfoBuilder_Bind_key_instance; + + private List? _interceptors_configBinder; + private List? _interceptors_OptionsBuilderExt; + private List? _interceptors_serviceCollectionExt; + + public MethodsToGen MethodsToGen { get; set; } + + public void RegisterInterceptor_ConfigBinder_Bind(MethodsToGen overload, ComplexTypeSpec type, IInvocationOperation invocation) + { + Debug.Assert((MethodsToGen.ConfigBinder_Bind & overload) is not 0); + + switch (overload) + { + case MethodsToGen.ConfigBinder_Bind_instance: + RegisterInterceptor(ref _configBinder_InfoBuilder_Bind_instance); + break; + case MethodsToGen.ConfigBinder_Bind_instance_BinderOptions: + RegisterInterceptor(ref _configBinder_InfoBuilder_Bind_instance_BinderOptions); + break; + case MethodsToGen.ConfigBinder_Bind_key_instance: + RegisterInterceptor(ref _configBinder_InfoBuilder_Bind_key_instance); + break; + } + + MethodsToGen |= overload; + + void RegisterInterceptor(ref TypedInterceptorInfoBuildler? infoBuilder) + { + infoBuilder ??= new TypedInterceptorInfoBuildler(); + infoBuilder.RegisterInterceptor(overload, type, invocation); + } + } + + public void RegisterInterceptor(MethodsToGen overload, IInvocationOperation operation) + { + Debug.Assert((MethodsToGen.ConfigBinder_Bind & overload) is 0); + + if ((MethodsToGen.ConfigBinder_Any ^ MethodsToGen.ConfigBinder_Bind & overload) is not 0) + { + RegisterInterceptor(ref _interceptors_configBinder); + } + else if ((MethodsToGen.OptionsBuilderExt_Any & overload) is not 0) + { + RegisterInterceptor(ref _interceptors_OptionsBuilderExt); + } + else + { + Debug.Assert((MethodsToGen.ServiceCollectionExt_Any & overload) is not 0); + RegisterInterceptor(ref _interceptors_serviceCollectionExt); + } + + MethodsToGen |= overload; + + void RegisterInterceptor(ref List? infoList) + { + infoList ??= new List(); + infoList.Add(new InvocationLocationInfo(overload, operation)); + } + } + + public InterceptorInfo ToIncrementalValue() => + new InterceptorInfo + { + MethodsToGen = MethodsToGen, + + ConfigBinder = _interceptors_configBinder?.ToImmutableEquatableArray(), + OptionsBuilderExt = _interceptors_OptionsBuilderExt?.ToImmutableEquatableArray(), + ServiceCollectionExt = _interceptors_serviceCollectionExt?.ToImmutableEquatableArray(), + + ConfigBinder_Bind_instance = _configBinder_InfoBuilder_Bind_instance?.ToIncrementalValue(), + ConfigBinder_Bind_instance_BinderOptions = _configBinder_InfoBuilder_Bind_instance_BinderOptions?.ToIncrementalValue(), + ConfigBinder_Bind_key_instance = _configBinder_InfoBuilder_Bind_key_instance?.ToIncrementalValue(), + }; + } + } + + internal sealed class TypedInterceptorInfoBuildler + { + private readonly Dictionary _invocationInfoBuilderCache = new(); + + public void RegisterInterceptor(MethodsToGen overload, ComplexTypeSpec type, IInvocationOperation invocation) + { + if (!_invocationInfoBuilderCache.TryGetValue(type, out TypedInterceptorInvocationInfo.Builder? invocationInfoBuilder)) + { + _invocationInfoBuilderCache[type] = invocationInfoBuilder = new TypedInterceptorInvocationInfo.Builder(overload, type); + } + + invocationInfoBuilder.RegisterInvocation(invocation); + } + + public ImmutableEquatableArray? ToIncrementalValue() => + _invocationInfoBuilderCache.Values + .Select(b => b.ToIncrementalValue()) + .ToImmutableEquatableArray(); + } + + public sealed record TypedInterceptorInvocationInfo(ComplexTypeSpec TargetType, ImmutableEquatableArray Locations) + { + public sealed class Builder(MethodsToGen Overload, ComplexTypeSpec TargetType) + { + private readonly List _infoList = new(); + + public void RegisterInvocation(IInvocationOperation invocation) => + _infoList.Add(new InvocationLocationInfo(Overload, invocation)); + + public TypedInterceptorInvocationInfo ToIncrementalValue() => new( + TargetType, + Locations: _infoList.ToImmutableEquatableArray()); + } + } + + public sealed record InvocationLocationInfo + { + public InvocationLocationInfo(MethodsToGen interceptor, IInvocationOperation invocation) + { + Debug.Assert(BinderInvocation.IsBindingOperation(invocation)); + + if (invocation.Syntax is not InvocationExpressionSyntax { Expression: MemberAccessExpressionSyntax memberAccessExprSyntax }) + { + const string InvalidInvocationErrMsg = "The invocation should have been validated upstream when selecting invocations to emit interceptors for."; + throw new ArgumentException(InvalidInvocationErrMsg, nameof(invocation)); + } + + SyntaxTree operationSyntaxTree = invocation.Syntax.SyntaxTree; + TextSpan memberNameSpan = memberAccessExprSyntax.Name.Span; + FileLinePositionSpan linePosSpan = operationSyntaxTree.GetLineSpan(memberNameSpan); + + Interceptor = interceptor; + LineNumber = linePosSpan.StartLinePosition.Line + 1; + CharacterNumber = linePosSpan.StartLinePosition.Character + 1; + FilePath = GetInterceptorFilePath(); + + // Use the same logic used by the interceptors API for resolving the source mapped value of a path. + // https://github.com/dotnet/roslyn/blob/f290437fcc75dad50a38c09e0977cce13a64f5ba/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs#L1063-L1064 + string GetInterceptorFilePath() + { + SourceReferenceResolver? sourceReferenceResolver = invocation.SemanticModel?.Compilation.Options.SourceReferenceResolver; + return sourceReferenceResolver?.NormalizePath(operationSyntaxTree.FilePath, baseFilePath: null) ?? operationSyntaxTree.FilePath; + } + } + + public MethodsToGen Interceptor { get; } + public string FilePath { get; } + public int LineNumber { get; } + public int CharacterNumber { get; } + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/InterceptorLocationInfo.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/InterceptorLocationInfo.cs deleted file mode 100644 index 441acbe6a7444f..00000000000000 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/InterceptorLocationInfo.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections; -using System.Collections.Generic; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Operations; -using Microsoft.CodeAnalysis.Text; - -namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration -{ - internal sealed record InterceptorLocationInfo - { - public InterceptorLocationInfo(IInvocationOperation operation) - { - MemberAccessExpressionSyntax memberAccessExprSyntax = ((MemberAccessExpressionSyntax)((InvocationExpressionSyntax)operation.Syntax).Expression); - SyntaxTree operationSyntaxTree = operation.Syntax.SyntaxTree; - TextSpan memberNameSpan = memberAccessExprSyntax.Name.Span; - FileLinePositionSpan linePosSpan = operationSyntaxTree.GetLineSpan(memberNameSpan); - - LineNumber = linePosSpan.StartLinePosition.Line + 1; - CharacterNumber = linePosSpan.StartLinePosition.Character + 1; - FilePath = GetInterceptorFilePath(); - - // Use the same logic used by the interceptors API for resolving the source mapped value of a path. - // https://github.com/dotnet/roslyn/blob/f290437fcc75dad50a38c09e0977cce13a64f5ba/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs#L1063-L1064 - string GetInterceptorFilePath() - { - SourceReferenceResolver? sourceReferenceResolver = operation.SemanticModel?.Compilation.Options.SourceReferenceResolver; - return sourceReferenceResolver?.NormalizePath(operationSyntaxTree.FilePath, baseFilePath: null) ?? operationSyntaxTree.FilePath; - } - } - - public string FilePath { get; } - public int LineNumber { get; } - public int CharacterNumber { get; } - } - - internal sealed record ConfigurationBinderInterceptorInfo - { - private OverloadInterceptorInfo? _bind_Instance; - private OverloadInterceptorInfo? _bind_instance_BinderOptions; - private OverloadInterceptorInfo? _bind_key_instance; - - public void RegisterOverloadInfo(MethodsToGen_ConfigurationBinder overload, TypeSpec type, IInvocationOperation operation) - { - OverloadInterceptorInfo overloadInfo = DetermineOverload(overload, initIfNull: true); - overloadInfo.RegisterLocationInfo(type, operation); - } - - public OverloadInterceptorInfo GetOverloadInfo(MethodsToGen_ConfigurationBinder overload) => - DetermineOverload(overload, initIfNull: false) ?? throw new ArgumentOutOfRangeException(nameof(overload)); - - private OverloadInterceptorInfo? DetermineOverload(MethodsToGen_ConfigurationBinder overload, bool initIfNull) - { - return overload switch - { - MethodsToGen_ConfigurationBinder.Bind_instance => InitIfNull(ref _bind_Instance), - MethodsToGen_ConfigurationBinder.Bind_instance_BinderOptions => InitIfNull(ref _bind_instance_BinderOptions), - MethodsToGen_ConfigurationBinder.Bind_key_instance => InitIfNull(ref _bind_key_instance), - _ => throw new InvalidOperationException(nameof(overload)), - }; - - OverloadInterceptorInfo InitIfNull(ref OverloadInterceptorInfo? info) - { - if (initIfNull) - { - info ??= new OverloadInterceptorInfo(); - } - - return info; - } - } - } - - internal sealed record OverloadInterceptorInfo : IEnumerable>> - { - private readonly Dictionary> _typeInterceptionInfo = new(); - - public void RegisterLocationInfo(TypeSpec type, IInvocationOperation operation) => - _typeInterceptionInfo.RegisterCacheEntry(type, new InterceptorLocationInfo(operation)); - - public IEnumerator>> GetEnumerator() => _typeInterceptionInfo.GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - } -} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/MemberSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/MemberSpec.cs index effd550482595d..dc5b03087ac87a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/MemberSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/MemberSpec.cs @@ -3,10 +3,11 @@ using System.Diagnostics; using Microsoft.CodeAnalysis; +using SourceGenerators; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { - internal abstract record MemberSpec + public abstract record MemberSpec { public MemberSpec(ISymbol member) { @@ -18,7 +19,7 @@ public MemberSpec(ISymbol member) public string Name { get; } public string DefaultValueExpr { get; protected set; } - public required TypeSpec Type { get; init; } + public required TypeRef TypeRef { get; init; } public required string ConfigurationKeyName { get; init; } public abstract bool CanGet { get; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/ParameterSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/ParameterSpec.cs index 0f17a6247f74d2..62c781e1f1631f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/ParameterSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/ParameterSpec.cs @@ -6,7 +6,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { - internal sealed record ParameterSpec : MemberSpec + public sealed record ParameterSpec : MemberSpec { public ParameterSpec(IParameterSymbol parameter) : base(parameter) { @@ -14,7 +14,7 @@ public ParameterSpec(IParameterSymbol parameter) : base(parameter) if (parameter.HasExplicitDefaultValue) { - string formatted = SymbolDisplay.FormatPrimitive(parameter.ExplicitDefaultValue, quoteStrings: true, useHexadecimalNumbers: false); + string formatted = SymbolDisplay.FormatPrimitive(parameter.ExplicitDefaultValue!, quoteStrings: true, useHexadecimalNumbers: false); if (formatted is not "null") { DefaultValueExpr = formatted; diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/PropertySpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/PropertySpec.cs index 4e9c468c4e3352..443e39d32e4933 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/PropertySpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/PropertySpec.cs @@ -5,7 +5,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { - internal sealed record PropertySpec : MemberSpec + public sealed record PropertySpec : MemberSpec { public PropertySpec(IPropertySymbol property) : base(property) { @@ -28,7 +28,5 @@ public PropertySpec(IPropertySymbol property) : base(property) public override bool CanGet { get; } public override bool CanSet { get; } - - public bool ShouldBindTo => CanGet || CanSet; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/MethodsToGen.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/MethodsToGen.cs index 6165a3e6d46dcb..af2a33fa6c2f80 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/MethodsToGen.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/MethodsToGen.cs @@ -16,137 +16,130 @@ public enum MethodsToGen_CoreBindingHelper Initialize = 0x10, HasValueOrChildren = 0x20, AsConfigWithChildren = 0x40, + ParsePrimitive = 0x80, } /// /// Methods on Microsoft.Extensions.Configuration.ConfigurationBinder /// [Flags] - internal enum MethodsToGen_ConfigurationBinder + public enum MethodsToGen { None = 0x0, + Any = ConfigBinder_Any | OptionsBuilderExt_Any | ServiceCollectionExt_Any, + #region IConfiguration ext. method overloads: 0x1 - 0x400 /// /// Bind(IConfiguration, object?). /// - Bind_instance = 0x1, + ConfigBinder_Bind_instance = 0x1, /// /// Bind(IConfiguration, object?, Action?). /// - Bind_instance_BinderOptions = 0x2, + ConfigBinder_Bind_instance_BinderOptions = 0x2, /// /// Bind(IConfiguration, string, object?). /// - Bind_key_instance = 0x4, + ConfigBinder_Bind_key_instance = 0x4, /// /// Get(IConfiguration). /// - Get_T = 0x8, + ConfigBinder_Get_T = 0x8, /// /// Get(IConfiguration, Action?). /// - Get_T_BinderOptions = 0x10, + ConfigBinder_Get_T_BinderOptions = 0x10, /// /// Get(IConfiguration, Type). /// - Get_TypeOf = 0x20, + ConfigBinder_Get_TypeOf = 0x20, /// /// Get(IConfiguration, Type, Action?). /// - Get_TypeOf_BinderOptions = 0x40, + ConfigBinder_Get_TypeOf_BinderOptions = 0x40, /// /// GetValue(IConfiguration, Type, string). /// - GetValue_TypeOf_key = 0x80, + ConfigBinder_GetValue_TypeOf_key = 0x80, /// /// GetValue(IConfiguration, Type, object?). /// - GetValue_TypeOf_key_defaultValue = 0x100, + ConfigBinder_GetValue_TypeOf_key_defaultValue = 0x100, /// /// GetValue(IConfiguration, string). /// - GetValue_T_key = 0x200, + ConfigBinder_GetValue_T_key = 0x200, /// /// GetValue(IConfiguration, string, T). /// - GetValue_T_key_defaultValue = 0x400, + ConfigBinder_GetValue_T_key_defaultValue = 0x400, // Method groups - Bind = Bind_instance | Bind_instance_BinderOptions | Bind_key_instance, - Get = Get_T | Get_T_BinderOptions | Get_TypeOf | Get_TypeOf_BinderOptions, - GetValue = GetValue_T_key | GetValue_T_key_defaultValue | GetValue_TypeOf_key | GetValue_TypeOf_key_defaultValue, + ConfigBinder_Bind = ConfigBinder_Bind_instance | ConfigBinder_Bind_instance_BinderOptions | ConfigBinder_Bind_key_instance, + ConfigBinder_Get = ConfigBinder_Get_T | ConfigBinder_Get_T_BinderOptions | ConfigBinder_Get_TypeOf | ConfigBinder_Get_TypeOf_BinderOptions, + ConfigBinder_GetValue = ConfigBinder_GetValue_T_key | ConfigBinder_GetValue_T_key_defaultValue | ConfigBinder_GetValue_TypeOf_key | ConfigBinder_GetValue_TypeOf_key_defaultValue, - Any = Bind | Get | GetValue, - } - - [Flags] - internal enum MethodsToGen_Extensions_OptionsBuilder - { - None = 0x0, + ConfigBinder_Any = ConfigBinder_Bind | ConfigBinder_Get | ConfigBinder_GetValue, + #endregion ConfigurationBinder ext. method overloads. + #region OptionsBuilder ext. method overloads: 0x800 - 0x2000 /// /// Bind(OptionsBuilder, IConfiguration). /// - Bind_T = 0x1, + OptionsBuilderExt_Bind_T = 0x800, /// /// Bind(OptionsBuilder, IConfiguration, Action?). /// - Bind_T_BinderOptions = 0x2, + OptionsBuilderExt_Bind_T_BinderOptions = 0x1000, /// /// BindConfiguration(OptionsBuilder, string, Action?). /// - BindConfiguration_T_path_BinderOptions = 0x4, + OptionsBuilderExt_BindConfiguration_T_path_BinderOptions = 0x2000, // Method group. BindConfiguration_T is its own method group. - Bind = Bind_T | Bind_T_BinderOptions, - - BindConfiguration = BindConfiguration_T_path_BinderOptions, + OptionsBuilderExt_Bind = OptionsBuilderExt_Bind_T | OptionsBuilderExt_Bind_T_BinderOptions, - Any = Bind | BindConfiguration, - } + OptionsBuilderExt_BindConfiguration = OptionsBuilderExt_BindConfiguration_T_path_BinderOptions, - /// - /// Methods on Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions - /// - [Flags] - public enum MethodsToGen_Extensions_ServiceCollection - { - None = 0x0, + OptionsBuilderExt_Any = OptionsBuilderExt_Bind | OptionsBuilderExt_BindConfiguration, + #endregion OptionsBuilder ext. method overloads. + #region IServiceCollection ext. method overloads: 0x4000 - 0x20000 /// /// Configure(IServiceCollection, IConfiguration). /// - Configure_T = 0x1, + ServiceCollectionExt_Configure_T = 0x4000, /// /// Configure(IServiceCollection, string, IConfiguration). /// - Configure_T_name = 0x2, + ServiceCollectionExt_Configure_T_name = 0x8000, /// /// Configure(IServiceCollection, IConfiguration, Action?). /// - Configure_T_BinderOptions = 0x4, + ServiceCollectionExt_Configure_T_BinderOptions = 0x10000, /// /// Configure(IServiceCollection, string, IConfiguration, Action?). /// - Configure_T_name_BinderOptions = 0x8, + ServiceCollectionExt_Configure_T_name_BinderOptions = 0x20000, - Configure = Configure_T | Configure_T_name | Configure_T_BinderOptions | Configure_T_name_BinderOptions, + ServiceCollectionExt_Configure = ServiceCollectionExt_Configure_T | ServiceCollectionExt_Configure_T_name | ServiceCollectionExt_Configure_T_BinderOptions | ServiceCollectionExt_Configure_T_name_BinderOptions, - Any = Configure, + ServiceCollectionExt_Any = ServiceCollectionExt_Configure, + #endregion IServiceCollection ext. method overloads: 0x4000 - 0x20000 } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/SourceGenerationSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/SourceGenerationSpec.cs index 760d57b1dcc888..4f57316429e2b1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/SourceGenerationSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/SourceGenerationSpec.cs @@ -1,31 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; +using SourceGenerators; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { - internal sealed record SourceGenerationSpec + public sealed record SourceGenerationSpec { - public Dictionary> InterceptionInfo { get; } = new(); - public ConfigurationBinderInterceptorInfo InterceptionInfo_ConfigBinder { get; } = new(); - - public Dictionary> TypesForGen_CoreBindingHelper_Methods { get; } = new(); - - public HashSet PrimitivesForHelperGen { get; } = new(); - public HashSet Namespaces { get; } = new() - { - "System", - "System.CodeDom.Compiler", - "System.Globalization", - "System.Runtime.CompilerServices", - "Microsoft.Extensions.Configuration", - }; - - public MethodsToGen_CoreBindingHelper MethodsToGen_CoreBindingHelper { get; set; } - public MethodsToGen_ConfigurationBinder MethodsToGen_ConfigurationBinder { get; set; } - public MethodsToGen_Extensions_OptionsBuilder MethodsToGen_OptionsBuilderExt { get; set; } - public MethodsToGen_Extensions_ServiceCollection MethodsToGen_ServiceCollectionExt { get; set; } + public required InterceptorInfo InterceptorInfo { get; init; } + public required BindingHelperInfo BindingHelperInfo { get; init; } + public required ImmutableEquatableArray ConfigTypes { get; init; } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/TypeIndex.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/TypeIndex.cs new file mode 100644 index 00000000000000..5b59577b392921 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/TypeIndex.cs @@ -0,0 +1,122 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using SourceGenerators; + +namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration +{ + internal sealed class TypeIndex(IEnumerable typeSpecs) + { + private readonly Dictionary _index = typeSpecs.ToDictionary(spec => spec.TypeRef); + + public bool CanBindTo(TypeRef typeRef) => GetEffectiveTypeSpec(typeRef) switch + { + SimpleTypeSpec => true, + ComplexTypeSpec complexTypeSpec => CanInstantiate(complexTypeSpec) || HasBindableMembers(complexTypeSpec), + _ => throw new InvalidOperationException(), + }; + + public bool CanInstantiate(ComplexTypeSpec typeSpec) => typeSpec switch + { + ObjectSpec objectSpec => objectSpec is { InstantiationStrategy: not ObjectInstantiationStrategy.None, InitExceptionMessage: null }, + DictionarySpec dictionarySpec => KeyIsSupported(dictionarySpec), + CollectionSpec collectionSpec => CanBindTo(collectionSpec.ElementTypeRef), + _ => throw new InvalidOperationException(), + }; + + public bool HasBindableMembers(ComplexTypeSpec typeSpec) => + typeSpec switch + { + ObjectSpec objectSpec => objectSpec.Properties?.Any(ShouldBindTo) is true, + DictionarySpec dictSpec => KeyIsSupported(dictSpec) && CanBindTo(dictSpec.ElementTypeRef), + CollectionSpec collectionSpec => CanBindTo(collectionSpec.ElementTypeRef), + _ => throw new InvalidOperationException(), + }; + + public bool ShouldBindTo(PropertySpec property) + { + TypeSpec propTypeSpec = GetEffectiveTypeSpec(property.TypeRef); + return IsAccessible() && !IsCollectionAndCannotOverride() && !IsDictWithUnsupportedKey(); + + bool IsAccessible() => property.CanGet || property.CanSet; + + bool IsDictWithUnsupportedKey() => propTypeSpec is DictionarySpec dictionarySpec && !KeyIsSupported(dictionarySpec); + + bool IsCollectionAndCannotOverride() => !property.CanSet && + propTypeSpec is CollectionWithCtorInitSpec + { + InstantiationStrategy: CollectionInstantiationStrategy.CopyConstructor or CollectionInstantiationStrategy.LinqToDictionary + }; + } + + public TypeSpec GetEffectiveTypeSpec(TypeRef typeRef) + { + TypeSpec typeSpec = GetTypeSpec(typeRef); + return GetEffectiveTypeSpec(typeSpec); + } + + public TypeSpec GetEffectiveTypeSpec(TypeSpec typeSpec) + { + TypeRef effectiveRef = typeSpec.EffectiveTypeRef; + TypeSpec effectiveSpec = effectiveRef == typeSpec.TypeRef ? typeSpec : _index[effectiveRef]; + return effectiveSpec; + } + + public TypeSpec GetTypeSpec(TypeRef typeRef) => _index[typeRef]; + + public string GetInstantiationTypeDisplayString(CollectionWithCtorInitSpec type) + { + CollectionInstantiationConcreteType concreteType = type.InstantiationConcreteType; + return concreteType is CollectionInstantiationConcreteType.Self + ? type.DisplayString + : GetGenericTypeDisplayString(type, concreteType); + } + + public string GetPopulationCastTypeDisplayString(CollectionWithCtorInitSpec type) + { + CollectionPopulationCastType castType = type.PopulationCastType; + Debug.Assert(castType is not CollectionPopulationCastType.NotApplicable); + return GetGenericTypeDisplayString(type, castType); + } + + public string GetGenericTypeDisplayString(CollectionWithCtorInitSpec type, Enum genericProxyTypeName) + { + string proxyTypeNameStr = genericProxyTypeName.ToString(); + string elementTypeDisplayString = GetTypeSpec(type.ElementTypeRef).DisplayString; + + if (type is EnumerableSpec) + { + return $"{proxyTypeNameStr}<{elementTypeDisplayString}>"; + } + + string keyTypeDisplayString = GetTypeSpec(((DictionarySpec)type).KeyTypeRef).DisplayString; + return $"{proxyTypeNameStr}<{keyTypeDisplayString}, {elementTypeDisplayString}>"; + } + + public bool KeyIsSupported(DictionarySpec typeSpec) => + // Only types that are parsable from string are supported. + // Nullable keys not allowed; that would cause us to emit + // code that violates dictionary key notnull constraint. + GetTypeSpec(typeSpec.KeyTypeRef) is ParsableFromStringSpec; + + public static string GetConfigKeyCacheFieldName(ObjectSpec type) => $"s_configKeys_{type.IdentifierCompatibleSubstring}"; + + public static string GetParseMethodName(ParsableFromStringSpec type) + { + Debug.Assert(type.StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue); + + string displayString = type.DisplayString; + + string parseMethod = type.StringParsableTypeKind is StringParsableTypeKind.ByteArray + ? "ParseByteArray" + // MinimalDisplayString.Length is certainly > 2. + : $"Parse{(char.ToUpper(displayString[0]) + displayString.Substring(1)).Replace(".", "")}"; + + return parseMethod; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/CollectionSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/CollectionSpec.cs index f565d245cc5502..f891328f77af7c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/CollectionSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/CollectionSpec.cs @@ -2,48 +2,67 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.CodeAnalysis; +using SourceGenerators; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { internal abstract record CollectionSpec : ComplexTypeSpec { - public CollectionSpec(ITypeSymbol type) : base(type) { } + protected CollectionSpec(ITypeSymbol type) : base(type) { } - public sealed override bool CanInstantiate => TypeToInstantiate?.CanInstantiate ?? InstantiationStrategy is not InstantiationStrategy.None; + public required TypeRef ElementTypeRef { get; init; } - public required TypeSpec ElementType { get; init; } + } + + internal abstract record CollectionWithCtorInitSpec : CollectionSpec + { + protected CollectionWithCtorInitSpec(ITypeSymbol type) : base(type) { } - public required CollectionPopulationStrategy PopulationStrategy { get; init; } + public required CollectionInstantiationStrategy InstantiationStrategy { get; init; } - public required CollectionSpec? TypeToInstantiate { get; init; } + public required CollectionInstantiationConcreteType InstantiationConcreteType { get; init; } - public required CollectionSpec? PopulationCastType { get; init; } + public required CollectionPopulationCastType PopulationCastType { get; init; } } - internal sealed record EnumerableSpec : CollectionSpec + internal sealed record ArraySpec : CollectionSpec { - public EnumerableSpec(ITypeSymbol type) : base(type) { } - - public override TypeSpecKind SpecKind => TypeSpecKind.Enumerable; + public ArraySpec(ITypeSymbol type) : base(type) { } + } - public override bool HasBindableMembers => PopulationStrategy is not CollectionPopulationStrategy.Unknown && ElementType.CanBindTo; + internal sealed record EnumerableSpec : CollectionWithCtorInitSpec + { + public EnumerableSpec(ITypeSymbol type) : base(type) { } } - internal sealed record DictionarySpec : CollectionSpec + internal sealed record DictionarySpec : CollectionWithCtorInitSpec { public DictionarySpec(INamedTypeSymbol type) : base(type) { } - public override TypeSpecKind SpecKind => TypeSpecKind.Dictionary; + public required TypeRef KeyTypeRef { get; init; } + } - public override bool HasBindableMembers => PopulationStrategy is not CollectionPopulationStrategy.Unknown; + internal enum CollectionInstantiationStrategy + { + NotApplicable = 0, + ParameterlessConstructor = 1, + CopyConstructor = 2, + LinqToDictionary = 3, + } - public required ParsableFromStringSpec KeyType { get; init; } + internal enum CollectionInstantiationConcreteType + { + Self = 0, + Dictionary = 1, + List = 2, + HashSet = 3, } - internal enum CollectionPopulationStrategy + internal enum CollectionPopulationCastType { - Unknown = 0, - Add = 1, - Cast_Then_Add = 2, + NotApplicable = 0, + IDictionary = 1, + ICollection = 2, + ISet = 3, } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ComplexTypeSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ComplexTypeSpec.cs deleted file mode 100644 index da5a5130141a53..00000000000000 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ComplexTypeSpec.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis; - -namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration -{ - internal abstract record ComplexTypeSpec : TypeSpec - { - public ComplexTypeSpec(ITypeSymbol type) : base(type) { } - - public InstantiationStrategy InstantiationStrategy { get; set; } - - public sealed override bool CanBindTo => CanInstantiate || HasBindableMembers; - - public sealed override TypeSpec EffectiveType => this; - - public abstract bool HasBindableMembers { get; } - } - - internal enum InstantiationStrategy - { - None = 0, - ParameterlessConstructor = 1, - ParameterizedConstructor = 2, - ToEnumerableMethod = 3, - Array = 4, - } -} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/NullableSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/NullableSpec.cs deleted file mode 100644 index 3de6d7d465ad98..00000000000000 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/NullableSpec.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.CodeAnalysis; - -namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration -{ - internal sealed record NullableSpec : TypeSpec - { - private readonly TypeSpec _underlyingType; - - public NullableSpec(ITypeSymbol type, TypeSpec underlyingType) : base(type) => _underlyingType = underlyingType; - - public override bool CanBindTo => _underlyingType.CanBindTo; - - public override bool CanInstantiate => _underlyingType.CanInstantiate; - - public override TypeSpecKind SpecKind => TypeSpecKind.Nullable; - - public override TypeSpec EffectiveType => _underlyingType; - } -} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ObjectSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ObjectSpec.cs index f6978fa9cf470a..abc01258d4190c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ObjectSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/ObjectSpec.cs @@ -1,27 +1,39 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; -using System.Linq; using Microsoft.CodeAnalysis; +using SourceGenerators; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { - internal sealed record ObjectSpec : ComplexTypeSpec + public sealed record ObjectSpec : ComplexTypeSpec { - public ObjectSpec(INamedTypeSymbol type) : base(type) { } - - public override TypeSpecKind SpecKind => TypeSpecKind.Object; - - public override bool HasBindableMembers => Properties.Values.Any(p => p.ShouldBindTo); - - public override bool CanInstantiate => InstantiationStrategy is not InstantiationStrategy.None && InitExceptionMessage is null; - - public Dictionary Properties { get; } = new(StringComparer.OrdinalIgnoreCase); - - public List ConstructorParameters { get; } = new(); + public ObjectSpec( + INamedTypeSymbol type, + ObjectInstantiationStrategy instantiationStrategy, + ImmutableEquatableArray? properties, + ImmutableEquatableArray? constructorParameters, + string? initExceptionMessage) : base(type) + { + InstantiationStrategy = instantiationStrategy; + Properties = properties; + ConstructorParameters = constructorParameters; + InitExceptionMessage = initExceptionMessage; + } + + public ObjectInstantiationStrategy InstantiationStrategy { get; } + + public ImmutableEquatableArray? Properties { get; } + + public ImmutableEquatableArray? ConstructorParameters { get; } + + public string? InitExceptionMessage { get; } + } - public string? InitExceptionMessage { get; set; } + public enum ObjectInstantiationStrategy + { + None = 0, + ParameterlessConstructor = 1, + ParameterizedConstructor = 2, } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/SimpleTypeSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/SimpleTypeSpec.cs index 2dfe08dc5f547a..70c7a8042e0359 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/SimpleTypeSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/SimpleTypeSpec.cs @@ -1,55 +1,28 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using Microsoft.CodeAnalysis; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { - internal abstract record SimpleTypeSpec : TypeSpec + public abstract record SimpleTypeSpec : TypeSpec { public SimpleTypeSpec(ITypeSymbol type) : base(type) { } - - public sealed override bool CanBindTo => true; - - public sealed override TypeSpec EffectiveType => this; - - public sealed override bool CanInstantiate => true; } internal sealed record ConfigurationSectionSpec : SimpleTypeSpec { public ConfigurationSectionSpec(ITypeSymbol type) : base(type) { } - - public override TypeSpecKind SpecKind => TypeSpecKind.IConfigurationSection; } - internal sealed record ParsableFromStringSpec : SimpleTypeSpec + public sealed record ParsableFromStringSpec : SimpleTypeSpec { public ParsableFromStringSpec(ITypeSymbol type) : base(type) { } - public override TypeSpecKind SpecKind => TypeSpecKind.ParsableFromString; - public required StringParsableTypeKind StringParsableTypeKind { get; init; } - - private string? _parseMethodName; - public string ParseMethodName - { - get - { - Debug.Assert(StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue); - - _parseMethodName ??= StringParsableTypeKind is StringParsableTypeKind.ByteArray - ? "ParseByteArray" - // MinimalDisplayString.Length is certainly > 2. - : $"Parse{(char.ToUpper(DisplayString[0]) + DisplayString.Substring(1)).Replace(".", "")}"; - - return _parseMethodName; - } - } } - internal enum StringParsableTypeKind + public enum StringParsableTypeKind { None = 0, diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/TypeSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/TypeSpec.cs index 651a40639f0ced..1c243ae1cdc7c1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/TypeSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/TypeSpec.cs @@ -3,27 +3,26 @@ using System.Diagnostics; using Microsoft.CodeAnalysis; +using SourceGenerators; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { [DebuggerDisplay("Name={DisplayString}, Kind={SpecKind}")] - internal abstract record TypeSpec + public abstract record TypeSpec { - private static readonly SymbolDisplayFormat s_minimalDisplayFormat = new SymbolDisplayFormat( - globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Omitted, - typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes, - genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, - miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes); - public TypeSpec(ITypeSymbol type) { - Namespace = type.ContainingNamespace?.ToDisplayString(); - DisplayString = type.ToDisplayString(s_minimalDisplayFormat); - Name = (Namespace is null ? string.Empty : Namespace + ".") + DisplayString.Replace(".", "+"); + TypeRef = new TypeRef(type); + EffectiveTypeRef = TypeRef; // Overriden by NullableSpec. + (Namespace, DisplayString, Name) = type.GetTypeName(); IdentifierCompatibleSubstring = type.ToIdentifierCompatibleSubstring(); IsValueType = type.IsValueType; } + public TypeRef TypeRef { get; } + + public TypeRef EffectiveTypeRef { get; protected init; } + public string Name { get; } public string DisplayString { get; } @@ -33,24 +32,35 @@ public TypeSpec(ITypeSymbol type) public string? Namespace { get; } public bool IsValueType { get; } + } - public abstract TypeSpecKind SpecKind { get; } + public abstract record ComplexTypeSpec : TypeSpec + { + protected ComplexTypeSpec(ITypeSymbol type) : base(type) { } + } - public abstract bool CanBindTo { get; } + internal sealed record NullableSpec : TypeSpec + { + public NullableSpec(ITypeSymbol type, TypeRef underlyingTypeRef) : base(type) => + EffectiveTypeRef = underlyingTypeRef; + } - public abstract bool CanInstantiate { get; } + internal sealed record UnsupportedTypeSpec : TypeSpec + { + public UnsupportedTypeSpec(ITypeSymbol type) : base(type) { } - public abstract TypeSpec EffectiveType { get; } + public required NotSupportedReason NotSupportedReason { get; init; } } - internal enum TypeSpecKind + public enum NotSupportedReason { - Unknown = 0, - ParsableFromString = 1, - Object = 2, - Enumerable = 3, - Dictionary = 4, - IConfigurationSection = 5, - Nullable = 6, + UnknownType = 1, + MissingPublicInstanceConstructor = 2, + CollectionNotSupported = 3, + DictionaryKeyNotSupported = 4, + ElementTypeNotSupported = 5, + MultipleParameterizedConstructors = 6, + MultiDimArraysNotSupported = 7, + NullableUnderlyingTypeNotSupported = 8, } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt index ddd52c68b99892..ea4fba79cbc465 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt @@ -37,7 +37,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #endregion IConfiguration extensions. #region Core binding extensions. - private readonly static Lazy> s_configKeys_ProgramMyClassWithCustomCollections = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "CustomDictionary", "CustomList", "IReadOnlyList", "IReadOnlyDictionary" }); + private readonly static Lazy> s_configKeys_ProgramMyClassWithCustomCollections = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "CustomDictionary", "CustomList", "ICustomDictionary", "ICustomCollection", "IReadOnlyList", "UnsupportedIReadOnlyDictionaryUnsupported", "IReadOnlyDictionary" }); public static object? GetCore(this IConfiguration configuration, Type type, Action? configureOptions) { @@ -85,28 +85,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) - { - foreach (IConfigurationSection section in configuration.GetChildren()) - { - if (section.Value is string value) - { - instance.Add(ParseInt(value, () => section.Path)); - } - } - } - - public static void BindCore(IConfiguration configuration, ref ICollection instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) - { - foreach (IConfigurationSection section in configuration.GetChildren()) - { - if (section.Value is string value) - { - instance.Add(ParseInt(value, () => section.Path)); - } - } - } - public static void BindCore(IConfiguration configuration, ref IReadOnlyList instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { if (instance is not ICollection temp) @@ -123,28 +101,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) - { - foreach (IConfigurationSection section in configuration.GetChildren()) - { - if (section.Value is string value) - { - instance[section.Key] = ParseInt(value, () => section.Path); - } - } - } - - public static void BindCore(IConfiguration configuration, ref IDictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) - { - foreach (IConfigurationSection section in configuration.GetChildren()) - { - if (section.Value is string value) - { - instance[section.Key] = ParseInt(value, () => section.Path); - } - } - } - public static void BindCore(IConfiguration configuration, ref IReadOnlyDictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { if (instance is not IDictionary temp) @@ -184,7 +140,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (AsConfigWithChildren(configuration.GetSection("IReadOnlyList")) is IConfigurationSection section7) { IReadOnlyList? temp9 = instance.IReadOnlyList; - temp9 = temp9 is null ? new List() : new List(temp9); + temp9 = temp9 is null ? (IReadOnlyList)new List() : (IReadOnlyList)new List(temp9); BindCore(section7, ref temp9, defaultValueIfNotFound: false, binderOptions); instance.IReadOnlyList = temp9; } @@ -192,7 +148,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (AsConfigWithChildren(configuration.GetSection("IReadOnlyDictionary")) is IConfigurationSection section10) { IReadOnlyDictionary? temp12 = instance.IReadOnlyDictionary; - temp12 = temp12 is null ? new Dictionary() : temp12.ToDictionary(pair => pair.Key, pair => pair.Value); + temp12 = temp12 is null ? (IReadOnlyDictionary)new Dictionary() : (IReadOnlyDictionary)temp12.ToDictionary(pair => pair.Key, pair => pair.Value); BindCore(section10, ref temp12, defaultValueIfNotFound: false, binderOptions); instance.IReadOnlyDictionary = temp12; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt index 5e7eeae29254a4..b6fb659d544d42 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt @@ -95,7 +95,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref int[] instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { var temp2 = new List(); - BindCore(configuration, ref temp2, defaultValueIfNotFound: false, binderOptions); + + foreach (IConfigurationSection section in configuration.GetChildren()) + { + if (section.Value is string value) + { + temp2.Add(ParseInt(value, () => section.Path)); + } + } + int originalCount = instance.Length; Array.Resize(ref instance, originalCount + temp2.Count); temp2.CopyTo(instance, originalCount); @@ -116,42 +124,42 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - if (configuration["MyString"] is string value4) + if (configuration["MyString"] is string value3) { - instance.MyString = value4; + instance.MyString = value3; } - if (configuration["MyInt"] is string value5) + if (configuration["MyInt"] is string value4) { - instance.MyInt = ParseInt(value5, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); } else if (defaultValueIfNotFound) { instance.MyInt = default; } - if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section6) + if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) { - List? temp8 = instance.MyList; - temp8 ??= new List(); - BindCore(section6, ref temp8, defaultValueIfNotFound: false, binderOptions); - instance.MyList = temp8; + List? temp7 = instance.MyList; + temp7 ??= new List(); + BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions); + instance.MyList = temp7; } - if (AsConfigWithChildren(configuration.GetSection("MyArray")) is IConfigurationSection section9) + if (AsConfigWithChildren(configuration.GetSection("MyArray")) is IConfigurationSection section8) { - int[]? temp11 = instance.MyArray; - temp11 ??= new int[0]; - BindCore(section9, ref temp11, defaultValueIfNotFound: false, binderOptions); - instance.MyArray = temp11; + int[]? temp10 = instance.MyArray; + temp10 ??= new int[0]; + BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions); + instance.MyArray = temp10; } - if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section12) + if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section11) { - Dictionary? temp14 = instance.MyDictionary; - temp14 ??= new Dictionary(); - BindCore(section12, ref temp14, defaultValueIfNotFound: false, binderOptions); - instance.MyDictionary = temp14; + Dictionary? temp13 = instance.MyDictionary; + temp13 ??= new Dictionary(); + BindCore(section11, ref temp13, defaultValueIfNotFound: false, binderOptions); + instance.MyDictionary = temp13; } } @@ -159,9 +167,9 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value15) + if (configuration["MyInt"] is string value14) { - instance.MyInt = ParseInt(value15, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value14, () => configuration.GetSection("MyInt").Path); } else if (defaultValueIfNotFound) { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_PrimitivesOnly.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_PrimitivesOnly.generated.txt new file mode 100644 index 00000000000000..b703fb5f1c864b --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_PrimitivesOnly.generated.txt @@ -0,0 +1,182 @@ +// +#nullable enable +#pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. + +namespace System.Runtime.CompilerServices +{ + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } +} + +namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration +{ + using Microsoft.Extensions.Configuration; + using System; + using System.CodeDom.Compiler; + using System.Globalization; + using System.Runtime.CompilerServices; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + file static class BindingExtensions + { + #region IConfiguration extensions. + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocation(@"src-0.cs", 10, 16)] + public static T? Get(this IConfiguration configuration) => (T?)(GetCore(configuration, typeof(T), configureOptions: null) ?? default(T)); + + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocation(@"src-0.cs", 12, 16)] + public static T? Get(this IConfiguration configuration, Action? configureOptions) => (T?)(GetCore(configuration, typeof(T), configureOptions) ?? default(T)); + + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocation(@"src-0.cs", 11, 16)] + public static object? Get(this IConfiguration configuration, Type type) => GetCore(configuration, type, configureOptions: null); + + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocation(@"src-0.cs", 13, 16)] + public static object? Get(this IConfiguration configuration, Type type, Action? configureOptions) => GetCore(configuration, type, configureOptions); + #endregion IConfiguration extensions. + + #region Core binding extensions. + public static object? GetCore(this IConfiguration configuration, Type type, Action? configureOptions) + { + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + BinderOptions? binderOptions = GetBinderOptions(configureOptions); + + if (!HasValueOrChildren(configuration)) + { + return null; + } + + if (type == typeof(int)) + { + if (configuration is not IConfigurationSection section) + { + throw new InvalidOperationException(); + } + if (section.Value is string value) + { + return ParseInt(value, () => section.Path); + } + } + else if (type == typeof(string)) + { + if (configuration is not IConfigurationSection section) + { + throw new InvalidOperationException(); + } + return section.Value; + } + else if (type == typeof(float)) + { + if (configuration is not IConfigurationSection section) + { + throw new InvalidOperationException(); + } + if (section.Value is string value) + { + return ParseFloat(value, () => section.Path); + } + } + else if (type == typeof(double)) + { + if (configuration is not IConfigurationSection section) + { + throw new InvalidOperationException(); + } + if (section.Value is string value) + { + return ParseDouble(value, () => section.Path); + } + } + + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + } + + public static bool HasValueOrChildren(IConfiguration configuration) + { + if ((configuration as IConfigurationSection)?.Value is not null) + { + return true; + } + return AsConfigWithChildren(configuration) is not null; + } + + public static IConfiguration? AsConfigWithChildren(IConfiguration configuration) + { + foreach (IConfigurationSection _ in configuration.GetChildren()) + { + return configuration; + } + return null; + } + + public static BinderOptions? GetBinderOptions(Action? configureOptions) + { + if (configureOptions is null) + { + return null; + } + + BinderOptions binderOptions = new(); + configureOptions(binderOptions); + + if (binderOptions.BindNonPublicProperties) + { + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + } + + return binderOptions; + } + + public static int ParseInt(string value, Func getPath) + { + try + { + return int.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture); + } + catch (Exception exception) + { + throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); + } + } + + public static float ParseFloat(string value, Func getPath) + { + try + { + return float.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); + } + catch (Exception exception) + { + throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(float)}'.", exception); + } + } + + public static double ParseDouble(string value, Func getPath) + { + try + { + return double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); + } + catch (Exception exception) + { + throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(double)}'.", exception); + } + } + #endregion Core binding extensions. + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt index 3fc5176bf50f09..c2e8f167bb4750 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt @@ -76,7 +76,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref int[] instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { var temp1 = new List(); - BindCore(configuration, ref temp1, defaultValueIfNotFound: false, binderOptions); + + foreach (IConfigurationSection section in configuration.GetChildren()) + { + if (section.Value is string value) + { + temp1.Add(ParseInt(value, () => section.Path)); + } + } + int originalCount = instance.Length; Array.Resize(ref instance, originalCount + temp1.Count); temp1.CopyTo(instance, originalCount); @@ -97,42 +105,42 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - if (configuration["MyString"] is string value3) + if (configuration["MyString"] is string value2) { - instance.MyString = value3; + instance.MyString = value2; } - if (configuration["MyInt"] is string value4) + if (configuration["MyInt"] is string value3) { - instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value3, () => configuration.GetSection("MyInt").Path); } else if (defaultValueIfNotFound) { instance.MyInt = default; } - if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) + if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section4) { - List? temp7 = instance.MyList; - temp7 ??= new List(); - BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions); - instance.MyList = temp7; + List? temp6 = instance.MyList; + temp6 ??= new List(); + BindCore(section4, ref temp6, defaultValueIfNotFound: false, binderOptions); + instance.MyList = temp6; } - if (AsConfigWithChildren(configuration.GetSection("MyArray")) is IConfigurationSection section8) + if (AsConfigWithChildren(configuration.GetSection("MyArray")) is IConfigurationSection section7) { - int[]? temp10 = instance.MyArray; - temp10 ??= new int[0]; - BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions); - instance.MyArray = temp10; + int[]? temp9 = instance.MyArray; + temp9 ??= new int[0]; + BindCore(section7, ref temp9, defaultValueIfNotFound: false, binderOptions); + instance.MyArray = temp9; } - if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section11) + if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section10) { - Dictionary? temp13 = instance.MyDictionary; - temp13 ??= new Dictionary(); - BindCore(section11, ref temp13, defaultValueIfNotFound: false, binderOptions); - instance.MyDictionary = temp13; + Dictionary? temp12 = instance.MyDictionary; + temp12 ??= new Dictionary(); + BindCore(section10, ref temp12, defaultValueIfNotFound: false, binderOptions); + instance.MyDictionary = temp12; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt index 81c23d7ceea65a..cd3f237917d4e3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt @@ -76,7 +76,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static void BindCore(IConfiguration configuration, ref int[] instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { var temp1 = new List(); - BindCore(configuration, ref temp1, defaultValueIfNotFound: false, binderOptions); + + foreach (IConfigurationSection section in configuration.GetChildren()) + { + if (section.Value is string value) + { + temp1.Add(ParseInt(value, () => section.Path)); + } + } + int originalCount = instance.Length; Array.Resize(ref instance, originalCount + temp1.Count); temp1.CopyTo(instance, originalCount); @@ -97,42 +105,42 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - if (configuration["MyString"] is string value3) + if (configuration["MyString"] is string value2) { - instance.MyString = value3; + instance.MyString = value2; } - if (configuration["MyInt"] is string value4) + if (configuration["MyInt"] is string value3) { - instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); + instance.MyInt = ParseInt(value3, () => configuration.GetSection("MyInt").Path); } else if (defaultValueIfNotFound) { instance.MyInt = default; } - if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) + if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section4) { - List? temp7 = instance.MyList; - temp7 ??= new List(); - BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions); - instance.MyList = temp7; + List? temp6 = instance.MyList; + temp6 ??= new List(); + BindCore(section4, ref temp6, defaultValueIfNotFound: false, binderOptions); + instance.MyList = temp6; } - if (AsConfigWithChildren(configuration.GetSection("MyArray")) is IConfigurationSection section8) + if (AsConfigWithChildren(configuration.GetSection("MyArray")) is IConfigurationSection section7) { - int[]? temp10 = instance.MyArray; - temp10 ??= new int[0]; - BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions); - instance.MyArray = temp10; + int[]? temp9 = instance.MyArray; + temp9 ??= new int[0]; + BindCore(section7, ref temp9, defaultValueIfNotFound: false, binderOptions); + instance.MyArray = temp9; } - if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section11) + if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section10) { - Dictionary? temp13 = instance.MyDictionary; - temp13 ??= new Dictionary(); - BindCore(section11, ref temp13, defaultValueIfNotFound: false, binderOptions); - instance.MyDictionary = temp13; + Dictionary? temp12 = instance.MyDictionary; + temp12 ??= new Dictionary(); + BindCore(section10, ref temp12, defaultValueIfNotFound: false, binderOptions); + instance.MyDictionary = temp12; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigBindingGenTestDriver.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigBindingGenTestDriver.cs new file mode 100644 index 00000000000000..4373b404fc67f0 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigBindingGenTestDriver.cs @@ -0,0 +1,156 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.Extensions.Configuration.Binder.SourceGeneration; +using SourceGenerators.Tests; +using Xunit; + +namespace Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests +{ + [ActiveIssue("https://github.com/dotnet/runtime/issues/52062", TestPlatforms.Browser)] + public partial class ConfigurationBindingGeneratorTests : ConfigurationBinderTestsBase + { + internal sealed class ConfigBindingGenTestDriver + { + private readonly CSharpParseOptions _parseOptions; + private GeneratorDriver _generatorDriver; + private SourceGenerationSpec? _genSpec; + + private readonly LanguageVersion _langVersion; + private readonly IEnumerable? _assemblyReferences; + private Compilation _compilation = null; + + public ConfigBindingGenTestDriver( + LanguageVersion langVersion = LanguageVersion.LatestMajor, + IEnumerable? assemblyReferences = null) + { + _langVersion = langVersion; + + _assemblyReferences = assemblyReferences ?? s_compilationAssemblyRefs; + + _parseOptions = new CSharpParseOptions(langVersion).WithFeatures(new[] { + new KeyValuePair("InterceptorsPreview", "") , + new KeyValuePair("InterceptorsPreviewNamespaces", "Microsoft.Extensions.Configuration.Binder.SourceGeneration") + }); + + ConfigurationBindingGenerator generator = new() { OnSourceEmitting = spec => _genSpec = spec }; + _generatorDriver = CSharpGeneratorDriver.Create( + new ISourceGenerator[] { generator.AsSourceGenerator() }, + parseOptions: _parseOptions, + driverOptions: new GeneratorDriverOptions( + disabledOutputs: IncrementalGeneratorOutputKind.None, + trackIncrementalGeneratorSteps: true)); + } + + public async Task RunGeneratorAndUpdateCompilation(string? source = null) + { + await UpdateCompilationWithSource(source); + Assert.NotNull(_compilation); + + _generatorDriver = _generatorDriver.RunGeneratorsAndUpdateCompilation(_compilation, out Compilation outputCompilation, out _, CancellationToken.None); + GeneratorDriverRunResult runResult = _generatorDriver.GetRunResult(); + + return new ConfigBindingGenRunResult + { + OutputCompilation = outputCompilation, + Diagnostics = runResult.Diagnostics, + GeneratedSource = runResult.Results[0].GeneratedSources is { Length: not 0 } sources ? sources[0] : null, + TrackedSteps = runResult.Results[0].TrackedSteps[ConfigurationBindingGenerator.GenSpecTrackingName], + GenerationSpec = _genSpec + }; + } + + private async Task UpdateCompilationWithSource(string? source = null) + { + if (_compilation is not null && source is not null) + { + SyntaxTree newTree = CSharpSyntaxTree.ParseText(source, _parseOptions); + _compilation = _compilation.ReplaceSyntaxTree(_compilation.SyntaxTrees.First(), newTree); + } + else if (_compilation is null) + { + Assert.True(source is not null, "Generator test requires input source."); + using AdhocWorkspace workspace = RoslynTestUtils.CreateTestWorkspace(); + + Project project = RoslynTestUtils.CreateTestProject(workspace, _assemblyReferences, langVersion: _langVersion) + .WithCompilationOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithNullableContextOptions(NullableContextOptions.Annotations)) + .WithParseOptions(_parseOptions) + .WithDocuments(new string[] { source }); + Assert.True(project.Solution.Workspace.TryApplyChanges(project.Solution)); + + _compilation = (await project.GetCompilationAsync(CancellationToken.None).ConfigureAwait(false))!; + } + } + } + } + + internal struct ConfigBindingGenRunResult + { + public required Compilation OutputCompilation { get; init; } + + public required GeneratedSourceResult? GeneratedSource { get; init; } + + /// + /// Diagnostics produced by the generator alone. Doesn't include any from other build participants. + /// + public required ImmutableArray Diagnostics { get; init; } + + public required ImmutableArray TrackedSteps { get; init; } + + public required SourceGenerationSpec? GenerationSpec { get; init; } + } + + internal enum ExpectedDiagnostics + { + None, + FromGeneratorOnly, + } + + internal static class ConfigBindingGenTestDriverExtensions + { + public static void ValidateIncrementalResult(this ConfigBindingGenRunResult result, + IncrementalStepRunReason inputReason, + IncrementalStepRunReason outputReason) + { + Assert.Collection(result.TrackedSteps, step => + { + Assert.Collection(step.Inputs, source => Assert.Equal(inputReason, source.Source.Outputs[source.OutputIndex].Reason)); + Assert.Collection(step.Outputs, output => Assert.Equal(outputReason, output.Reason)); + }); + } + + public static void ValidateDiagnostics(this ConfigBindingGenRunResult result, ExpectedDiagnostics expectedDiags) + { + ImmutableArray outputDiagnostics = result.OutputCompilation.GetDiagnostics(); + + if (expectedDiags is ExpectedDiagnostics.None) + { + foreach (Diagnostic diagnostic in outputDiagnostics) + { + Assert.True( + IsPermitted(diagnostic), + $"Generator caused dagnostic in output compilation: {diagnostic.GetMessage(CultureInfo.InvariantCulture)}."); + } + } + else + { + Debug.Assert(expectedDiags is ExpectedDiagnostics.FromGeneratorOnly); + + Assert.NotEmpty(result.Diagnostics); + Assert.False(outputDiagnostics.Any(diag => !IsPermitted(diag))); + } + + static bool IsPermitted(Diagnostic diagnostic) => diagnostic.Severity <= DiagnosticSeverity.Info; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs index 3c46f5f99818b1..e05a7737137128 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis; @@ -141,7 +142,7 @@ public static void Main() public class MyClass { - public string MyString { get; set; } + public string? MyString { get; set; } public int MyInt { get; set; } public List MyList { get; set; } public Dictionary MyDictionary { get; set; } @@ -314,6 +315,30 @@ public class MyClass4 await VerifyAgainstBaselineUsingFile("Get.generated.txt", source, extType: ExtensionClassType.ConfigurationBinder); } + [Fact] + public async Task Get_PrimitivesOnly() + { + string source = """ + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfigurationRoot config = configurationBuilder.Build(); + + config.Get(); + config.Get(typeof(string)); + config.Get(binderOptions => { }); + config.Get(typeof(double), binderOptions => { }); + } + } + """; + + await VerifyAgainstBaselineUsingFile("Get_PrimitivesOnly.generated.txt", source, extType: ExtensionClassType.ConfigurationBinder); + } + [Fact] public async Task Get_T() { @@ -654,9 +679,9 @@ public class MyClass2 }" ; - var (d, r) = await RunGenerator(source); - Assert.Empty(r); - Assert.Empty(d); + ConfigBindingGenRunResult result = await RunGeneratorAndUpdateCompilation(source); + Assert.False(result.GeneratedSource.HasValue); + Assert.Empty(result.Diagnostics); } [Fact] @@ -736,6 +761,7 @@ public static void Main() section.Get(); } + // Diagnostic warning because we don't know how to instantiate two properties on this type. public class MyClassWithCustomCollections { public CustomDictionary CustomDictionary { get; set; } @@ -743,6 +769,7 @@ public class MyClassWithCustomCollections public ICustomDictionary ICustomDictionary { get; set; } public ICustomSet ICustomCollection { get; set; } public IReadOnlyList IReadOnlyList { get; set; } + // Diagnostic warning because we don't know how to instantiate the property type. public IReadOnlyDictionary UnsupportedIReadOnlyDictionaryUnsupported { get; set; } public IReadOnlyDictionary IReadOnlyDictionary { get; set; } } @@ -755,21 +782,26 @@ public class CustomList : List { } + // Diagnostic warning because we don't know how to instantiate this type. public interface ICustomDictionary : IDictionary { } + // Diagnostic warning because we don't know how to instantiate this type. public interface ICustomSet : ISet { } } """; - await VerifyAgainstBaselineUsingFile("Collections.generated.txt", source, validateOutputCompDiags: false, assessDiagnostics: (d) => - { - Assert.Equal(3, d.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); - Assert.Equal(6, d.Where(diag => diag.Id == Diagnostics.PropertyNotSupported.Id).Count()); - }); + ConfigBindingGenRunResult result = await VerifyAgainstBaselineUsingFile( + "Collections.generated.txt", + source, + expectedDiags: ExpectedDiagnostics.FromGeneratorOnly); + + ImmutableArray diagnostics = result.Diagnostics; + Assert.Equal(3, diagnostics.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); + Assert.Equal(3, diagnostics.Where(diag => diag.Id == Diagnostics.PropertyNotSupported.Id).Count()); } [Fact] @@ -811,14 +843,12 @@ public abstract class AbstractType_CannotInit } """; - await VerifyAgainstBaselineUsingFile( + ConfigBindingGenRunResult result = await VerifyAgainstBaselineUsingFile( "EmptyConfigType.generated.txt", source, - assessDiagnostics: (d) => - { - Assert.Equal(2, d.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); - }, - validateOutputCompDiags: false); + expectedDiags: ExpectedDiagnostics.FromGeneratorOnly); + + Assert.Equal(2, result.Diagnostics.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs index 7a47ad1cb27251..cbbd34e7fc41da 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs @@ -9,10 +9,10 @@ using System.IO; using System.Linq; using System.Reflection; -using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Text; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration.Binder.SourceGeneration; using Microsoft.Extensions.DependencyInjection; @@ -24,6 +24,9 @@ namespace Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests { public partial class ConfigurationBindingGeneratorTests { + /// + /// Keep in sync with variants, e.g. . + /// private const string BindCallSampleCode = """ using System.Collections.Generic; using Microsoft.Extensions.Configuration; @@ -63,6 +66,7 @@ private static class Diagnostics } private static readonly Assembly[] s_compilationAssemblyRefs = new[] { + typeof(BitArray).Assembly, typeof(ConfigurationBinder).Assembly, typeof(ConfigurationBuilder).Assembly, typeof(CultureInfo).Assembly, @@ -87,18 +91,19 @@ private enum ExtensionClassType private static async Task VerifyThatSourceIsGenerated(string testSourceCode) { - var (d, r) = await RunGenerator(testSourceCode); - Assert.Equal(1, r.Length); - Assert.Empty(d); - Assert.True(r[0].SourceText.Lines.Count > 10); + ConfigBindingGenRunResult result = await RunGeneratorAndUpdateCompilation(testSourceCode); + GeneratedSourceResult? source = result.GeneratedSource; + + Assert.NotNull(source); + Assert.Empty(result.Diagnostics); + Assert.True(source.Value.SourceText.Lines.Count > 10); } - private static async Task VerifyAgainstBaselineUsingFile( + private static async Task VerifyAgainstBaselineUsingFile( string filename, string testSourceCode, - Action>? assessDiagnostics = null, ExtensionClassType extType = ExtensionClassType.None, - bool validateOutputCompDiags = true) + ExpectedDiagnostics expectedDiags = ExpectedDiagnostics.None) { string path = extType is ExtensionClassType.None ? Path.Combine("Baselines", filename) @@ -107,70 +112,52 @@ private static async Task VerifyAgainstBaselineUsingFile( string[] expectedLines = baseline.Replace("%VERSION%", typeof(ConfigurationBindingGenerator).Assembly.GetName().Version?.ToString()) .Split(Environment.NewLine); - var (d, r) = await RunGenerator(testSourceCode, validateOutputCompDiags); - bool success = RoslynTestUtils.CompareLines(expectedLines, r[0].SourceText, out string errorMessage); + ConfigBindingGenRunResult result = await RunGeneratorAndUpdateCompilation(testSourceCode); + result.ValidateDiagnostics(expectedDiags); + + SourceText resultSourceText = result.GeneratedSource.Value.SourceText; + bool resultEqualsBaseline = RoslynTestUtils.CompareLines(expectedLines, resultSourceText, out string errorMessage); #if UPDATE_BASELINES - if (!success) + if (!resultEqualsBaseline) { - string? repoRootDir = Environment.GetEnvironmentVariable("RepoRootDir"); - Assert.True(repoRootDir is not null, "To update baselines, specifiy the root runtime repo dir"); + const string envVarName = "RepoRootDir"; + string errMessage = $"To update baselines, specify a '{envVarName}' environment variable. See this assembly's README.md doc for more details."; + + string? repoRootDir = Environment.GetEnvironmentVariable(envVarName); + Assert.True(repoRootDir is not null, errMessage); - IEnumerable lines = r[0].SourceText.Lines.Select(l => l.ToString()); + IEnumerable lines = resultSourceText.Lines.Select(l => l.ToString()); string source = string.Join(Environment.NewLine, lines).TrimEnd(Environment.NewLine.ToCharArray()) + Environment.NewLine; path = Path.Combine($"{repoRootDir}\\src\\libraries\\Microsoft.Extensions.Configuration.Binder\\tests\\SourceGenerationTests\\", path); await File.WriteAllTextAsync(path, source).ConfigureAwait(false); - success = true; + resultEqualsBaseline = true; } #endif - Assert.Single(r); - (assessDiagnostics ?? ((d) => Assert.Empty(d))).Invoke(d); - Assert.True(success, errorMessage); + Assert.True(resultEqualsBaseline, errorMessage); + + return result; } - private static async Task<(ImmutableArray, ImmutableArray)> RunGenerator( - string testSourceCode, - bool validateOutputCompDiags = false, + private static async Task RunGeneratorAndUpdateCompilation( + string source, LanguageVersion langVersion = LanguageVersion.CSharp12, - IEnumerable? references = null) + IEnumerable? assemblyReferences = null) { - using var workspace = RoslynTestUtils.CreateTestWorkspace(); - CSharpParseOptions parseOptions = new CSharpParseOptions(langVersion).WithFeatures(new[] { - new KeyValuePair("InterceptorsPreview", ""), - new KeyValuePair("InterceptorsPreviewNamespaces", "Microsoft.Extensions.Configuration.Binder.SourceGeneration") - }); - - Project proj = RoslynTestUtils.CreateTestProject(workspace, references ?? s_compilationAssemblyRefs, langVersion: langVersion) - .WithCompilationOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithNullableContextOptions(NullableContextOptions.Annotations)) - .WithDocuments(new string[] { testSourceCode }) - .WithParseOptions(parseOptions); - - Assert.True(proj.Solution.Workspace.TryApplyChanges(proj.Solution)); - - Compilation comp = await proj.GetCompilationAsync(CancellationToken.None).ConfigureAwait(false); - CSharpGeneratorDriver cgd = CSharpGeneratorDriver.Create(new[] { new ConfigurationBindingGenerator().AsSourceGenerator() }, parseOptions: parseOptions); - GeneratorDriver gd = cgd.RunGeneratorsAndUpdateCompilation(comp, out Compilation outputCompilation, out _, CancellationToken.None); - GeneratorDriverRunResult runResult = gd.GetRunResult(); - - if (validateOutputCompDiags) - { - ImmutableArray diagnostics = outputCompilation.GetDiagnostics(); - Assert.False(diagnostics.Any(d => d.Severity > DiagnosticSeverity.Info)); - } - - return (runResult.Results[0].Diagnostics, runResult.Results[0].GeneratedSources); + ConfigBindingGenTestDriver driver = new ConfigBindingGenTestDriver(langVersion, assemblyReferences); + return await driver.RunGeneratorAndUpdateCompilation(source); } - public static List GetAssemblyRefsWithAdditional(params Type[] additional) + private static List GetAssemblyRefsWithAdditional(params Type[] additional) { List assemblies = new(s_compilationAssemblyRefs); assemblies.AddRange(additional.Select(t => t.Assembly)); return assemblies; } - public static HashSet GetFilteredAssemblyRefs(IEnumerable exclusions) + private static HashSet GetFilteredAssemblyRefs(IEnumerable exclusions) { HashSet assemblies = new(s_compilationAssemblyRefs); foreach (Type exclusion in exclusions) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Incremental.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Incremental.cs new file mode 100644 index 00000000000000..aff9a0c20364ca --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Incremental.cs @@ -0,0 +1,362 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.Extensions.Configuration.Binder.SourceGeneration; +using SourceGenerators.Tests; +using Xunit; + +namespace Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests +{ + public partial class ConfigurationBindingGeneratorTests : ConfigurationBinderTestsBase + { + [ActiveIssue("https://github.com/dotnet/runtime/issues/52062", TestPlatforms.Browser)] + public sealed class IncrementalTests + { + [Fact] + public async Task CompilingTheSameSourceResultsInEqualModels() + { + SourceGenerationSpec spec1 = (await new ConfigBindingGenTestDriver().RunGeneratorAndUpdateCompilation(BindCallSampleCode)).GenerationSpec; + SourceGenerationSpec spec2 = (await new ConfigBindingGenTestDriver().RunGeneratorAndUpdateCompilation(BindCallSampleCode)).GenerationSpec; + + Assert.NotSame(spec1, spec2); + GeneratorTestHelpers.AssertStructurallyEqual(spec1, spec2); + + Assert.Equal(spec1, spec2); + Assert.Equal(spec1.GetHashCode(), spec2.GetHashCode()); + } + + [Fact] + public async Task RunWithNoDiags_Then_NoEdit() + { + ConfigBindingGenTestDriver driver = new ConfigBindingGenTestDriver(); + + ConfigBindingGenRunResult result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCode); + result.ValidateIncrementalResult(IncrementalStepRunReason.New, IncrementalStepRunReason.New); + + result = await driver.RunGeneratorAndUpdateCompilation(); + result.ValidateIncrementalResult(IncrementalStepRunReason.Modified, IncrementalStepRunReason.Unchanged); + } + + [Fact] + public async Task RunWithNoDiags_Then_ChangeInputOrder() + { + ConfigBindingGenTestDriver driver = new ConfigBindingGenTestDriver(); + + ConfigBindingGenRunResult result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCode); + result.ValidateIncrementalResult(IncrementalStepRunReason.New, IncrementalStepRunReason.New); + + // We expect different spec because diag locations are different. + result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCodeVariant_ReorderedInvocations); + result.ValidateIncrementalResult(IncrementalStepRunReason.Modified, IncrementalStepRunReason.Modified); + + // We expect different spec because members are reordered. + result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCodeVariant_ReorderedConfigTypeMembers); + result.ValidateIncrementalResult(IncrementalStepRunReason.Modified, IncrementalStepRunReason.Modified); + } + + [Fact] + public async Task RunWithNoDiags_Then_EditWithNoDiags() + { + ConfigBindingGenTestDriver driver = new ConfigBindingGenTestDriver(); + + ConfigBindingGenRunResult result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCode); + result.ValidateIncrementalResult(IncrementalStepRunReason.New, IncrementalStepRunReason.New); + + result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCodeVariant_WithDifferentConfigTypeName); + result.ValidateIncrementalResult(IncrementalStepRunReason.Modified, IncrementalStepRunReason.Modified); + } + + [Fact] + public async Task RunWithNoDiags_Then_EditWithDiags() + { + ConfigBindingGenTestDriver driver = new ConfigBindingGenTestDriver(); + + ConfigBindingGenRunResult result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCode); + result.ValidateIncrementalResult(IncrementalStepRunReason.New, IncrementalStepRunReason.New); + + result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCodeVariant_WithUnsupportedMember); + result.ValidateIncrementalResult(IncrementalStepRunReason.Modified, IncrementalStepRunReason.Modified); + } + + [Fact] + public async Task RunWithDiags_Then_NoEdit() + { + ConfigBindingGenTestDriver driver = new ConfigBindingGenTestDriver(); + + ConfigBindingGenRunResult result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCodeVariant_WithUnsupportedMember); + result.ValidateIncrementalResult(IncrementalStepRunReason.New, IncrementalStepRunReason.New); + + result = await driver.RunGeneratorAndUpdateCompilation(); + result.ValidateIncrementalResult(IncrementalStepRunReason.Modified, IncrementalStepRunReason.Unchanged); + } + + [Fact] + public async Task RunWithDiags_Then_ChangeInputOrder() + { + ConfigBindingGenTestDriver driver = new ConfigBindingGenTestDriver(); + + ConfigBindingGenRunResult result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCodeVariant_WithUnsupportedMember); + result.ValidateIncrementalResult(IncrementalStepRunReason.New, IncrementalStepRunReason.New); + + // We expect different spec because diag locations are different. + result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCodeVariant_WithUnsupportedMember_ReorderedInvocations); + result.ValidateIncrementalResult(IncrementalStepRunReason.Modified, IncrementalStepRunReason.Modified); + + // We expect different spec because members are reordered. + result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCodeVariant_WithUnsupportedMember_ReorderedConfigTypeMembers); + result.ValidateIncrementalResult(IncrementalStepRunReason.Modified, IncrementalStepRunReason.Modified); + } + + [Fact] + public async Task RunWithDiags_Then_EditWithNoDiags() + { + ConfigBindingGenTestDriver driver = new ConfigBindingGenTestDriver(); + + ConfigBindingGenRunResult result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCodeVariant_WithUnsupportedMember); + result.ValidateIncrementalResult(IncrementalStepRunReason.New, IncrementalStepRunReason.New); + + result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCode); + result.ValidateIncrementalResult(IncrementalStepRunReason.Modified, IncrementalStepRunReason.Modified); + } + + [Fact] + public async Task RunWithDiags_Then_EditWithDiags() + { + ConfigBindingGenTestDriver driver = new ConfigBindingGenTestDriver(); + + ConfigBindingGenRunResult result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCodeVariant_WithUnsupportedMember); + result.ValidateIncrementalResult(IncrementalStepRunReason.New, IncrementalStepRunReason.New); + + result = await driver.RunGeneratorAndUpdateCompilation(BindCallSampleCodeVariant_WithUnsupportedMember_WithDiffMemberName); + result.ValidateIncrementalResult(IncrementalStepRunReason.Modified, IncrementalStepRunReason.Modified); + } + } + + #region Incremental test sources. + /// + /// Keep in sync with . + /// + private const string BindCallSampleCodeVariant_ReorderedInvocations = """ + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfigurationRoot config = configurationBuilder.Build(); + + MyClass configObj = new(); + config.Bind(configObj, options => { }); + config.Bind("key", configObj); + config.Bind(configObj); + } + + public class MyClass + { + public string MyString { get; set; } + public int MyInt { get; set; } + public List MyList { get; set; } + public Dictionary MyDictionary { get; set; } + public Dictionary MyComplexDictionary { get; set; } + } + + public class MyClass2 { } + } + """; + + /// + /// Keep in sync with . + /// + private const string BindCallSampleCodeVariant_ReorderedConfigTypeMembers = """ + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfigurationRoot config = configurationBuilder.Build(); + + MyClass configObj = new(); + config.Bind(configObj, options => { }); + config.Bind("key", configObj); + config.Bind(configObj); + } + + public class MyClass + { + public List MyList { get; set; } + public Dictionary MyDictionary { get; set; } + public string MyString { get; set; } + public int MyInt { get; set; } + public Dictionary MyComplexDictionary { get; set; } + } + + public class MyClass2 { } + } + """; + + /// + /// Keep in sync with . + /// + private const string BindCallSampleCodeVariant_WithDifferentConfigTypeName = """ + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfigurationRoot config = configurationBuilder.Build(); + + MyClass0 configObj = new(); + config.Bind(configObj, options => { }); + config.Bind("key", configObj); + config.Bind(configObj); + } + + public class MyClass0 + { + public List MyList { get; set; } + public Dictionary MyDictionary { get; set; } + public string MyString { get; set; } + public int MyInt { get; set; } + public Dictionary MyComplexDictionary { get; set; } + } + + public class MyClass2 { } + } + """; + + private const string BindCallSampleCodeVariant_WithUnsupportedMember = """ + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfigurationRoot config = configurationBuilder.Build(); + + MyClass configObj = new(); + config.Bind(configObj); + config.Bind(configObj, options => { }); + config.Bind("key", configObj); + } + + public class MyClass + { + public string MyString { get; set; } + public int MyInt { get; set; } + public List MyList { get; set; } + public Dictionary MyDictionary { get; set; } + public Dictionary MyComplexDictionary { get; set; } + public int[,] UnsupportedMember { get; set; } + } + + public class MyClass2 { } + } + """; + + private const string BindCallSampleCodeVariant_WithUnsupportedMember_ReorderedInvocations = """ + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfigurationRoot config = configurationBuilder.Build(); + + MyClass configObj = new(); + config.Bind("key", configObj); + config.Bind(configObj); + config.Bind(configObj, options => { }); + } + + public class MyClass + { + public string MyString { get; set; } + public int MyInt { get; set; } + public List MyList { get; set; } + public Dictionary MyDictionary { get; set; } + public Dictionary MyComplexDictionary { get; set; } + public int[,] UnsupportedMember { get; set; } + } + + public class MyClass2 { } + } + """; + + private const string BindCallSampleCodeVariant_WithUnsupportedMember_ReorderedConfigTypeMembers = """ + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfigurationRoot config = configurationBuilder.Build(); + + MyClass configObj = new(); + config.Bind("key", configObj); + config.Bind(configObj); + config.Bind(configObj, options => { }); + } + + public class MyClass + { + public string MyString { get; set; } + public int MyInt { get; set; } + public int[,] UnsupportedMember { get; set; } + public Dictionary MyDictionary { get; set; } + public Dictionary MyComplexDictionary { get; set; } + public List MyList { get; set; } + } + + public class MyClass2 { } + } + """; + + private const string BindCallSampleCodeVariant_WithUnsupportedMember_WithDiffMemberName = """ + using System.Collections.Generic; + using Microsoft.Extensions.Configuration; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfigurationRoot config = configurationBuilder.Build(); + + MyClass configObj = new(); + config.Bind(configObj); + config.Bind(configObj, options => { }); + config.Bind("key", configObj); + } + + public class MyClass + { + public string MyString { get; set; } + public int MyInt { get; set; } + public List MyList { get; set; } + public Dictionary MyDictionary { get; set; } + public Dictionary MyComplexDictionary { get; set; } + public int[,] UnsupportedMember_DiffMemberName { get; set; } + } + + public class MyClass2 { } + } + """; + #endregion Incremental test sources. + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs index 846e64d904d531..d93607d3763996 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs @@ -27,10 +27,10 @@ public partial class ConfigurationBindingGeneratorTests : ConfigurationBinderTes [InlineData(LanguageVersion.CSharp10)] public async Task LangVersionMustBeCharp12OrHigher(LanguageVersion langVersion) { - var (d, r) = await RunGenerator(BindCallSampleCode, langVersion: langVersion); - Assert.Empty(r); + ConfigBindingGenRunResult result = await RunGeneratorAndUpdateCompilation(BindCallSampleCode, langVersion: langVersion); + Assert.False(result.GeneratedSource.HasValue); - Diagnostic diagnostic = Assert.Single(d); + Diagnostic diagnostic = Assert.Single(result.Diagnostics); Assert.True(diagnostic.Id == "SYSLIB1102"); Assert.Contains("C# 12", diagnostic.Descriptor.Title.ToString(CultureInfo.InvariantCulture)); Assert.Equal(DiagnosticSeverity.Error, diagnostic.Severity); @@ -75,11 +75,11 @@ public record struct MyRecordStruct { } } """; - var (d, r) = await RunGenerator(source); - Assert.Empty(r); - Assert.Equal(7, d.Count()); + ConfigBindingGenRunResult result = await RunGeneratorAndUpdateCompilation(source); + Assert.False(result.GeneratedSource.HasValue); + Assert.Equal(7, result.Diagnostics.Count()); - foreach (Diagnostic diagnostic in d) + foreach (Diagnostic diagnostic in result.Diagnostics) { Assert.True(diagnostic.Id == Diagnostics.ValueTypesInvalidForBind.Id); Assert.Contains(Diagnostics.ValueTypesInvalidForBind.Title, diagnostic.Descriptor.Title.ToString(CultureInfo.InvariantCulture)); @@ -111,11 +111,11 @@ public record struct MyRecordStruct { } } """; - var (d, r) = await RunGenerator(source); - Assert.Empty(r); - Assert.Equal(2, d.Count()); + ConfigBindingGenRunResult result = await RunGeneratorAndUpdateCompilation(source); + Assert.False(result.GeneratedSource.HasValue); + Assert.Equal(2, result.Diagnostics.Count()); - foreach (Diagnostic diagnostic in d) + foreach (Diagnostic diagnostic in result.Diagnostics) { Assert.True(diagnostic.Id == Diagnostics.CouldNotDetermineTypeInfo.Id); Assert.Contains(Diagnostics.CouldNotDetermineTypeInfo.Title, diagnostic.Descriptor.Title.ToString(CultureInfo.InvariantCulture)); @@ -163,11 +163,11 @@ public class MyClass { } } """; - var (d, r) = await RunGenerator(source); - Assert.Empty(r); - Assert.Equal(6, d.Count()); + ConfigBindingGenRunResult result = await RunGeneratorAndUpdateCompilation(source); + Assert.False(result.GeneratedSource.HasValue); + Assert.Equal(6, result.Diagnostics.Count()); - foreach (Diagnostic diagnostic in d) + foreach (Diagnostic diagnostic in result.Diagnostics) { Assert.True(diagnostic.Id == Diagnostics.CouldNotDetermineTypeInfo.Id); Assert.Contains(Diagnostics.CouldNotDetermineTypeInfo.Title, diagnostic.Descriptor.Title.ToString(CultureInfo.InvariantCulture)); @@ -218,22 +218,15 @@ public class MyClass0 { } async Task Test(bool expectOutput) { - var (d, r) = await RunGenerator(source, references: GetFilteredAssemblyRefs(exclusions)); - - Assert.Empty(d); - - if (expectOutput) - { - Assert.Single(r); - } - else - { - Assert.Empty(r); - } + ConfigBindingGenRunResult result = await RunGeneratorAndUpdateCompilation(source, assemblyReferences: GetFilteredAssemblyRefs(exclusions)); + Assert.Empty(result.Diagnostics); + Action ValidateSourceResult = expectOutput ? () => Assert.NotNull(result.GeneratedSource) : () => Assert.False(result.GeneratedSource.HasValue); + ValidateSourceResult(); } } [Fact] + [ActiveIssue("Work out why we aren't getting all the expected diagnostics.")] public async Task IssueDiagnosticsForAllOffendingCallsites() { string source = """ @@ -282,10 +275,10 @@ public class AnotherGraphWithUnsupportedMembers } """; - var (d, r) = await RunGenerator(source, references: GetAssemblyRefsWithAdditional(typeof(ImmutableArray<>), typeof(Encoding), typeof(JsonSerializer))); - Assert.Single(r); - Assert.Equal(47, d.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); - Assert.Equal(44, d.Where(diag => diag.Id == Diagnostics.PropertyNotSupported.Id).Count()); + ConfigBindingGenRunResult result = await RunGeneratorAndUpdateCompilation(source, assemblyReferences: GetAssemblyRefsWithAdditional(typeof(ImmutableArray<>), typeof(Encoding), typeof(JsonSerializer))); + Assert.NotNull(result.GeneratedSource); + Assert.True(result.Diagnostics.Any(diag => diag.Id == Diagnostics.TypeNotSupported.Id)); + Assert.True(result.Diagnostics.Any(diag => diag.Id == Diagnostics.PropertyNotSupported.Id)); } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj index fc8db157eddeea..848d93b32a475a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj @@ -2,8 +2,10 @@ $(NetCoreAppCurrent);$(NetFrameworkMinimum) true - - SYSLIB1100,SYSLIB1101 + + $(NoWarn);SYSLIB1100,SYSLIB1101 + + $(NoWarn);SYSLIB1103,SYSLIB1104 $(Features);InterceptorsPreview $(InterceptorsPreviewNamespaces);Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -22,6 +24,7 @@ + @@ -46,17 +49,16 @@ - + PreserveNewest + + diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj index 1f12dab5b9ac44..e83340eb0eae55 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj @@ -11,7 +11,8 @@ $(InterceptorsPreviewNamespaces);Microsoft.Extensions.Configuration.Binder.SourceGeneration true - true + + $(NoWarn);SYSLIB1100;SYSLIB1101 Console logger provider implementation for Microsoft.Extensions.Logging. diff --git a/src/libraries/System.Text.Json/gen/Helpers/DiagnosticInfo.cs b/src/libraries/System.Text.Json/gen/Helpers/DiagnosticInfo.cs deleted file mode 100644 index 493f79191d4375..00000000000000 --- a/src/libraries/System.Text.Json/gen/Helpers/DiagnosticInfo.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Linq; -using System.Numerics.Hashing; -using Microsoft.CodeAnalysis; - -namespace System.Text.Json.SourceGeneration -{ - /// - /// Descriptor for diagnostic instances using structural equality comparison. - /// Provides a work-around for https://github.com/dotnet/roslyn/issues/68291. - /// - public readonly struct DiagnosticInfo : IEquatable - { - public required DiagnosticDescriptor Descriptor { get; init; } - public required object?[] MessageArgs { get; init; } - public required Location? Location { get; init; } - - public Diagnostic CreateDiagnostic() - => Diagnostic.Create(Descriptor, Location, MessageArgs); - - public override readonly bool Equals(object? obj) => obj is DiagnosticInfo info && Equals(info); - public readonly bool Equals(DiagnosticInfo other) - { - return Descriptor.Equals(other.Descriptor) && - MessageArgs.SequenceEqual(other.MessageArgs) && - Location == other.Location; - } - - public override readonly int GetHashCode() - { - int hashCode = Descriptor.GetHashCode(); - foreach (object? messageArg in MessageArgs) - { - hashCode = HashHelpers.Combine(hashCode, messageArg?.GetHashCode() ?? 0); - } - - hashCode = HashHelpers.Combine(hashCode, Location?.GetHashCode() ?? 0); - return hashCode; - } - } -} diff --git a/src/libraries/System.Text.Json/gen/Helpers/RoslynExtensions.cs b/src/libraries/System.Text.Json/gen/Helpers/RoslynExtensions.cs index 7d280ce7603c2d..3f3ecb506fd83d 100644 --- a/src/libraries/System.Text.Json/gen/Helpers/RoslynExtensions.cs +++ b/src/libraries/System.Text.Json/gen/Helpers/RoslynExtensions.cs @@ -25,8 +25,6 @@ internal static class RoslynExtensions return compilation.GetBestTypeByMetadataName(type.FullName); } - public static string GetFullyQualifiedName(this ITypeSymbol type) => type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); - public static Location? GetLocation(this ISymbol typeSymbol) => typeSymbol.Locations.Length > 0 ? typeSymbol.Locations[0] : null; @@ -36,12 +34,6 @@ internal static class RoslynExtensions return reference?.SyntaxTree.GetLocation(reference.Span); } - /// - /// Creates a copy of the Location instance that does not capture a reference to Compilation. - /// - public static Location GetTrimmedLocation(this Location location) - => Location.Create(location.SourceTree?.FilePath ?? "", location.SourceSpan, location.GetLineSpan().Span); - /// /// Returns true if the specified location is contained in one of the syntax trees in the compilation. /// diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs index 0f3b11b038bc93..e0dac6a9ad82ce 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs @@ -60,12 +60,7 @@ public void ReportDiagnostic(DiagnosticDescriptor descriptor, Location? location location = _contextClassLocation; } - Diagnostics.Add(new DiagnosticInfo - { - Descriptor = descriptor, - Location = location.GetTrimmedLocation(), - MessageArgs = messageArgs ?? Array.Empty(), - }); + Diagnostics.Add(DiagnosticInfo.Create(descriptor, location, messageArgs)); } public Parser(KnownTypeSymbols knownSymbols) diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn3.11.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn3.11.cs index 4c58a3d968ac54..7520f9bc75a6f5 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn3.11.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn3.11.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; +using SourceGenerators; namespace System.Text.Json.SourceGeneration { diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn4.0.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn4.0.cs index e3f8b4aacf6c5b..447f54c7f07821 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn4.0.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn4.0.cs @@ -9,6 +9,7 @@ #if !ROSLYN4_4_OR_GREATER using Microsoft.CodeAnalysis.DotnetRuntime.Extensions; #endif +using SourceGenerators; namespace System.Text.Json.SourceGeneration { diff --git a/src/libraries/System.Text.Json/gen/Model/ContextGenerationSpec.cs b/src/libraries/System.Text.Json/gen/Model/ContextGenerationSpec.cs index 1e2ee2d737e009..00c7192c3ae58c 100644 --- a/src/libraries/System.Text.Json/gen/Model/ContextGenerationSpec.cs +++ b/src/libraries/System.Text.Json/gen/Model/ContextGenerationSpec.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using System.Text.Json.Serialization; +using SourceGenerators; namespace System.Text.Json.SourceGeneration { diff --git a/src/libraries/System.Text.Json/gen/Model/ParameterGenerationSpec.cs b/src/libraries/System.Text.Json/gen/Model/ParameterGenerationSpec.cs index 2945b20b730b15..68e32d01531569 100644 --- a/src/libraries/System.Text.Json/gen/Model/ParameterGenerationSpec.cs +++ b/src/libraries/System.Text.Json/gen/Model/ParameterGenerationSpec.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using SourceGenerators; + namespace System.Text.Json.SourceGeneration { /// diff --git a/src/libraries/System.Text.Json/gen/Model/PropertyGenerationSpec.cs b/src/libraries/System.Text.Json/gen/Model/PropertyGenerationSpec.cs index 56b42970f68893..214c32b4d19e21 100644 --- a/src/libraries/System.Text.Json/gen/Model/PropertyGenerationSpec.cs +++ b/src/libraries/System.Text.Json/gen/Model/PropertyGenerationSpec.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Text.Json.Serialization; +using SourceGenerators; namespace System.Text.Json.SourceGeneration { diff --git a/src/libraries/System.Text.Json/gen/Model/PropertyInitializerGenerationSpec.cs b/src/libraries/System.Text.Json/gen/Model/PropertyInitializerGenerationSpec.cs index 9fc68a11928470..608ce8e887d725 100644 --- a/src/libraries/System.Text.Json/gen/Model/PropertyInitializerGenerationSpec.cs +++ b/src/libraries/System.Text.Json/gen/Model/PropertyInitializerGenerationSpec.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using SourceGenerators; + namespace System.Text.Json.SourceGeneration { /// diff --git a/src/libraries/System.Text.Json/gen/Model/SourceGenerationOptionsSpec.cs b/src/libraries/System.Text.Json/gen/Model/SourceGenerationOptionsSpec.cs index 7e94f824bae8cb..83b587fb962f7e 100644 --- a/src/libraries/System.Text.Json/gen/Model/SourceGenerationOptionsSpec.cs +++ b/src/libraries/System.Text.Json/gen/Model/SourceGenerationOptionsSpec.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Text.Json.Serialization; +using SourceGenerators; namespace System.Text.Json.SourceGeneration { diff --git a/src/libraries/System.Text.Json/gen/Model/TypeGenerationSpec.cs b/src/libraries/System.Text.Json/gen/Model/TypeGenerationSpec.cs index 189295bcb971ca..9b71bf16438b89 100644 --- a/src/libraries/System.Text.Json/gen/Model/TypeGenerationSpec.cs +++ b/src/libraries/System.Text.Json/gen/Model/TypeGenerationSpec.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Text.Json.Serialization; using Microsoft.CodeAnalysis; +using SourceGenerators; namespace System.Text.Json.SourceGeneration { diff --git a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets index 4020a05cb421db..23add6278d7c07 100644 --- a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets +++ b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets @@ -30,8 +30,11 @@ + + + @@ -54,9 +57,7 @@ - - @@ -74,6 +75,5 @@ - diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorIncrementalTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorIncrementalTests.cs index 7a38a7e5fb5128..daa6498cbc9b2d 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorIncrementalTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorIncrementalTests.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Reflection; using Microsoft.CodeAnalysis; +using SourceGenerators.Tests; using Xunit; namespace System.Text.Json.SourceGeneration.UnitTests @@ -29,7 +30,7 @@ public static void CompilingTheSameSourceResultsInEqualModels(Func ContextGenerationSpec ctx2 = result2.ContextGenerationSpecs[i]; Assert.NotSame(ctx1, ctx2); - AssertStructurallyEqual(ctx1, ctx2); + GeneratorTestHelpers.AssertStructurallyEqual(ctx1, ctx2); Assert.Equal(ctx1, ctx2); Assert.Equal(ctx1.GetHashCode(), ctx2.GetHashCode()); @@ -86,7 +87,7 @@ public partial class JsonContext : JsonSerializerContext { } ContextGenerationSpec ctx2 = result2.ContextGenerationSpecs[0]; Assert.NotSame(ctx1, ctx2); - AssertStructurallyEqual(ctx1, ctx2); + GeneratorTestHelpers.AssertStructurallyEqual(ctx1, ctx2); Assert.Equal(ctx1, ctx2); Assert.Equal(ctx1.GetHashCode(), ctx2.GetHashCode()); @@ -377,74 +378,5 @@ public static IEnumerable GetCompilationHelperFactories() .Where(m => m.ReturnType == typeof(Compilation) && m.GetParameters().Length == 0) .Select(m => new object[] { Delegate.CreateDelegate(typeof(Func), m) }); } - - /// - /// Asserts for structural equality, returning a path to the mismatching data when not equal. - /// - private static void AssertStructurallyEqual(T expected, T actual) - { - CheckAreEqualCore(expected, actual, new()); - static void CheckAreEqualCore(object expected, object actual, Stack path) - { - if (expected is null || actual is null) - { - if (expected is not null || actual is not null) - { - FailNotEqual(); - } - - return; - } - - Type type = expected.GetType(); - if (type != actual.GetType()) - { - FailNotEqual(); - return; - } - - if (expected is IEnumerable leftCollection) - { - if (actual is not IEnumerable rightCollection) - { - FailNotEqual(); - return; - } - - object?[] expectedValues = leftCollection.Cast().ToArray(); - object?[] actualValues = rightCollection.Cast().ToArray(); - - for (int i = 0; i < Math.Max(expectedValues.Length, actualValues.Length); i++) - { - object? expectedElement = i < expectedValues.Length ? expectedValues[i] : ""; - object? actualElement = i < actualValues.Length ? actualValues[i] : ""; - - path.Push($"[{i}]"); - CheckAreEqualCore(expectedElement, actualElement, path); - path.Pop(); - } - } - - if (type.GetProperty("EqualityContract", BindingFlags.Instance | BindingFlags.NonPublic, null, returnType: typeof(Type), types: Array.Empty(), null) != null) - { - // Type is a C# record, run pointwise equality comparison. - foreach (PropertyInfo property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) - { - path.Push("." + property.Name); - CheckAreEqualCore(property.GetValue(expected), property.GetValue(actual), path); - path.Pop(); - } - - return; - } - - if (!expected.Equals(actual)) - { - FailNotEqual(); - } - - void FailNotEqual() => Assert.Fail($"Value not equal in ${string.Join("", path.Reverse())}: expected {expected}, but was {actual}."); - } - } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/System.Text.Json.SourceGeneration.Unit.Tests.targets b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/System.Text.Json.SourceGeneration.Unit.Tests.targets index a700b2a9f3a385..56bf105dc1fddf 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/System.Text.Json.SourceGeneration.Unit.Tests.targets +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/System.Text.Json.SourceGeneration.Unit.Tests.targets @@ -12,6 +12,7 @@ + From 2e50c1e87261c61d082b36d0ef6145eb1b652adf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 10:28:26 -0700 Subject: [PATCH 341/783] [release/8.0] [wasm] Endian fix for Webcil (#92495) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [wasm] Endian fix for Webcil 'dotnet new blazorwasm' command failed on s390x and was throwing a not implemented exception The issue was with with the WebCil writer and reader, specific endianness conversions relating to the webcil payload were not implemented for big endian machines. We considered fixing the generic implementation, but there were only two structures in use: WebcilHeader and WebcilSectionHeader, so it was easier to handle them explicitly. * Fix infinite recursion * rename var --------- Co-authored-by: Sanjam Panda Co-authored-by: Aleksey Kliger (λgeek) --- .../Microsoft.NET.WebAssembly.Webcil.csproj | 1 + .../WebcilConverter.cs | 34 +++++++++++------ .../WebcilReader.cs | 37 +++++++++++++++---- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/tasks/Microsoft.NET.WebAssembly.Webcil/Microsoft.NET.WebAssembly.Webcil.csproj b/src/tasks/Microsoft.NET.WebAssembly.Webcil/Microsoft.NET.WebAssembly.Webcil.csproj index c35eb57e80686b..d09ae4a569a598 100644 --- a/src/tasks/Microsoft.NET.WebAssembly.Webcil/Microsoft.NET.WebAssembly.Webcil.csproj +++ b/src/tasks/Microsoft.NET.WebAssembly.Webcil/Microsoft.NET.WebAssembly.Webcil.csproj @@ -16,6 +16,7 @@ + diff --git a/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs b/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs index a38af7270a2dad..13c34bde4b8ea1 100644 --- a/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs +++ b/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Buffers.Binary; using System.IO; using System.Collections.Immutable; using System.Reflection.PortableExecutable; @@ -174,16 +175,23 @@ public unsafe void GatherInfo(PEReader peReader, out WCFileInfo wcInfo, out PEFi SectionStart: firstWCSection); } - private static void WriteHeader(Stream s, WebcilHeader header) + private static void WriteHeader(Stream s, WebcilHeader webcilHeader) { - WriteStructure(s, header); + if (!BitConverter.IsLittleEndian) + { + webcilHeader.version_major = BinaryPrimitives.ReverseEndianness(webcilHeader.version_major); + webcilHeader.version_minor = BinaryPrimitives.ReverseEndianness(webcilHeader.version_minor); + webcilHeader.coff_sections = BinaryPrimitives.ReverseEndianness(webcilHeader.coff_sections); + webcilHeader.pe_cli_header_rva = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_cli_header_rva); + webcilHeader.pe_cli_header_size = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_cli_header_size); + webcilHeader.pe_debug_rva = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_debug_rva); + webcilHeader.pe_debug_size = BinaryPrimitives.ReverseEndianness(webcilHeader.pe_debug_size); + } + WriteStructure(s, webcilHeader); } private static void WriteSectionHeaders(Stream s, ImmutableArray sectionsHeaders) { - // FIXME: fixup endianness - if (!BitConverter.IsLittleEndian) - throw new NotImplementedException(); foreach (var sectionHeader in sectionsHeaders) { WriteSectionHeader(s, sectionHeader); @@ -192,6 +200,16 @@ private static void WriteSectionHeaders(Stream s, ImmutableArray(Stream s, T structure) where T : unmanaged { - // FIXME: fixup endianness - if (!BitConverter.IsLittleEndian) - throw new NotImplementedException(); unsafe { byte* p = (byte*)&structure; @@ -212,9 +227,6 @@ private static void WriteStructure(Stream s, T structure) private static void WriteStructure(Stream s, T structure) where T : unmanaged { - // FIXME: fixup endianness - if (!BitConverter.IsLittleEndian) - throw new NotImplementedException(); int size = Marshal.SizeOf(); byte[] buffer = new byte[size]; IntPtr ptr = IntPtr.Zero; diff --git a/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilReader.cs b/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilReader.cs index 4f42f827986643..ac4f9d86095a90 100644 --- a/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilReader.cs +++ b/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilReader.cs @@ -6,7 +6,7 @@ using System.IO; using System.Reflection; using System.Runtime.InteropServices; - +using System.Buffers.Binary; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; @@ -63,14 +63,20 @@ private unsafe bool ReadHeader() { return false; } - if (!BitConverter.IsLittleEndian) - { - throw new NotImplementedException("TODO: implement big endian support"); - } fixed (byte* p = buffer) { header = *(WebcilHeader*)p; } + if (!BitConverter.IsLittleEndian) + { + header.version_major = BinaryPrimitives.ReverseEndianness(header.version_major); + header.version_minor = BinaryPrimitives.ReverseEndianness(header.version_minor); + header.coff_sections = BinaryPrimitives.ReverseEndianness(header.coff_sections); + header.pe_cli_header_rva = BinaryPrimitives.ReverseEndianness(header.pe_cli_header_rva); + header.pe_cli_header_size = BinaryPrimitives.ReverseEndianness(header.pe_cli_header_size); + header.pe_debug_rva = BinaryPrimitives.ReverseEndianness(header.pe_debug_rva); + header.pe_debug_rva = BinaryPrimitives.ReverseEndianness(header.pe_debug_size); + } if (header.id[0] != 'W' || header.id[1] != 'b' || header.id[2] != 'I' || header.id[3] != 'L' || header.version_major != Internal.Constants.WC_VERSION_MAJOR @@ -346,6 +352,7 @@ private long TranslateRVA(uint rva) private unsafe ImmutableArray ReadSections() { + WebcilSectionHeader secheader; var sections = ImmutableArray.CreateBuilder(_header.coff_sections); var buffer = new byte[Marshal.SizeOf()]; _stream.Seek(SectionDirectoryOffset + _webcilInWasmOffset, SeekOrigin.Begin); @@ -357,8 +364,24 @@ private unsafe ImmutableArray ReadSections() } fixed (byte* p = buffer) { - // FIXME endianness - sections.Add(*(WebcilSectionHeader*)p); + secheader = (*(WebcilSectionHeader*)p); + } + if (!BitConverter.IsLittleEndian) + { + sections.Add + ( + new WebcilSectionHeader + ( + virtualSize: BinaryPrimitives.ReverseEndianness(secheader.VirtualSize), + virtualAddress: BinaryPrimitives.ReverseEndianness(secheader.VirtualAddress), + sizeOfRawData: BinaryPrimitives.ReverseEndianness(secheader.SizeOfRawData), + pointerToRawData: BinaryPrimitives.ReverseEndianness(secheader.PointerToRawData) + ) + ); + } + else + { + sections.Add(secheader); } } return sections.MoveToImmutable(); From dedfe8e49ac0d0a2a817da5be0f84357acbe6454 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 10:30:29 -0700 Subject: [PATCH 342/783] Update dependencies from https://github.com/dotnet/source-build-externals build 20231002.1 (#92935) Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.23475.1 -> To Version 8.0.0-alpha.1.23502.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1f220ede26d087..12cfc3ce525f94 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -100,9 +100,9 @@ 7b55da982fc6e71c1776c4de89111aee0eecb45a - + https://github.com/dotnet/source-build-externals - e04156dbe14f882a80d4499dbebd45ab156b6c3c + ed17956dbc31097b7ba6a66be086f4a70a97d84f From a7c94198273b091f02b89e98073e24ae3a0c5b58 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 10:30:41 -0700 Subject: [PATCH 343/783] [release/8.0] Update dependencies from dotnet/cecil dotnet/hotreload-utils (#92932) * Update dependencies from https://github.com/dotnet/cecil build 20231002.1 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23476.1 -> To Version 0.11.4-alpha.23502.1 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20231002.1 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23475.1 -> To Version 8.0.0-alpha.0.23502.1 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 12cfc3ce525f94..9c18388aa5346d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -85,9 +85,9 @@ 02fe27cd6a9b001c8feb7938e6ef4b3799745759b - + https://github.com/dotnet/cecil - 13d6536e2dc92404da76d61d248badc040eb0de0 + 64a8874f3c485657e732ca56a5f24e2095740103 @@ -350,9 +350,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 492f7464d31d9599531fab2a67bc2422046f5133 - + https://github.com/dotnet/hotreload-utils - 6c20c1d568568b9b2da84f878ac9cb4a48aaa4e5 + 94979ba9c2904e39ddb9aa255a288caacd6ce166 https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index 1663485ec06805..ef9555ba255cbe 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -186,7 +186,7 @@ 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 - 8.0.0-alpha.0.23475.1 + 8.0.0-alpha.0.23502.1 2.4.2 1.0.0 2.4.5 @@ -213,7 +213,7 @@ 8.0.0-rc.1.23406.6 - 0.11.4-alpha.23476.1 + 0.11.4-alpha.23502.1 8.0.0-rc.1.23406.6 From 0eeb6b268afa56fc173264b9905e8287a681db64 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 3 Oct 2023 15:42:56 -0400 Subject: [PATCH 344/783] [release/8.0][wasm] Use intended ports when running `DevServer` (#92906) * [wasm] Ignore empty `$ASPNETCORE_URLS` * [wasm] DevServer: honor urls specified in the options * [wasm] CI: Don't trigger non-wbt jobs on wasm-app-host changes * CI: don't trigger wasm runtime tests on wasm-app-host changes * [wasm] wasmbrowser - change the default webserver port to 0, to randomly select a port --- eng/pipelines/common/evaluate-default-paths.yml | 2 ++ src/mono/wasm/host/BrowserHost.cs | 2 +- src/mono/wasm/host/DevServer/DevServer.cs | 3 ++- src/mono/wasm/host/RuntimeConfigJson.cs | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/eng/pipelines/common/evaluate-default-paths.yml b/eng/pipelines/common/evaluate-default-paths.yml index 5fb74a3741f413..0e4279a9697b94 100644 --- a/eng/pipelines/common/evaluate-default-paths.yml +++ b/eng/pipelines/common/evaluate-default-paths.yml @@ -241,6 +241,7 @@ jobs: - src/mono/tools/* - src/mono/wasi/* - src/mono/wasm/debugger/* + - src/mono/wasm/host/* - src/mono/wasm/Wasm.Build.Tests/* - ${{ parameters._const_paths._wasm_pipelines }} - ${{ parameters._const_paths._always_exclude }} @@ -258,6 +259,7 @@ jobs: - eng/testing/workloads-testing.targets - src/mono/mono/component/mini-wasm-debugger.c - src/mono/wasm/debugger/* + - src/mono/wasm/host/* - src/mono/wasm/Wasm.Build.Tests/* - src/mono/nuget/Microsoft.NET.Runtime* src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/* diff --git a/src/mono/wasm/host/BrowserHost.cs b/src/mono/wasm/host/BrowserHost.cs index adb24f81f88dac..cbe160eeb0214a 100644 --- a/src/mono/wasm/host/BrowserHost.cs +++ b/src/mono/wasm/host/BrowserHost.cs @@ -74,7 +74,7 @@ private async Task RunAsync(ILoggerFactory loggerFactory, CancellationToken toke debugging: _args.CommonConfig.Debugging); runArgsJson.Save(Path.Combine(_args.CommonConfig.AppPath, "runArgs.json")); - string[] urls = envVars.TryGetValue("ASPNETCORE_URLS", out string? aspnetUrls) + string[] urls = (envVars.TryGetValue("ASPNETCORE_URLS", out string? aspnetUrls) && aspnetUrls.Length > 0) ? aspnetUrls.Split(';', StringSplitOptions.RemoveEmptyEntries) : new string[] { $"http://127.0.0.1:{_args.CommonConfig.HostProperties.WebServerPort}", "https://127.0.0.1:0" }; diff --git a/src/mono/wasm/host/DevServer/DevServer.cs b/src/mono/wasm/host/DevServer/DevServer.cs index 1acbe6954eeb3b..9a5a079cee695e 100644 --- a/src/mono/wasm/host/DevServer/DevServer.cs +++ b/src/mono/wasm/host/DevServer/DevServer.cs @@ -46,7 +46,8 @@ internal static class DevServer services.AddSingleton(Options.Create(options)); services.AddSingleton(realUrlsAvailableTcs); services.AddRouting(); - }); + }) + .UseUrls(options.Urls); IWebHost? host = builder.Build(); diff --git a/src/mono/wasm/host/RuntimeConfigJson.cs b/src/mono/wasm/host/RuntimeConfigJson.cs index ed698ed8fb3725..3ad30dd88015ae 100644 --- a/src/mono/wasm/host/RuntimeConfigJson.cs +++ b/src/mono/wasm/host/RuntimeConfigJson.cs @@ -24,7 +24,7 @@ internal sealed record WasmHostProperties( int? FirefoxDebuggingPort, int? ChromeProxyPort, int? ChromeDebuggingPort, - int WebServerPort = 9000) + int WebServerPort = 0) { // using an explicit property because the deserializer doesn't like // extension data in the record constructor From 937cfcdf13fdc5a8833807b49db4137a7970925e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 12:45:25 -0700 Subject: [PATCH 345/783] Update EventPipeEventDispatcher.cs (#92912) Co-authored-by: David Mason --- .../Tracing/EventPipeEventDispatcher.cs | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventDispatcher.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventDispatcher.cs index 708c5afc1bc70e..030560b2002145 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventDispatcher.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventDispatcher.cs @@ -103,8 +103,8 @@ private void CommitDispatchConfiguration() new EventPipeProviderConfiguration(NativeRuntimeEventSource.EventSourceName, (ulong)aggregatedKeywords, (uint)enableLevel, null) }; - m_sessionID = EventPipeInternal.Enable(null, EventPipeSerializationFormat.NetTrace, DefaultEventListenerCircularMBSize, providerConfiguration); - if (m_sessionID == 0) + ulong sessionID = EventPipeInternal.Enable(null, EventPipeSerializationFormat.NetTrace, DefaultEventListenerCircularMBSize, providerConfiguration); + if (sessionID == 0) { throw new EventSourceException(SR.EventSource_CouldNotEnableEventPipe); } @@ -113,7 +113,7 @@ private void CommitDispatchConfiguration() EventPipeSessionInfo sessionInfo; unsafe { - if (!EventPipeInternal.GetSessionInfo(m_sessionID, &sessionInfo)) + if (!EventPipeInternal.GetSessionInfo(sessionID, &sessionInfo)) { Debug.Fail("GetSessionInfo returned false."); } @@ -124,8 +124,11 @@ private void CommitDispatchConfiguration() long syncTimeQPC = sessionInfo.StartTimeStamp; long timeQPCFrequency = sessionInfo.TimeStampFrequency; + Debug.Assert(Volatile.Read(ref m_sessionID) == 0); + Volatile.Write(ref m_sessionID, sessionID); + // Start the dispatch task. - StartDispatchTask(m_sessionID, syncTimeUtc, syncTimeQPC, timeQPCFrequency); + StartDispatchTask(sessionID, syncTimeUtc, syncTimeQPC, timeQPCFrequency); } private void StartDispatchTask(ulong sessionID, DateTime syncTimeUtc, long syncTimeQPC, long timeQPCFrequency) @@ -147,10 +150,11 @@ private void SetStopDispatchTask() return; } - Debug.Assert(m_sessionID != 0); + ulong sessionID = Volatile.Read(ref m_sessionID); + Debug.Assert(sessionID != 0); m_dispatchTaskCancellationSource.Cancel(); - EventPipeInternal.SignalSession(m_sessionID); - m_sessionID = 0; + EventPipeInternal.SignalSession(sessionID); + Volatile.Write(ref m_sessionID, 0); } private unsafe void DispatchEventsToEventListeners(ulong sessionID, DateTime syncTimeUtc, long syncTimeQPC, long timeQPCFrequency, Task? previousDispatchTask, CancellationToken token) @@ -190,12 +194,17 @@ private unsafe void DispatchEventsToEventListeners(ulong sessionID, DateTime syn } } - lock (m_dispatchControlLock) + // Wait for SignalSession() to be called before we call disable, otherwise + // the SignalSession() call could be on a disabled session. + SpinWait sw = default; + while (Volatile.Read(ref m_sessionID) == sessionID) { - // Disable the old session. This can happen asynchronously since we aren't using the old session - // anymore. We take the lock to make sure we don't call SignalSession on an invalid session ID. - EventPipeInternal.Disable(sessionID); + sw.SpinOnce(); } + + // Disable the old session. This can happen asynchronously since we aren't using the old session + // anymore. + EventPipeInternal.Disable(sessionID); } /// From a84f8ffbf5d597b8a91e893a1f413466de017a68 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 3 Oct 2023 21:28:29 -0400 Subject: [PATCH 346/783] CI: runtime-wasm-perf: disable for PRs (#92977) --- eng/pipelines/runtime-wasm-perf.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/pipelines/runtime-wasm-perf.yml b/eng/pipelines/runtime-wasm-perf.yml index bd6a6d979e3e40..69039fb3e2a473 100644 --- a/eng/pipelines/runtime-wasm-perf.yml +++ b/eng/pipelines/runtime-wasm-perf.yml @@ -3,6 +3,7 @@ # UI to this, and thus avoid any scheduled triggers trigger: none +pr: none variables: - template: /eng/pipelines/common/variables.yml From 1954c378cef9d701156b45423494fd4936803e2a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 18:37:55 -0700 Subject: [PATCH 347/783] Throw NotSupportedException when applying JsonObjectHandling.Populate on types with parameterized constructors. (#92947) Co-authored-by: Eirik Tsarpalis --- .../src/Resources/Strings.resx | 3 ++ ...ctWithParameterizedConstructorConverter.cs | 4 +- .../DefaultJsonTypeInfoResolver.Helpers.cs | 16 +++++-- .../Metadata/JsonPropertyInfo.cs | 34 +++++++++---- .../Metadata/JsonTypeInfo.Cache.cs | 8 ++++ .../Serialization/Metadata/JsonTypeInfo.cs | 25 +++++----- .../Text/Json/Serialization/ReadStack.cs | 6 +-- .../Text/Json/ThrowHelper.Serialization.cs | 6 +++ .../JsonCreationHandlingTests.Object.cs | 48 +++++++++++++++++++ .../JsonCreationHandlingTests.cs | 3 ++ ...tJsonTypeInfoResolverTests.JsonTypeInfo.cs | 5 +- 11 files changed, 125 insertions(+), 33 deletions(-) diff --git a/src/libraries/System.Text.Json/src/Resources/Strings.resx b/src/libraries/System.Text.Json/src/Resources/Strings.resx index f091984783b601..0ebab3e5d27d6f 100644 --- a/src/libraries/System.Text.Json/src/Resources/Strings.resx +++ b/src/libraries/System.Text.Json/src/Resources/Strings.resx @@ -696,6 +696,9 @@ JsonObjectCreationHandling.Populate is incompatible with reference handling. + + JsonObjectCreationHandling.Populate is currently not supported in types with parameterized constructors. + Either the JSON value is not in a supported format, or is out of bounds for an Int128. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs index 304ca0a26e409c..7c5d6aae1c4051 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs @@ -25,10 +25,10 @@ internal sealed override bool OnTryRead(ref Utf8JsonReader reader, Type typeToCo { JsonTypeInfo jsonTypeInfo = state.Current.JsonTypeInfo; - if (jsonTypeInfo.CreateObject != null || state.Current.IsPopulating) + if (!jsonTypeInfo.UsesParameterizedConstructor || state.Current.IsPopulating) { // Fall back to default object converter in following cases: - // - if user has set a default constructor delegate with contract customization + // - if user configuration has invalidated the parameterized constructor // - we're continuing populating an object. return base.OnTryRead(ref reader, typeToConvert, options, ref state, out value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs index 8ee9f3db0283b4..c654a920f8ff6e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs @@ -38,12 +38,20 @@ internal static MemberAccessor MemberAccessor private static JsonTypeInfo CreateTypeInfoCore(Type type, JsonConverter converter, JsonSerializerOptions options) { JsonTypeInfo typeInfo = JsonTypeInfo.CreateJsonTypeInfo(type, converter, options); - typeInfo.NumberHandling = GetNumberHandlingForType(typeInfo.Type); - typeInfo.PreferredPropertyObjectCreationHandling = GetObjectCreationHandlingForType(typeInfo.Type); - if (typeInfo.Kind == JsonTypeInfoKind.Object) + if (GetNumberHandlingForType(typeInfo.Type) is { } numberHandling) { - typeInfo.UnmappedMemberHandling = GetUnmappedMemberHandling(typeInfo.Type); + typeInfo.NumberHandling = numberHandling; + } + + if (GetObjectCreationHandlingForType(typeInfo.Type) is { } creationHandling) + { + typeInfo.PreferredPropertyObjectCreationHandling = creationHandling; + } + + if (GetUnmappedMemberHandling(typeInfo.Type) is { } unmappedMemberHandling) + { + typeInfo.UnmappedMemberHandling = unmappedMemberHandling; } typeInfo.PopulatePolymorphismMetadata(); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfo.cs index 0ab5c08d7825b3..e2234093474e0d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfo.cs @@ -495,9 +495,17 @@ private void DetermineEffectiveObjectCreationHandlingForProperty() Debug.Assert(ParentTypeInfo != null, "We should have ensured parent is assigned in JsonTypeInfo"); Debug.Assert(!IsConfigured, "Should not be called post-configuration."); + JsonObjectCreationHandling effectiveObjectCreationHandling = JsonObjectCreationHandling.Replace; if (ObjectCreationHandling == null) { - JsonObjectCreationHandling preferredCreationHandling = ParentTypeInfo.PreferredPropertyObjectCreationHandling ?? Options.PreferredObjectCreationHandling; + // Consult type-level configuration, then global configuration. + // Ignore global configuration if we're using a parameterized constructor. + JsonObjectCreationHandling preferredCreationHandling = + ParentTypeInfo.PreferredPropertyObjectCreationHandling + ?? (ParentTypeInfo.DetermineUsesParameterizedConstructor() + ? JsonObjectCreationHandling.Replace + : Options.PreferredObjectCreationHandling); + bool canPopulate = preferredCreationHandling == JsonObjectCreationHandling.Populate && EffectiveConverter.CanPopulate && @@ -506,7 +514,7 @@ private void DetermineEffectiveObjectCreationHandlingForProperty() !ParentTypeInfo.SupportsPolymorphicDeserialization && !(Set == null && IgnoreReadOnlyMember); - EffectiveObjectCreationHandling = canPopulate ? JsonObjectCreationHandling.Populate : JsonObjectCreationHandling.Replace; + effectiveObjectCreationHandling = canPopulate ? JsonObjectCreationHandling.Populate : JsonObjectCreationHandling.Replace; } else if (ObjectCreationHandling == JsonObjectCreationHandling.Populate) { @@ -537,18 +545,24 @@ private void DetermineEffectiveObjectCreationHandlingForProperty() ThrowHelper.ThrowInvalidOperationException_ObjectCreationHandlingPropertyCannotAllowReadOnlyMember(this); } - EffectiveObjectCreationHandling = JsonObjectCreationHandling.Populate; - } - else - { - Debug.Assert(EffectiveObjectCreationHandling == JsonObjectCreationHandling.Replace); + effectiveObjectCreationHandling = JsonObjectCreationHandling.Populate; } - if (EffectiveObjectCreationHandling == JsonObjectCreationHandling.Populate && - Options.ReferenceHandlingStrategy != ReferenceHandlingStrategy.None) + if (effectiveObjectCreationHandling is JsonObjectCreationHandling.Populate) { - ThrowHelper.ThrowInvalidOperationException_ObjectCreationHandlingPropertyCannotAllowReferenceHandling(); + if (ParentTypeInfo.DetermineUsesParameterizedConstructor()) + { + ThrowHelper.ThrowNotSupportedException_ObjectCreationHandlingPropertyDoesNotSupportParameterizedConstructors(); + } + + if (Options.ReferenceHandlingStrategy != ReferenceHandlingStrategy.None) + { + ThrowHelper.ThrowInvalidOperationException_ObjectCreationHandlingPropertyCannotAllowReferenceHandling(); + } } + + // Validation complete, commit configuration. + EffectiveObjectCreationHandling = effectiveObjectCreationHandling; } private bool NumberHandingIsApplicable() diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.Cache.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.Cache.cs index 86a7af256a78a8..5a901fbb80eae6 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.Cache.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.Cache.cs @@ -35,6 +35,14 @@ public abstract partial class JsonTypeInfo // All of the serializable parameters on a POCO constructor keyed on parameter name. // Only parameters which bind to properties are cached. internal JsonPropertyDictionary? ParameterCache { get; private set; } + internal bool UsesParameterizedConstructor + { + get + { + Debug.Assert(IsConfigured); + return ParameterCache != null; + } + } // All of the serializable properties on a POCO (except the optional extension property) keyed on property name. internal JsonPropertyDictionary? PropertyCache { get; private set; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs index b9e9fe60d2b23f..a1a184f6059d2b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs @@ -552,17 +552,14 @@ public JsonObjectCreationHandling? PreferredPropertyObjectCreationHandling { VerifyMutable(); - if (value is not null) + if (Kind != JsonTypeInfoKind.Object) { - if (Kind != JsonTypeInfoKind.Object) - { - ThrowHelper.ThrowInvalidOperationException_JsonTypeInfoOperationNotPossibleForKind(Kind); - } + ThrowHelper.ThrowInvalidOperationException_JsonTypeInfoOperationNotPossibleForKind(Kind); + } - if (!JsonSerializer.IsValidCreationHandlingValue(value.Value)) - { - throw new ArgumentOutOfRangeException(nameof(value)); - } + if (value is not null && !JsonSerializer.IsValidCreationHandlingValue(value.Value)) + { + throw new ArgumentOutOfRangeException(nameof(value)); } _preferredPropertyObjectCreationHandling = value; @@ -684,7 +681,7 @@ private void Configure() { ConfigureProperties(); - if (Converter.ConstructorIsParameterized) + if (DetermineUsesParameterizedConstructor()) { ConfigureConstructorParameters(); } @@ -808,6 +805,12 @@ bool IsCurrentNodeCompatible() /// private bool IsCompatibleWithCurrentOptions { get; set; } = true; + /// + /// Determine if the current configuration is compatible with using a parameterized constructor. + /// + internal bool DetermineUsesParameterizedConstructor() + => Converter.ConstructorIsParameterized && CreateObject is null; + #if DEBUG internal string GetPropertyDebugInfo(ReadOnlySpan unescapedPropertyName) { @@ -1107,7 +1110,7 @@ internal void ConfigureProperties() internal void ConfigureConstructorParameters() { Debug.Assert(Kind == JsonTypeInfoKind.Object); - Debug.Assert(Converter.ConstructorIsParameterized); + Debug.Assert(DetermineUsesParameterizedConstructor()); Debug.Assert(PropertyCache is not null); Debug.Assert(ParameterCache is null); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs index 59a47bc3ac7bc6..25c067cc10930a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs @@ -386,20 +386,20 @@ public JsonTypeInfo GetTopJsonTypeInfoWithParameterizedConstructor() for (int i = 0; i < _count - 1; i++) { - if (_stack[i].JsonTypeInfo.Converter.ConstructorIsParameterized) + if (_stack[i].JsonTypeInfo.UsesParameterizedConstructor) { return _stack[i].JsonTypeInfo; } } - Debug.Assert(Current.JsonTypeInfo.Converter.ConstructorIsParameterized); + Debug.Assert(Current.JsonTypeInfo.UsesParameterizedConstructor); return Current.JsonTypeInfo; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void SetConstructorArgumentState() { - if (Current.JsonTypeInfo.Converter.ConstructorIsParameterized) + if (Current.JsonTypeInfo.UsesParameterizedConstructor) { Current.CtorArgumentState ??= new(); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs index 7072d9e3020085..5b05ff243a80a9 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs @@ -99,6 +99,12 @@ public static void ThrowInvalidOperationException_ObjectCreationHandlingProperty throw new InvalidOperationException(SR.ObjectCreationHandlingPropertyCannotAllowReferenceHandling); } + [DoesNotReturn] + public static void ThrowNotSupportedException_ObjectCreationHandlingPropertyDoesNotSupportParameterizedConstructors() + { + throw new NotSupportedException(SR.ObjectCreationHandlingPropertyDoesNotSupportParameterizedConstructors); + } + [DoesNotReturn] public static void ThrowJsonException_SerializationConverterRead(JsonConverter? converter) { diff --git a/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Object.cs b/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Object.cs index aae9da6b2c628b..e25adffef53fa2 100644 --- a/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Object.cs +++ b/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Object.cs @@ -1165,4 +1165,52 @@ public class ClassWithInvalidPropertyAnnotation [JsonObjectCreationHandling((JsonObjectCreationHandling)(-1))] public List Property { get; } } + + [Theory] + [InlineData(typeof(ClassWithParameterizedConstructorWithPopulateProperty))] + [InlineData(typeof(ClassWithParameterizedConstructorWithPopulateType))] + public async Task ClassWithParameterizedCtor_UsingPopulateConfiguration_ThrowsNotSupportedException(Type type) + { + object instance = Activator.CreateInstance(type, "Jim"); + string json = """{"Username":"Jim","PhoneNumbers":["123456"]}"""; + + await Assert.ThrowsAsync(() => Serializer.SerializeWrapper(instance, type)); + await Assert.ThrowsAsync(() => Serializer.DeserializeWrapper(json, type)); + Assert.Throws(() => Serializer.GetTypeInfo(type)); + } + + public class ClassWithParameterizedConstructorWithPopulateProperty(string name) + { + public string Name { get; } = name; + + [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] + public List PhoneNumbers { get; } = new(); + } + + [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] + public class ClassWithParameterizedConstructorWithPopulateType(string name) + { + public string Name { get; } = name; + + public List PhoneNumbers { get; } = new(); + } + + [Fact] + public async Task ClassWithParameterizedCtor_NoPopulateConfiguration_WorksWithGlobalPopulateConfiguration() + { + string json = """{"Username":"Jim","PhoneNumbers":["123456"]}"""; + + JsonSerializerOptions options = Serializer.CreateOptions(makeReadOnly: false); + options.PreferredObjectCreationHandling = JsonObjectCreationHandling.Populate; + + ClassWithParameterizedConstructorNoPopulate result = await Serializer.DeserializeWrapper(json, options); + Assert.Empty(result.PhoneNumbers); + } + + public class ClassWithParameterizedConstructorNoPopulate(string name) + { + public string Name { get; } = name; + + public List PhoneNumbers { get; } = new(); + } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonCreationHandlingTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonCreationHandlingTests.cs index eab6f939b93674..5862387200f6a4 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonCreationHandlingTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonCreationHandlingTests.cs @@ -278,6 +278,9 @@ public sealed class JsonCreationHandlingTests_AsyncStreamWithSmallBuffer() [JsonSerializable(typeof(SimpleClassWitNonPopulatableProperty))] [JsonSerializable(typeof(ClassWithInvalidTypeAnnotation))] [JsonSerializable(typeof(ClassWithInvalidPropertyAnnotation))] + [JsonSerializable(typeof(ClassWithParameterizedConstructorWithPopulateProperty))] + [JsonSerializable(typeof(ClassWithParameterizedConstructorWithPopulateType))] + [JsonSerializable(typeof(ClassWithParameterizedConstructorNoPopulate))] internal partial class CreationHandlingTestContext : JsonSerializerContext { } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonTypeInfo.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonTypeInfo.cs index 06fd59bae037e9..bc6e3a28ff78f7 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonTypeInfo.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonTypeInfo.cs @@ -1440,11 +1440,10 @@ public static void PreferredPropertyObjectCreationHandling_NonObjectKind_ThrowsI { JsonTypeInfo jsonTypeInfo = JsonTypeInfo.CreateJsonTypeInfo(type, new()); - // Invalid kinds default to null and can be set to null. - Assert.Null(jsonTypeInfo.PreferredPropertyObjectCreationHandling); - jsonTypeInfo.PreferredPropertyObjectCreationHandling = null; + // Invalid kinds default to null. Assert.Null(jsonTypeInfo.PreferredPropertyObjectCreationHandling); + Assert.Throws(() => jsonTypeInfo.PreferredPropertyObjectCreationHandling = null); Assert.Throws(() => jsonTypeInfo.PreferredPropertyObjectCreationHandling = JsonObjectCreationHandling.Populate); Assert.Throws(() => jsonTypeInfo.PreferredPropertyObjectCreationHandling = JsonObjectCreationHandling.Replace); Assert.Null(jsonTypeInfo.PreferredPropertyObjectCreationHandling); From 8a66d7d91bcec7e956d53ae65a83515a6b54ee41 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Oct 2023 08:55:42 -0700 Subject: [PATCH 348/783] [release/8.0] Use invariant culture in CBOR date encoding (#92924) * Use invariant culture for CBOR tests * Update src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Reader/CborReader.Tag.cs * Add testing for #92539. --------- Co-authored-by: Filip Navara Co-authored-by: Filip Navara Co-authored-by: Eirik Tsarpalis --- .../Formats/Cbor/Reader/CborReader.Tag.cs | 2 +- .../Formats/Cbor/Writer/CborWriter.Tag.cs | 5 ++-- .../tests/Reader/CborReaderTests.Tag.cs | 29 +++++++++++++++++++ .../tests/System.Formats.Cbor.Tests.csproj | 3 +- .../tests/Writer/CborWriterTests.Tag.cs | 27 +++++++++++++++++ 5 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Reader/CborReader.Tag.cs b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Reader/CborReader.Tag.cs index 238217856c1905..2dd4c4d1d9abe1 100644 --- a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Reader/CborReader.Tag.cs +++ b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Reader/CborReader.Tag.cs @@ -72,7 +72,7 @@ public DateTimeOffset ReadDateTimeOffset() string dateString = ReadTextString(); // TODO determine if conformance modes should allow inexact date sting parsing - if (!DateTimeOffset.TryParseExact(dateString, CborWriter.Rfc3339FormatString, null, DateTimeStyles.RoundtripKind, out DateTimeOffset result)) + if (!DateTimeOffset.TryParseExact(dateString, CborWriter.Rfc3339FormatString, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out DateTimeOffset result)) { throw new CborContentException(SR.Cbor_Reader_InvalidDateTimeEncoding); } diff --git a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Tag.cs b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Tag.cs index e5e772dcfd1be5..3ca04f085e04c0 100644 --- a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Tag.cs +++ b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Tag.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Globalization; using System.Numerics; namespace System.Formats.Cbor @@ -42,8 +43,8 @@ public void WriteDateTimeOffset(DateTimeOffset value) #else value.Offset == TimeSpan.Zero ? #endif // NET8_0_OR_GREATER - value.UtcDateTime.ToString(Rfc3339FormatString) : // prefer 'Z' over '+00:00' - value.ToString(Rfc3339FormatString); + value.UtcDateTime.ToString(Rfc3339FormatString, CultureInfo.InvariantCulture) : // prefer 'Z' over '+00:00' + value.ToString(Rfc3339FormatString, CultureInfo.InvariantCulture); WriteTag(CborTag.DateTimeString); WriteTextString(dateString); diff --git a/src/libraries/System.Formats.Cbor/tests/Reader/CborReaderTests.Tag.cs b/src/libraries/System.Formats.Cbor/tests/Reader/CborReaderTests.Tag.cs index af9adfbe67b500..c6fba6d2a3981c 100644 --- a/src/libraries/System.Formats.Cbor/tests/Reader/CborReaderTests.Tag.cs +++ b/src/libraries/System.Formats.Cbor/tests/Reader/CborReaderTests.Tag.cs @@ -2,8 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Numerics; +using System.Threading; +using Microsoft.DotNet.RemoteExecutor; using Test.Cryptography; using Xunit; @@ -192,6 +195,31 @@ public static void ReadDateTimeOffset_SingleValue_HappyPath(string expectedValue Assert.Equal(expectedValue.Offset, result.Offset); } + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public static void ReadDateTimeOffset_IsCultureInvariant() + { + // Regression test for https://github.com/dotnet/runtime/pull/92539 + RemoteExecutor.Invoke(static () => + { + DateTimeOffset expectedValue = DateTimeOffset.Parse("2020-04-09T14:31:21.3535941+01:00", CultureInfo.InvariantCulture); + byte[] data = "c07821323032302d30342d30395431343a33313a32312e333533353934312b30313a3030".HexToByteArray(); + + // Install a non-Gregorian calendar + var culture = new CultureInfo("he-IL"); + culture.DateTimeFormat.Calendar = new HebrewCalendar(); + Thread.CurrentThread.CurrentCulture = culture; + + var reader = new CborReader(data); + + DateTimeOffset result = reader.ReadDateTimeOffset(); + + Assert.Equal(CborReaderState.Finished, reader.PeekState()); + Assert.Equal(expectedValue, result); + Assert.Equal(expectedValue.Offset, result.Offset); + }).Dispose(); + } + [Theory] [InlineData("c01a514b67b0")] // string datetime tag with unix time payload public static void ReadDateTimeOffset_InvalidTagPayload_ShouldThrowCborContentException(string hexEncoding) @@ -206,6 +234,7 @@ public static void ReadDateTimeOffset_InvalidTagPayload_ShouldThrowCborContentEx [Theory] [InlineData("c07330392f30342f323032302031393a35313a3530")] // 0("09/04/2020 19:51:50") [InlineData("c06e4c617374204368726973746d6173")] // 0("Last Christmas") + [InlineData("c07828d7aad7a922d7a42dd796272dd79822d7955431343a33313a32312e333533353934312b30313a3030")] // Non-Gregorian calendar date. public static void ReadDateTimeOffset_InvalidDateString_ShouldThrowCborContentException(string hexEncoding) { byte[] encoding = hexEncoding.HexToByteArray(); diff --git a/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj b/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj index 2ade4c628c7fbc..bf7b2f2b4aac54 100644 --- a/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj +++ b/src/libraries/System.Formats.Cbor/tests/System.Formats.Cbor.Tests.csproj @@ -1,6 +1,7 @@ - + $(NetCoreAppCurrent);$(NetFrameworkCurrent) + true enable $(NoWarn);CS8002 diff --git a/src/libraries/System.Formats.Cbor/tests/Writer/CborWriterTests.Tag.cs b/src/libraries/System.Formats.Cbor/tests/Writer/CborWriterTests.Tag.cs index 3413eadc84cc31..ff480bca39e119 100644 --- a/src/libraries/System.Formats.Cbor/tests/Writer/CborWriterTests.Tag.cs +++ b/src/libraries/System.Formats.Cbor/tests/Writer/CborWriterTests.Tag.cs @@ -2,8 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Numerics; +using System.Threading; +using Microsoft.DotNet.RemoteExecutor; using Test.Cryptography; using Xunit; @@ -88,6 +91,30 @@ public static void WriteDateTimeOffset_SingleValue_HappyPath(string valueString, AssertHelper.HexEqual(expectedHexEncoding.HexToByteArray(), encoding); } + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public static void WriteDateTimeOffset_IsCultureInvariant() + { + // Regression test for https://github.com/dotnet/runtime/pull/92539 + RemoteExecutor.Invoke(static () => + { + DateTimeOffset value = DateTimeOffset.Parse("2020-04-09T14:31:21.3535941+01:00", CultureInfo.InvariantCulture); + string expectedHexEncoding = "c07821323032302d30342d30395431343a33313a32312e333533353934312b30313a3030"; + + // Install a non-Gregorian calendar + var culture = new CultureInfo("he-IL"); + culture.DateTimeFormat.Calendar = new HebrewCalendar(); + Thread.CurrentThread.CurrentCulture = culture; + + var writer = new CborWriter(); + + writer.WriteDateTimeOffset(value); + + byte[] encoding = writer.Encode(); + AssertHelper.HexEqual(expectedHexEncoding.HexToByteArray(), encoding); + }).Dispose(); + } + [Theory] [InlineData(1363896240, "c11a514b67b0")] [InlineData(1586439081, "c11a5e8f23a9")] From 22b8a5665f5725a2c7bb09cfbe88f2cdc9847c1a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 4 Oct 2023 08:59:04 -0700 Subject: [PATCH 349/783] Update dependencies from https://github.com/dotnet/roslyn build 20231003.7 (#93005) Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23501.1 -> To Version 4.8.0-3.23503.7 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9c18388aa5346d..85c7a7aaaebf60 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - 0d735148bbb4cb511be547fbc1db63a2c81a821d + 61728203004a6c9f57df5cd0b0bf4e35e865f10b - + https://github.com/dotnet/roslyn - 0d735148bbb4cb511be547fbc1db63a2c81a821d + 61728203004a6c9f57df5cd0b0bf4e35e865f10b - + https://github.com/dotnet/roslyn - 0d735148bbb4cb511be547fbc1db63a2c81a821d + 61728203004a6c9f57df5cd0b0bf4e35e865f10b https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index ef9555ba255cbe..0744fd3d3ea304 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -44,9 +44,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23501.1 - 4.8.0-3.23501.1 - 4.8.0-3.23501.1 + 4.8.0-3.23503.7 + 4.8.0-3.23503.7 + 4.8.0-3.23503.7 8.0.0-rc.1.23406.6 8.0.0-preview.7.23325.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 6.0.0 1.1.1 @@ -222,38 +222,38 @@ 2.2.2 8.0.0-alpha.1.23468.1 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 - 8.0.0-rtm.23477.1 + 8.0.0-rtm.23504.4 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda 1.0.0-v3.14.0.5722 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 - 16.0.5-alpha.1.23472.2 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23478.1 3.1.7 1.0.406601 From 61b723a1a72a66f9546bc064bac8087f2f4c541d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 09:58:57 -0600 Subject: [PATCH 352/783] Update dependencies from https://github.com/dotnet/roslyn build 20231004.4 (#93040) Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23503.7 -> To Version 4.8.0-3.23504.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3d9872fc4aea32..a72729529000a8 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - 61728203004a6c9f57df5cd0b0bf4e35e865f10b + 81d9274600db701a8b08ed8af3fd6b00a775cc33 - + https://github.com/dotnet/roslyn - 61728203004a6c9f57df5cd0b0bf4e35e865f10b + 81d9274600db701a8b08ed8af3fd6b00a775cc33 - + https://github.com/dotnet/roslyn - 61728203004a6c9f57df5cd0b0bf4e35e865f10b + 81d9274600db701a8b08ed8af3fd6b00a775cc33 https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index e1e3d130797023..af2b4d15204cae 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -44,9 +44,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23503.7 - 4.8.0-3.23503.7 - 4.8.0-3.23503.7 + 4.8.0-3.23504.4 + 4.8.0-3.23504.4 + 4.8.0-3.23504.4 diff --git a/eng/Versions.props b/eng/Versions.props index af2b4d15204cae..9b0053d511440e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23478.3 - 1.0.0-prerelease.23478.3 - 1.0.0-prerelease.23478.3 - 1.0.0-prerelease.23478.3 - 1.0.0-prerelease.23478.3 - 1.0.0-prerelease.23478.3 + 1.0.0-prerelease.23504.3 + 1.0.0-prerelease.23504.3 + 1.0.0-prerelease.23504.3 + 1.0.0-prerelease.23504.3 + 1.0.0-prerelease.23504.3 + 1.0.0-prerelease.23504.3 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From 0c2796c70c658706684bf00b65cfdd975cf8d33a Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Fri, 6 Oct 2023 14:02:37 -0500 Subject: [PATCH 354/783] [release/8.0] Manually update release/8.0 arcade to latest (#92778) * Manually update release/8.0 arcade to latest * Fix ILCompiler build * Fix analyzer warning * work around rid issues * Move to Directory.Build.targets And use the same condition as in main. * Set RunAnalyzers to false for projects with no sources * Fix Microsoft.NETCore.App.deps.json to include RID graph --------- Co-authored-by: Sven Boemer Co-authored-by: Marek Safar Co-authored-by: Elinor Fung --- eng/Analyzers.targets | 7 ++ eng/Version.Details.xml | 76 +++++++++---------- eng/Versions.props | 30 ++++---- eng/common/sdk-task.ps1 | 2 +- eng/common/tools.ps1 | 4 +- global.json | 10 +-- .../SymbolReader/UnmanagedPdbSymbolReader.cs | 4 +- src/coreclr/tools/aot/Directory.Build.props | 6 -- src/coreclr/tools/aot/Directory.Build.targets | 6 ++ .../Microsoft.NETCore.App.Runtime.sfxproj | 3 + src/tests/Common/external/external.csproj | 2 +- 11 files changed, 80 insertions(+), 70 deletions(-) delete mode 100644 src/coreclr/tools/aot/Directory.Build.props create mode 100644 src/coreclr/tools/aot/Directory.Build.targets diff --git a/eng/Analyzers.targets b/eng/Analyzers.targets index 4ca3df7737280a..a7955d74e9bdc4 100644 --- a/eng/Analyzers.targets +++ b/eng/Analyzers.targets @@ -1,4 +1,11 @@ + + + false + false diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index fc875a6f4f55a3..e4e859d2c6289b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -107,79 +107,79 @@ - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/xliff-tasks - 194f32828726c3f1f63f79f3dc09b9e99c157b11 + 73f0850939d96131c28cf6ea6ee5aacb4da0083a - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 https://github.com/dotnet/runtime-assets @@ -330,9 +330,9 @@ https://github.com/dotnet/xharness 480b9159eb7e69b182a87581d5a336e97e0b6dae - + https://github.com/dotnet/arcade - 1d451c32dda2314c721adbf8829e1c0cd4e681ff + 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index 9b0053d511440e..204fea8a41055e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -87,21 +87,21 @@ 8.0.100-preview.7.23329.3 - 8.0.0-beta.23463.1 - 8.0.0-beta.23463.1 - 8.0.0-beta.23463.1 - 8.0.0-beta.23463.1 - 8.0.0-beta.23463.1 - 2.5.1-beta.23463.1 - 8.0.0-beta.23463.1 - 8.0.0-beta.23463.1 - 8.0.0-beta.23463.1 - 8.0.0-beta.23463.1 - 8.0.0-beta.23463.1 - 8.0.0-beta.23463.1 - 8.0.0-beta.23463.1 - 8.0.0-beta.23463.1 - 8.0.0-beta.23463.1 + 8.0.0-beta.23477.4 + 8.0.0-beta.23477.4 + 8.0.0-beta.23477.4 + 8.0.0-beta.23477.4 + 8.0.0-beta.23477.4 + 2.5.1-beta.23477.4 + 8.0.0-beta.23477.4 + 8.0.0-beta.23477.4 + 8.0.0-beta.23477.4 + 8.0.0-beta.23477.4 + 8.0.0-beta.23477.4 + 8.0.0-beta.23477.4 + 8.0.0-beta.23477.4 + 8.0.0-beta.23477.4 + 8.0.0-beta.23477.4 6.0.0-preview.1.102 diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1 index 6c4ac6fec1a99a..ff5342eb5c1947 100644 --- a/eng/common/sdk-task.ps1 +++ b/eng/common/sdk-task.ps1 @@ -64,7 +64,7 @@ try { $GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty } if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) { - $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.6.0-2" -MemberType NoteProperty + $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.7.2" -MemberType NoteProperty } if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") { $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index aa74ab4a81e782..19e9fa66239be6 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -384,8 +384,8 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = # If the version of msbuild is going to be xcopied, # use this version. Version matches a package here: - # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/RoslynTools.MSBuild/versions/17.6.0-2 - $defaultXCopyMSBuildVersion = '17.6.0-2' + # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/RoslynTools.MSBuild/versions/17.7.2 + $defaultXCopyMSBuildVersion = '17.7.2' if (!$vsRequirements) { if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') { diff --git a/global.json b/global.json index 2b41b42c3256e6..38d6bdc6407177 100644 --- a/global.json +++ b/global.json @@ -1,16 +1,16 @@ { "sdk": { - "version": "8.0.100-preview.7.23376.3", + "version": "8.0.100-rc.1.23455.8", "allowPrerelease": true, "rollForward": "major" }, "tools": { - "dotnet": "8.0.100-preview.7.23376.3" + "dotnet": "8.0.100-rc.1.23455.8" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23463.1", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23463.1", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23463.1", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23477.4", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23477.4", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23477.4", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/UnmanagedPdbSymbolReader.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/UnmanagedPdbSymbolReader.cs index c791a509f02a99..107170e743fbc7 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/UnmanagedPdbSymbolReader.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/UnmanagedPdbSymbolReader.cs @@ -68,7 +68,7 @@ protected override object CreateObject(IntPtr externalComObject, CreateObjectFla Debug.Assert(flags == CreateObjectFlags.UniqueInstance); var iid = ICLRMetaHost.IID; - if (Marshal.QueryInterface(externalComObject, ref iid, out IntPtr hostPtr) != 0) + if (Marshal.QueryInterface(externalComObject, in iid, out IntPtr hostPtr) != 0) { throw new ArgumentException("Expected ICLRMetaHost COM interface"); } @@ -284,7 +284,7 @@ private CoCreateWrapperCache() { } Debug.Assert(flags == CreateObjectFlags.UniqueInstance); var iid = new Guid("AA544D42-28CB-11d3-BD22-0000F80849BD"); - if (Marshal.QueryInterface(externalComObject, ref iid, out IntPtr ppv) != 0) + if (Marshal.QueryInterface(externalComObject, in iid, out IntPtr ppv) != 0) { return null; } diff --git a/src/coreclr/tools/aot/Directory.Build.props b/src/coreclr/tools/aot/Directory.Build.props deleted file mode 100644 index 5a5e0e9914b730..00000000000000 --- a/src/coreclr/tools/aot/Directory.Build.props +++ /dev/null @@ -1,6 +0,0 @@ - - - - true - - diff --git a/src/coreclr/tools/aot/Directory.Build.targets b/src/coreclr/tools/aot/Directory.Build.targets new file mode 100644 index 00000000000000..4f855d71288f72 --- /dev/null +++ b/src/coreclr/tools/aot/Directory.Build.targets @@ -0,0 +1,6 @@ + + + + true + + diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.sfxproj b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.sfxproj index 979432e74e5fa8..d0e9b6e16ff1a1 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.sfxproj +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.sfxproj @@ -12,6 +12,9 @@ dotnet-runtime-symbols NetCore.SharedFramework true + + true diff --git a/src/tests/Common/external/external.csproj b/src/tests/Common/external/external.csproj index d2541b5ae4835b..71aa7a42b5661c 100644 --- a/src/tests/Common/external/external.csproj +++ b/src/tests/Common/external/external.csproj @@ -13,7 +13,7 @@ --> $(TargetingPackPath) $(NetCoreAppToolCurrent) - win7-x86;win7-x64 + win-x86;win-x64 SharedLibrary false false From 6659ef0c1a367bf5f89d632779d40bac8a8c624f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 6 Oct 2023 13:04:19 -0600 Subject: [PATCH 355/783] Update release/8.0-rc1 to release/8.0 in perf.yml. This will need to be backported to the release/8.0 branch. (#93136) Co-authored-by: Parker Bibus --- eng/pipelines/coreclr/perf.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/coreclr/perf.yml b/eng/pipelines/coreclr/perf.yml index edaadde3e511ee..65d29662504364 100644 --- a/eng/pipelines/coreclr/perf.yml +++ b/eng/pipelines/coreclr/perf.yml @@ -3,7 +3,7 @@ trigger: branches: include: - main - - release/8.0-rc1 + - release/8.0 paths: include: - '*' From b17a34c818bd5e01fdb9827fea64727a5fc51025 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 6 Oct 2023 13:06:13 -0600 Subject: [PATCH 356/783] [release/8.0] Resolve x64 libc++ being included with linux-arm64 to browser-wasm cross-compiler (#93070) * Try to resolve x64 libc++ being included with linux-arm64 to browser-wasm cross-compilers, due to incorrect assumption that the build architecture should be used for wasm cases. Closes: https://github.com/dotnet/runtime/issues/93015 * Still bad. Remove a condition. --------- Co-authored-by: Jo Shields Co-authored-by: Jo Shields --- src/mono/mono.proj | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 6be683f8e2eb2c..6f15a31d94dca4 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -254,9 +254,10 @@ - - <_MonoLLVMTargetArchitecture Condition="'$(TargetArchitecture)' == 'wasm' and '$(MonoUseLLVMPackage)' == 'true'">$(BuildArchitecture) - <_MonoLLVMTargetArchitecture Condition="'$(TargetArchitecture)' != 'wasm' and '$(MonoUseLLVMPackage)' == 'true'">$(TargetArchitecture) + + <_MonoLLVMTargetArchitecture Condition="'$(TargetArchitecture)' == 'wasm'">$(BuildArchitecture) + <_MonoLLVMTargetArchitecture Condition="'$(TargetArchitecture)' != 'wasm'">$(TargetArchitecture) + <_MonoLLVMHostArchitecture Condition="'$(AotHostArchitecture)' != ''">$(AotHostArchitecture) <_MonoCMakeArgs Condition="'$(_MonoUseNinja)' == 'true'" Include="-G Ninja"/> @@ -698,14 +699,14 @@ $(MonoCrossDir)/usr/lib/gcc/aarch64-linux-gnu/5 - - <_MonoLLVMTargetArchitecture Condition="'$(MonoUseLLVMPackage)' == 'true'">$(BuildArchitecture) - <_MonoLLVMTargetArchitecture Condition="'$(MonoUseLLVMPackage)' == 'true'">$(AotHostArchitecture) + + <_MonoLLVMTargetArchitecture>$(TargetArchitecture) + <_MonoLLVMHostArchitecture>$(AotHostArchitecture) - <_MonoAOTCXXFLAGS Include="-I$(MonoLLVMDir)\$(_MonoLLVMTargetArchitecture)\include\c++\v1" /> - <_MonoAOTCXXFLAGS Include="-L$(MonoLLVMDir)\$(_MonoLLVMTargetArchitecture)\lib" /> + <_MonoAOTCXXFLAGS Include="-I$(MonoLLVMDir)\$(_MonoLLVMHostArchitecture)\include\c++\v1" /> + <_MonoAOTCXXFLAGS Include="-L$(MonoLLVMDir)\$(_MonoLLVMHostArchitecture)\lib" /> <_MonoAOTCXXFLAGS Include="-stdlib=libc++" /> @@ -844,7 +845,7 @@ - + @@ -936,8 +937,7 @@ <_MonoAotCrossPdbFilePath>$(MonoObjCrossDir)out\bin\$(MonoAotCrossPdbFileName) - <_MonoLLVMTargetArchitecture>$(BuildArchitecture) - <_MonoLLVMTargetArchitecture Condition="'$(TargetArchitecture)' != 'wasm'">$(AotHostArchitecture) + <_MonoLLVMHostArchitecture>$(AotHostArchitecture) @@ -977,25 +977,25 @@ <_MonoRuntimeArtifacts Condition="'$(HostOS)' == 'Linux' and ('$(MonoBundleLLVMOptimizer)' == 'true' or '$(MonoEnableLLVM)' == 'true') and '$(TargetArchitecture)' != 'wasm' and '$(MonoUseLibCxx)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMTargetArchitecture)\lib\libc++abi.so.1"> $(RuntimeBinDir)libc++abi.so.1 - <_MonoRuntimeArtifacts Condition="'$(HostOS)' == 'Linux' and ((('$(MonoAOTBundleLLVMOptimizer)' == 'true' or '$(MonoAOTEnableLLVM)' == 'true') and '$(MonoUseLibCxx)' == 'true') or '$(TargetArchitecture)' == 'wasm')" Include="$(MonoLLVMDir)\$(_MonoLLVMTargetArchitecture)\lib\libc++.so.1"> + <_MonoRuntimeArtifacts Condition="'$(HostOS)' == 'Linux' and ((('$(MonoAOTBundleLLVMOptimizer)' == 'true' or '$(MonoAOTEnableLLVM)' == 'true') and '$(MonoUseLibCxx)' == 'true') or '$(TargetArchitecture)' == 'wasm')" Include="$(MonoLLVMDir)\$(_MonoLLVMHostArchitecture)\lib\libc++.so.1"> $(RuntimeBinDir)cross\$(OutputRID)\libc++.so.1 - <_MonoRuntimeArtifacts Condition="'$(HostOS)' == 'Linux' and ((('$(MonoAOTBundleLLVMOptimizer)' == 'true' or '$(MonoAOTEnableLLVM)' == 'true') and '$(MonoUseLibCxx)' == 'true') or '$(TargetArchitecture)' == 'wasm')" Include="$(MonoLLVMDir)\$(_MonoLLVMTargetArchitecture)\lib\libc++abi.so.1"> + <_MonoRuntimeArtifacts Condition="'$(HostOS)' == 'Linux' and ((('$(MonoAOTBundleLLVMOptimizer)' == 'true' or '$(MonoAOTEnableLLVM)' == 'true') and '$(MonoUseLibCxx)' == 'true') or '$(TargetArchitecture)' == 'wasm')" Include="$(MonoLLVMDir)\$(_MonoLLVMHostArchitecture)\lib\libc++abi.so.1"> $(RuntimeBinDir)cross\$(OutputRID)\libc++abi.so.1 <_MonoRuntimeArtifacts Include="$(_MonoAotCrossPdbFilePath)" Condition="Exists('$(_MonoAotCrossPdbFilePath)')"> $(RuntimeBinDir)cross\$(OutputRID)\$(MonoAotCrossPdbFileName) - <_MonoRuntimeArtifacts Condition="'$(MonoBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMTargetArchitecture)\bin\llc$(ExeSuffix)"> + <_MonoRuntimeArtifacts Condition="'$(MonoBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMHostArchitecture)\bin\llc$(ExeSuffix)"> $(RuntimeBinDir)\llc$(ExeSuffix) - <_MonoRuntimeArtifacts Condition="'$(MonoBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMTargetArchitecture)\bin\opt$(ExeSuffix)"> + <_MonoRuntimeArtifacts Condition="'$(MonoBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMHostArchitecture)\bin\opt$(ExeSuffix)"> $(RuntimeBinDir)\opt$(ExeSuffix) - <_MonoRuntimeArtifacts Condition="'$(MonoAOTBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMTargetArchitecture)\bin\llc$(ExeSuffix)"> + <_MonoRuntimeArtifacts Condition="'$(MonoAOTBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMHostArchitecture)\bin\llc$(ExeSuffix)"> $(RuntimeBinDir)cross\$(OutputRID)\llc$(ExeSuffix) - <_MonoRuntimeArtifacts Condition="'$(MonoAOTBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMTargetArchitecture)\bin\opt$(ExeSuffix)"> + <_MonoRuntimeArtifacts Condition="'$(MonoAOTBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMHostArchitecture)\bin\opt$(ExeSuffix)"> $(RuntimeBinDir)cross\$(OutputRID)\opt$(ExeSuffix) <_MonoIncludeArtifacts Include="$(MonoObjDir)out\include\**" /> From a9cc3c80fe43d19a38cacda4c1aecc51fb6eabb1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 09:53:38 -0700 Subject: [PATCH 357/783] [release/8.0] Update dependencies from dnceng/internal/dotnet-optimization (#93112) * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231005.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23504.3 -> To Version 1.0.0-prerelease.23505.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231006.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23504.3 -> To Version 1.0.0-prerelease.23506.3 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231007.6 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23504.3 -> To Version 1.0.0-prerelease.23507.6 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231007.6 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23504.3 -> To Version 1.0.0-prerelease.23507.6 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e4e859d2c6289b..ffffa99e8a4f3e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -334,21 +334,21 @@ https://github.com/dotnet/arcade 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 281a6c9edb3f35d5915666ccb26336c9973213c3 + 9d70382f52bc311fa51e523bb066ebb012bf8035 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 281a6c9edb3f35d5915666ccb26336c9973213c3 + 9d70382f52bc311fa51e523bb066ebb012bf8035 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 281a6c9edb3f35d5915666ccb26336c9973213c3 + 9d70382f52bc311fa51e523bb066ebb012bf8035 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 281a6c9edb3f35d5915666ccb26336c9973213c3 + 9d70382f52bc311fa51e523bb066ebb012bf8035 https://github.com/dotnet/hotreload-utils @@ -384,13 +384,13 @@ d10b02ae5cc670609d920a672985ed4456bdd6b6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 281a6c9edb3f35d5915666ccb26336c9973213c3 + 9d70382f52bc311fa51e523bb066ebb012bf8035 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 281a6c9edb3f35d5915666ccb26336c9973213c3 + 9d70382f52bc311fa51e523bb066ebb012bf8035 diff --git a/eng/Versions.props b/eng/Versions.props index 204fea8a41055e..4dd8db8ddc99e5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23504.3 - 1.0.0-prerelease.23504.3 - 1.0.0-prerelease.23504.3 - 1.0.0-prerelease.23504.3 - 1.0.0-prerelease.23504.3 - 1.0.0-prerelease.23504.3 + 1.0.0-prerelease.23507.6 + 1.0.0-prerelease.23507.6 + 1.0.0-prerelease.23507.6 + 1.0.0-prerelease.23507.6 + 1.0.0-prerelease.23507.6 + 1.0.0-prerelease.23507.6 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From 85119055d2603da931bd3cd92ede9a4be709ca48 Mon Sep 17 00:00:00 2001 From: Koundinya Veluri Date: Wed, 11 Oct 2023 14:01:01 -0700 Subject: [PATCH 358/783] Make thread pool thread timeouts configurable (#92986) - Added two config options, one that configures the worker and wait thread timeouts, and another that enables keeping some number of worker threads alive after they are created - This enables services that take periodic traffic to keep some worker threads around for better latency, while allowing extra threads to time out as appropriate for the service --- .../src/System/AppContextConfigHelper.cs | 79 +++++++++++++++++++ ...tableThreadPool.WorkerThread.NonBrowser.cs | 47 ++++++++++- .../System/Threading/PortableThreadPool.cs | 18 ++++- 3 files changed, 141 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/AppContextConfigHelper.cs b/src/libraries/System.Private.CoreLib/src/System/AppContextConfigHelper.cs index 3a8c3e8e7ea72d..efbe9e691625d7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/AppContextConfigHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/AppContextConfigHelper.cs @@ -65,6 +65,45 @@ internal static int GetInt32Config(string configName, int defaultValue, bool all } } + internal static int GetInt32Config(string configName, string envVariable, int defaultValue, bool allowNegative = true) + { + string? str = Environment.GetEnvironmentVariable(envVariable); + if (str != null) + { + try + { + int result; + if (str.StartsWith('0')) + { + if (str.Length >= 2 && str[1] == 'x') + { + result = Convert.ToInt32(str, 16); + } + else + { + result = Convert.ToInt32(str, 8); + } + } + else + { + result = int.Parse(str, NumberStyles.AllowLeadingSign, NumberFormatInfo.InvariantInfo); + } + + if (allowNegative || result >= 0) + { + return result; + } + } + catch (FormatException) + { + } + catch (OverflowException) + { + } + } + + return GetInt32Config(configName, defaultValue, allowNegative); + } internal static short GetInt16Config(string configName, short defaultValue, bool allowNegative = true) { @@ -112,5 +151,45 @@ internal static short GetInt16Config(string configName, short defaultValue, bool return defaultValue; } } + + internal static short GetInt16Config(string configName, string envVariable, short defaultValue, bool allowNegative = true) + { + string? str = Environment.GetEnvironmentVariable(envVariable); + if (str != null) + { + try + { + short result; + if (str.StartsWith('0')) + { + if (str.Length >= 2 && str[1] == 'x') + { + result = Convert.ToInt16(str, 16); + } + else + { + result = Convert.ToInt16(str, 8); + } + } + else + { + result = short.Parse(str, NumberStyles.AllowLeadingSign, NumberFormatInfo.InvariantInfo); + } + + if (allowNegative || result >= 0) + { + return result; + } + } + catch (FormatException) + { + } + catch (OverflowException) + { + } + } + + return GetInt16Config(configName, defaultValue, allowNegative); + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.NonBrowser.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.NonBrowser.cs index 2e634fd469d9d8..c3b278019f6d92 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.NonBrowser.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.NonBrowser.cs @@ -7,11 +7,29 @@ namespace System.Threading { internal sealed partial class PortableThreadPool { + private int _numThreadsBeingKeptAlive; + /// /// The worker thread infastructure for the CLR thread pool. /// private static partial class WorkerThread { + private static readonly short ThreadsToKeepAlive = DetermineThreadsToKeepAlive(); + + private static short DetermineThreadsToKeepAlive() + { + const short DefaultThreadsToKeepAlive = 0; + + // The number of worker threads to keep alive after they are created. Set to -1 to keep all created worker + // threads alive. When the ThreadTimeoutMs config value is also set, for worker threads the timeout applies to + // worker threads that are in excess of the number configured for ThreadsToKeepAlive. + short threadsToKeepAlive = + AppContextConfigHelper.GetInt16Config( + "System.Threading.ThreadPool.ThreadsToKeepAlive", + "DOTNET_ThreadPool_ThreadsToKeepAlive", + DefaultThreadsToKeepAlive); + return threadsToKeepAlive >= -1 ? threadsToKeepAlive : DefaultThreadsToKeepAlive; + } /// /// Semaphore for controlling how many threads are currently working. @@ -50,10 +68,36 @@ private static void WorkerThreadStart() LowLevelLock threadAdjustmentLock = threadPoolInstance._threadAdjustmentLock; LowLevelLifoSemaphore semaphore = s_semaphore; + // Determine the idle timeout to use for this thread. Some threads may always be kept alive based on config. + int timeoutMs = ThreadPoolThreadTimeoutMs; + if (ThreadsToKeepAlive != 0) + { + if (ThreadsToKeepAlive < 0) + { + timeoutMs = Timeout.Infinite; + } + else + { + int count = threadPoolInstance._numThreadsBeingKeptAlive; + while (count < ThreadsToKeepAlive) + { + int countBeforeUpdate = + Interlocked.CompareExchange(ref threadPoolInstance._numThreadsBeingKeptAlive, count + 1, count); + if (countBeforeUpdate == count) + { + timeoutMs = Timeout.Infinite; + break; + } + + count = countBeforeUpdate; + } + } + } + while (true) { bool spinWait = true; - while (semaphore.Wait(ThreadPoolThreadTimeoutMs, spinWait)) + while (semaphore.Wait(timeoutMs, spinWait)) { WorkerDoWork(threadPoolInstance, ref spinWait); } @@ -65,7 +109,6 @@ private static void WorkerThreadStart() } } - private static void CreateWorkerThread() { // Thread pool threads must start in the default execution context without transferring the context, so diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs index 9ada201e134c5a..db49ea2c5a5a92 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs @@ -13,7 +13,6 @@ namespace System.Threading /// internal sealed partial class PortableThreadPool { - private const int ThreadPoolThreadTimeoutMs = 20 * 1000; // If you change this make sure to change the timeout times in the tests. private const int SmallStackSizeBytes = 256 * 1024; private const short MaxPossibleThreadCount = short.MaxValue; @@ -40,6 +39,23 @@ internal sealed partial class PortableThreadPool private static readonly short ForcedMaxWorkerThreads = AppContextConfigHelper.GetInt16Config("System.Threading.ThreadPool.MaxThreads", 0, false); + private static readonly int ThreadPoolThreadTimeoutMs = DetermineThreadPoolThreadTimeoutMs(); + + private static int DetermineThreadPoolThreadTimeoutMs() + { + const int DefaultThreadPoolThreadTimeoutMs = 20 * 1000; // If you change this make sure to change the timeout times in the tests. + + // The amount of time in milliseconds a thread pool thread waits without having done any work before timing out and + // exiting. Set to -1 to disable the timeout. Applies to worker threads and wait threads. Also see the + // ThreadsToKeepAlive config value for relevant information. + int timeoutMs = + AppContextConfigHelper.GetInt32Config( + "System.Threading.ThreadPool.ThreadTimeoutMs", + "DOTNET_ThreadPool_ThreadTimeoutMs", + DefaultThreadPoolThreadTimeoutMs); + return timeoutMs >= -1 ? timeoutMs : DefaultThreadPoolThreadTimeoutMs; + } + [ThreadStatic] private static object? t_completionCountObject; From 705221b07530bb28448badbc29f1b107e5c61cbf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 17:01:03 -0700 Subject: [PATCH 359/783] [release/8.0] Make a copy of assembly path. (#93253) * Make a copy of assembly path. * Use correct C++. * Use copy ctor explicitly --------- Co-authored-by: Aaron R Robinson --- src/coreclr/vm/perfinfo.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/coreclr/vm/perfinfo.cpp b/src/coreclr/vm/perfinfo.cpp index 0be2e519936fbe..98fc667661a504 100644 --- a/src/coreclr/vm/perfinfo.cpp +++ b/src/coreclr/vm/perfinfo.cpp @@ -32,8 +32,8 @@ void PerfInfo::LogImage(PEAssembly* pPEAssembly, CHAR* guid) PRECONDITION(guid != nullptr); } CONTRACTL_END; - SString value; - const SString& path = pPEAssembly->GetPath(); + // Nothing to log if the assembly path isn't present. + SString path{ pPEAssembly->GetPath() }; if (path.IsEmpty()) { return; @@ -49,12 +49,11 @@ void PerfInfo::LogImage(PEAssembly* pPEAssembly, CHAR* guid) } } + SString value; value.Printf("%s%c%s%c%p", path.GetUTF8(), sDelimiter, guid, sDelimiter, baseAddr); - SString command; - command.Printf("%s", "ImageLoad"); + SString command{ SString::Literal, "ImageLoad" }; WriteLine(command, value); - } // Writes a command line, with "type" being the type of command, with "value" as the command's corresponding instructions/values. This is to be used to log specific information, e.g. LogImage From ba516416679c89f545562d63fdbf42d9c80620ef Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 17:02:34 -0700 Subject: [PATCH 360/783] [release/8.0] Fix Options Source Gen Trimming Issues (#93193) * Fix Options Source Gen Trimming Issues * Make Emitted Attribute Order Deterministic in Options Source Generator (#93260) * Make Emitted Attribute Order Deterministic in Options Source Generator * Use ordinal comparison when ordering the list --------- Co-authored-by: Tarek Mahmoud Sayed --- docs/project/list-of-diagnostics.md | 2 +- .../gen/DiagDescriptors.cs | 7 + .../gen/Emitter.cs | 445 +++++++++++++++-- .../gen/Generator.cs | 6 +- ...Extensions.Options.SourceGeneration.csproj | 1 + .../gen/OptionsSourceGenContext.cs | 83 +++ .../gen/Parser.cs | 103 +++- .../gen/ParserUtilities.cs | 23 + .../gen/Resources/Strings.resx | 6 + .../gen/Resources/xlf/Strings.cs.xlf | 10 + .../gen/Resources/xlf/Strings.de.xlf | 10 + .../gen/Resources/xlf/Strings.es.xlf | 10 + .../gen/Resources/xlf/Strings.fr.xlf | 10 + .../gen/Resources/xlf/Strings.it.xlf | 10 + .../gen/Resources/xlf/Strings.ja.xlf | 10 + .../gen/Resources/xlf/Strings.ko.xlf | 10 + .../gen/Resources/xlf/Strings.pl.xlf | 10 + .../gen/Resources/xlf/Strings.pt-BR.xlf | 10 + .../gen/Resources/xlf/Strings.ru.xlf | 10 + .../gen/Resources/xlf/Strings.tr.xlf | 10 + .../gen/Resources/xlf/Strings.zh-Hans.xlf | 10 + .../gen/Resources/xlf/Strings.zh-Hant.xlf | 10 + .../gen/SymbolHolder.cs | 7 + .../gen/SymbolLoader.cs | 37 ++ .../src/Microsoft.Extensions.Options.csproj | 3 +- .../DataAnnotationAttributesWithParams.g.cs | 135 +++++ .../EmitterWithCustomValidator.netcore.g.cs | 175 +++++++ .../EmitterWithCustomValidator.netfx.g.cs | 173 +++++++ ...eneratedAttributesTest.netcore.lang10.g.cs | 471 ++++++++++++++++++ ...eneratedAttributesTest.netcore.lang11.g.cs | 471 ++++++++++++++++++ .../GeneratedAttributesTest.netfx.lang10.g.cs | 386 ++++++++++++++ .../GeneratedAttributesTest.netfx.lang11.g.cs | 386 ++++++++++++++ .../tests/SourceGeneration.Unit.Tests/Main.cs | 278 +++++------ ...Options.SourceGeneration.Unit.Tests.csproj | 7 + .../OptionsRuntimeTests.cs | 211 +++++++- .../Resources/Strings.resx | 8 +- .../Baselines/NetCoreApp/Validators.g.cs | 263 +++++++++- .../Baselines/NetFX/Validators.g.cs | 165 +++++- .../Resources/Strings.resx | 8 +- .../tests/TrimmingTests/ConfigureTests.cs | 44 ++ ...soft.Extensions.Options.TrimmingTests.proj | 7 +- 41 files changed, 3819 insertions(+), 222 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.Options/gen/OptionsSourceGenContext.cs create mode 100644 src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/DataAnnotationAttributesWithParams.g.cs create mode 100644 src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netcore.g.cs create mode 100644 src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netfx.g.cs create mode 100644 src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang10.g.cs create mode 100644 src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang11.g.cs create mode 100644 src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang10.g.cs create mode 100644 src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang11.g.cs diff --git a/docs/project/list-of-diagnostics.md b/docs/project/list-of-diagnostics.md index 4b46d49f5813f0..aed0f89c89ced4 100644 --- a/docs/project/list-of-diagnostics.md +++ b/docs/project/list-of-diagnostics.md @@ -251,7 +251,7 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL | __`SYSLIB1214`__ | Options validation generator: Can't validate constants, static fields or properties. | | __`SYSLIB1215`__ | Options validation generator: Validation attribute on the member is inaccessible from the validator type. | | __`SYSLIB1216`__ | C# language version not supported by the options validation source generator. | -| __`SYSLIB1217`__ | *_`SYSLIB1201`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* | +| __`SYSLIB1217`__ | The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. | | __`SYSLIB1218`__ | *_`SYSLIB1201`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* | | __`SYSLIB1219`__ | *_`SYSLIB1201`-`SYSLIB1219` reserved for Microsoft.Extensions.Options.SourceGeneration.* | | __`SYSLIB1220`__ | JsonSourceGenerator encountered a [JsonConverterAttribute] with an invalid type argument. | diff --git a/src/libraries/Microsoft.Extensions.Options/gen/DiagDescriptors.cs b/src/libraries/Microsoft.Extensions.Options/gen/DiagDescriptors.cs index 141fc6b9c7f9ae..49562a0a128c2b 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/DiagDescriptors.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/DiagDescriptors.cs @@ -112,5 +112,12 @@ internal sealed class DiagDescriptors : DiagDescriptorsBase messageFormat: SR.OptionsUnsupportedLanguageVersionMessage, category: Category, defaultSeverity: DiagnosticSeverity.Error); + + public static DiagnosticDescriptor IncompatibleWithTypeForValidationAttribute { get; } = Make( + id: "SYSLIB1217", + title: SR.TypeCannotBeUsedWithTheValidationAttributeTitle, + messageFormat: SR.TypeCannotBeUsedWithTheValidationAttributeMessage, + category: Category, + defaultSeverity: DiagnosticSeverity.Warning); } } diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs b/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs index 9e0cb659a6c94a..41609ad4b2010a 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using System.Text; using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -18,36 +19,39 @@ namespace Microsoft.Extensions.Options.Generators internal sealed class Emitter : EmitterBase { private const string StaticFieldHolderClassesNamespace = "__OptionValidationStaticInstances"; + internal const string StaticGeneratedValidationAttributesClassesNamespace = "__OptionValidationGeneratedAttributes"; + internal const string StaticAttributeClassNamePrefix = "__SourceGen_"; + internal const string StaticGeneratedMaxLengthAttributeClassesName = "__SourceGen_MaxLengthAttribute"; private const string StaticListType = "global::System.Collections.Generic.List"; private const string StaticValidationResultType = "global::System.ComponentModel.DataAnnotations.ValidationResult"; private const string StaticValidationAttributeType = "global::System.ComponentModel.DataAnnotations.ValidationAttribute"; - + private const string StaticValidationContextType = "global::System.ComponentModel.DataAnnotations.ValidationContext"; private string _staticValidationAttributeHolderClassName = "__Attributes"; private string _staticValidatorHolderClassName = "__Validators"; private string _staticValidationAttributeHolderClassFQN; private string _staticValidatorHolderClassFQN; - private string _modifier; private string _TryGetValueNullableAnnotation; + private readonly SymbolHolder _symbolHolder; + private readonly OptionsSourceGenContext _optionsSourceGenContext; + private sealed record StaticFieldInfo(string FieldTypeFQN, int FieldOrder, string FieldName, IList InstantiationLines); - public Emitter(Compilation compilation, bool emitPreamble = true) : base(emitPreamble) + public Emitter(Compilation compilation, SymbolHolder symbolHolder, OptionsSourceGenContext optionsSourceGenContext, bool emitPreamble = true) : base(emitPreamble) { - if (((CSharpCompilation)compilation).LanguageVersion >= Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp11) - { - _modifier = "file"; - } - else + _optionsSourceGenContext = optionsSourceGenContext; + + if (!_optionsSourceGenContext.IsLangVersion11AndAbove) { - _modifier = "internal"; - string suffix = $"_{GetNonRandomizedHashCode(compilation.SourceModule.Name):X8}"; - _staticValidationAttributeHolderClassName += suffix; - _staticValidatorHolderClassName += suffix; + _staticValidationAttributeHolderClassName += _optionsSourceGenContext.Suffix; + _staticValidatorHolderClassName += _optionsSourceGenContext.Suffix; } _staticValidationAttributeHolderClassFQN = $"global::{StaticFieldHolderClassesNamespace}.{_staticValidationAttributeHolderClassName}"; _staticValidatorHolderClassFQN = $"global::{StaticFieldHolderClassesNamespace}.{_staticValidatorHolderClassName}"; _TryGetValueNullableAnnotation = GetNullableAnnotationStringForTryValidateValueToUseInGeneratedCode(compilation); + + _symbolHolder = symbolHolder; } public string Emit( @@ -65,6 +69,7 @@ public string Emit( GenStaticClassWithStaticReadonlyFields(staticValidationAttributesDict.Values, StaticFieldHolderClassesNamespace, _staticValidationAttributeHolderClassName); GenStaticClassWithStaticReadonlyFields(staticValidatorsDict.Values, StaticFieldHolderClassesNamespace, _staticValidatorHolderClassName); + GenValidationAttributesClasses(); return Capture(); } @@ -146,7 +151,7 @@ private void GenStaticClassWithStaticReadonlyFields(IEnumerable OutOpenBrace(); OutGeneratedCodeAttribute(); - OutLn($"{_modifier} static class {className}"); + OutLn($"{_optionsSourceGenContext.ClassModifier} static class {className}"); OutOpenBrace(); var staticValidationAttributes = staticFields @@ -186,6 +191,396 @@ private void GenStaticClassWithStaticReadonlyFields(IEnumerable OutCloseBrace(); } + public void EmitMaxLengthAttribute(string modifier, string prefix, string className, string linesToInsert, string suffix) + { + OutGeneratedCodeAttribute(); + + string qualifiedClassName = $"{prefix}{suffix}_{className}"; + + OutLn($$""" +[global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + {{modifier}} class {{qualifiedClassName}} : {{StaticValidationAttributeType}} + { + private const int MaxAllowableLength = -1; + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a maximum length of '{1}'."; + public {{qualifiedClassName}}(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public {{qualifiedClassName}}(): base(() => DefaultErrorMessageString) { Length = MaxAllowableLength; } + public int Length { get; } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + public override bool IsValid(object? value) + { + if (Length == 0 || Length < -1) + { + throw new global::System.InvalidOperationException("MaxLengthAttribute must have a Length value that is greater than zero. Use MaxLength() without parameters to indicate that the string or array can have the maximum allowable length."); + } + if (value == null || MaxAllowableLength == Length) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + {{linesToInsert}}else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length <= Length; + } + } +"""); + } + + public void EmitMinLengthAttribute(string modifier, string prefix, string className, string linesToInsert, string suffix) + { + OutGeneratedCodeAttribute(); + + string qualifiedClassName = $"{prefix}{suffix}_{className}"; + + OutLn($$""" +[global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + {{modifier}} class {{qualifiedClassName}} : {{StaticValidationAttributeType}} + { + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a minimum length of '{1}'."; + + public {{qualifiedClassName}}(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public int Length { get; } + public override bool IsValid(object? value) + { + if (Length < -1) + { + throw new global::System.InvalidOperationException("MinLengthAttribute must have a Length value that is zero or greater."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + {{linesToInsert}}else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length >= Length; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + } +"""); + } + + public void EmitLengthAttribute(string modifier, string prefix, string className, string linesToInsert, string suffix) + { + OutGeneratedCodeAttribute(); + + string qualifiedClassName = $"{prefix}{suffix}_{className}"; + + OutLn($$""" +[global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + {{modifier}} class {{qualifiedClassName}} : {{StaticValidationAttributeType}} + { + private static string DefaultErrorMessageString => "The field {0} must be a string or collection type with a minimum length of '{1}' and maximum length of '{2}'."; + public {{qualifiedClassName}}(int minimumLength, int maximumLength) : base(() => DefaultErrorMessageString) { MinimumLength = minimumLength; MaximumLength = maximumLength; } + public int MinimumLength { get; } + public int MaximumLength { get; } + public override bool IsValid(object? value) + { + if (MinimumLength < 0) + { + throw new global::System.InvalidOperationException("LengthAttribute must have a MinimumLength value that is zero or greater."); + } + if (MaximumLength < MinimumLength) + { + throw new global::System.InvalidOperationException("LengthAttribute must have a MaximumLength value that is greater than or equal to MinimumLength."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + {{linesToInsert}}else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return (uint)(length - MinimumLength) <= (uint)(MaximumLength - MinimumLength); + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, MinimumLength, MaximumLength); + } +"""); + } + + public void EmitCompareAttribute(string modifier, string prefix, string className, string linesToInsert, string suffix) + { + OutGeneratedCodeAttribute(); + + string qualifiedClassName = $"{prefix}{suffix}_{className}"; + + OutLn($$""" +[global::System.AttributeUsage(global::System.AttributeTargets.Property, AllowMultiple = false)] + {{modifier}} class {{qualifiedClassName}} : {{StaticValidationAttributeType}} + { + private static string DefaultErrorMessageString => "'{0}' and '{1}' do not match."; + public {{qualifiedClassName}}(string otherProperty) : base(() => DefaultErrorMessageString) + { + if (otherProperty == null) + { + throw new global::System.ArgumentNullException(nameof(otherProperty)); + } + OtherProperty = otherProperty; + } + public string OtherProperty { get; } + public override bool RequiresValidationContext => true; + + protected override {{StaticValidationResultType}}? IsValid(object? value, {{StaticValidationContextType}} validationContext) + { + bool result = true; + + {{linesToInsert}} + if (!result) + { + string[]? memberNames = validationContext.MemberName is null ? null : new string[] { validationContext.MemberName }; + return new {{StaticValidationResultType}}(FormatErrorMessage(validationContext.DisplayName), memberNames); + } + + return null; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, OtherProperty); + } +"""); + } + + public void EmitRangeAttribute(string modifier, string prefix, string className, string suffix) + { + OutGeneratedCodeAttribute(); + + string qualifiedClassName = $"{prefix}{suffix}_{className}"; + + OutLn($$""" +[global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + {{modifier}} class {{qualifiedClassName}} : {{StaticValidationAttributeType}} + { + public {{qualifiedClassName}}(int minimum, int maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(int); + } + public {{qualifiedClassName}}(double minimum, double maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(double); + } + public {{qualifiedClassName}}(global::System.Type type, string minimum, string maximum) : base() + { + OperandType = type; + NeedToConvertMinMax = true; + Minimum = minimum; + Maximum = maximum; + } + public object Minimum { get; private set; } + public object Maximum { get; private set; } + public bool MinimumIsExclusive { get; set; } + public bool MaximumIsExclusive { get; set; } + public global::System.Type OperandType { get; } + public bool ParseLimitsInInvariantCulture { get; set; } + public bool ConvertValueInInvariantCulture { get; set; } + public override string FormatErrorMessage(string name) => + string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); + private bool NeedToConvertMinMax { get; } + private bool Initialized { get; set; } + public override bool IsValid(object? value) + { + if (!Initialized) + { + if (Minimum is null || Maximum is null) + { + throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + if (NeedToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + Initialized = true; + } + + if (value is null or string { Length: 0 }) + { + return true; + } + + System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + object? convertedValue; + + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } + + var min = (global::System.IComparable)Minimum; + var max = (global::System.IComparable)Maximum; + + return + (MinimumIsExclusive ? min.CompareTo(convertedValue) < 0 : min.CompareTo(convertedValue) <= 0) && + (MaximumIsExclusive ? max.CompareTo(convertedValue) > 0 : max.CompareTo(convertedValue) >= 0); + } + private string GetValidationErrorMessage() + { + return (MinimumIsExclusive, MaximumIsExclusive) switch + { + (false, false) => "The field {0} must be between {1} and {2}.", + (true, false) => "The field {0} must be between {1} exclusive and {2}.", + (false, true) => "The field {0} must be between {1} and {2} exclusive.", + (true, true) => "The field {0} must be between {1} exclusive and {2} exclusive.", + }; + } + private object? ConvertValue(object? value, System.Globalization.CultureInfo formatProvider) + { + if (value is string stringValue) + { + value = global::System.Convert.ChangeType(stringValue, OperandType, formatProvider); + } + else + { + value = global::System.Convert.ChangeType(value, OperandType, formatProvider); + } + return value; + } + } +"""); + } + + private string GenerateStronglyTypedCodeForLengthAttributes(HashSet data) + { + if (data.Count == 0) + { + return string.Empty; + } + + StringBuilder sb = new(); + string padding = GetPaddingString(3); + + foreach (var type in data) + { + string typeName = (string)type; + sb.AppendLine($"else if (value is {typeName})"); + sb.AppendLine($"{padding}{{"); + sb.AppendLine($"{padding} length = (({typeName})value).Count;"); + sb.AppendLine($"{padding}}}"); + sb.Append($"{padding}"); + } + + return sb.ToString(); + } + + private string GenerateStronglyTypedCodeForCompareAttribute(HashSet? data) + { + if (data is null || data.Count == 0) + { + return string.Empty; + } + + StringBuilder sb = new(); + string padding = GetPaddingString(3); + bool first = true; + + foreach (var obj in data) + { + (string type, string property) = ((string, string))obj; + sb.Append(first ? $"if " : $"{padding}else if "); + sb.AppendLine($"(validationContext.ObjectInstance is {type} && OtherProperty == \"{property}\")"); + sb.AppendLine($"{padding}{{"); + sb.AppendLine($"{padding} result = Equals(value, (({type})validationContext.ObjectInstance).{property});"); + sb.AppendLine($"{padding}}}"); + first = false; + } + + return sb.ToString(); + } + + private void GenValidationAttributesClasses() + { + if (_optionsSourceGenContext.AttributesToGenerate.Count == 0) + { + return; + } + + var attributesData = _optionsSourceGenContext.AttributesToGenerate.OrderBy(static kvp => kvp.Key, StringComparer.Ordinal).ToArray(); + + OutLn($"namespace {StaticGeneratedValidationAttributesClassesNamespace}"); + OutOpenBrace(); + + foreach (var attributeData in attributesData) + { + if (attributeData.Key == _symbolHolder.MaxLengthAttributeSymbol.Name) + { + string linesToInsert = attributeData.Value is not null ? GenerateStronglyTypedCodeForLengthAttributes((HashSet)attributeData.Value) : string.Empty; + EmitMaxLengthAttribute(_optionsSourceGenContext.ClassModifier, Emitter.StaticAttributeClassNamePrefix, attributeData.Key, linesToInsert, _optionsSourceGenContext.Suffix); + } + else if (attributeData.Key == _symbolHolder.MinLengthAttributeSymbol.Name) + { + string linesToInsert = attributeData.Value is not null ? GenerateStronglyTypedCodeForLengthAttributes((HashSet)attributeData.Value) : string.Empty; + EmitMinLengthAttribute(_optionsSourceGenContext.ClassModifier, Emitter.StaticAttributeClassNamePrefix, attributeData.Key, linesToInsert, _optionsSourceGenContext.Suffix); + } + else if (_symbolHolder.LengthAttributeSymbol is not null && attributeData.Key == _symbolHolder.LengthAttributeSymbol.Name) + { + string linesToInsert = attributeData.Value is not null ? GenerateStronglyTypedCodeForLengthAttributes((HashSet)attributeData.Value) : string.Empty; + EmitLengthAttribute(_optionsSourceGenContext.ClassModifier, Emitter.StaticAttributeClassNamePrefix, attributeData.Key, linesToInsert, _optionsSourceGenContext.Suffix); + } + else if (attributeData.Key == _symbolHolder.CompareAttributeSymbol.Name && attributeData.Value is not null) + { + string linesToInsert = GenerateStronglyTypedCodeForCompareAttribute((HashSet)attributeData.Value); + EmitCompareAttribute(_optionsSourceGenContext.ClassModifier, Emitter.StaticAttributeClassNamePrefix, attributeData.Key, linesToInsert: linesToInsert, _optionsSourceGenContext.Suffix); + } + else if (attributeData.Key == _symbolHolder.RangeAttributeSymbol.Name) + { + EmitRangeAttribute(_optionsSourceGenContext.ClassModifier, Emitter.StaticAttributeClassNamePrefix, attributeData.Key, _optionsSourceGenContext.Suffix); + } + } + + OutCloseBrace(); + } + private void GenModelSelfValidationIfNecessary(ValidatedModel modelToValidate) { if (modelToValidate.SelfValidates) @@ -209,10 +604,18 @@ private void GenModelValidationMethod( OutLn($"/// Validation result."); OutGeneratedCodeAttribute(); + if (_symbolHolder.UnconditionalSuppressMessageAttributeSymbol is not null) + { + // We disable the warning on `new ValidationContext(object)` usage as we use it in a safe way that not require executing the reflection code. + // This is done by initializing the DisplayName in the context which is the part trigger reflection if it is not initialized. + OutLn($"[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage(\"Trimming\", \"IL2026:RequiresUnreferencedCode\","); + OutLn($" Justification = \"The created ValidationContext object is used in a way that never call reflection\")]"); + } + OutLn($"public {(makeStatic ? "static " : string.Empty)}global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, {modelToValidate.Name} options)"); OutOpenBrace(); OutLn($"global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null;"); - OutLn($"var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options);"); + OutLn($"var context = new {StaticValidationContextType}(options);"); int capacity = modelToValidate.MembersToValidate.Max(static vm => vm.ValidationAttributes.Count); if (capacity > 0) @@ -438,19 +841,5 @@ private StaticFieldInfo GetOrAddStaticValidator(ref Dictionary - /// Returns a non-randomized hash code for the given string. - /// We always return a positive value. - /// - internal static int GetNonRandomizedHashCode(string s) - { - uint result = 2166136261u; - foreach (char c in s) - { - result = (c ^ result) * 16777619; - } - return Math.Abs((int)result); - } } } diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Generator.cs b/src/libraries/Microsoft.Extensions.Options/gen/Generator.cs index 34533fc0a96b05..e9c1f55fcca512 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Generator.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/Generator.cs @@ -38,12 +38,14 @@ private static void HandleAnnotatedTypes(Compilation compilation, ImmutableArray return; } - var parser = new Parser(compilation, context.ReportDiagnostic, symbolHolder!, context.CancellationToken); + OptionsSourceGenContext optionsSourceGenContext = new(compilation); + + var parser = new Parser(compilation, context.ReportDiagnostic, symbolHolder!, optionsSourceGenContext, context.CancellationToken); var validatorTypes = parser.GetValidatorTypes(types); if (validatorTypes.Count > 0) { - var emitter = new Emitter(compilation); + var emitter = new Emitter(compilation, symbolHolder!, optionsSourceGenContext); var result = emitter.Emit(validatorTypes, context.CancellationToken); context.AddSource("Validators.g.cs", SourceText.From(result, Encoding.UTF8)); diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Microsoft.Extensions.Options.SourceGeneration.csproj b/src/libraries/Microsoft.Extensions.Options/gen/Microsoft.Extensions.Options.SourceGeneration.csproj index 5571341b06060e..f5bad279371755 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Microsoft.Extensions.Options.SourceGeneration.csproj +++ b/src/libraries/Microsoft.Extensions.Options/gen/Microsoft.Extensions.Options.SourceGeneration.csproj @@ -30,6 +30,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Options/gen/OptionsSourceGenContext.cs b/src/libraries/Microsoft.Extensions.Options/gen/OptionsSourceGenContext.cs new file mode 100644 index 00000000000000..8da3e317769627 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options/gen/OptionsSourceGenContext.cs @@ -0,0 +1,83 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.Versioning; + +namespace Microsoft.Extensions.Options.Generators +{ + internal sealed class OptionsSourceGenContext + { + public OptionsSourceGenContext(Compilation compilation) + { + IsLangVersion11AndAbove = ((CSharpCompilation)compilation).LanguageVersion >= Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp11; + ClassModifier = IsLangVersion11AndAbove ? "file" : "internal"; + Suffix = IsLangVersion11AndAbove ? "" : $"_{GetNonRandomizedHashCode(compilation.SourceModule.Name):X8}"; + } + + internal string Suffix { get; } + internal string ClassModifier { get; } + internal bool IsLangVersion11AndAbove { get; } + internal Dictionary?> AttributesToGenerate { get; set; } = new Dictionary?>(); + + internal void EnsureTrackingAttribute(string attributeName, bool createValue, out HashSet? value) + { + bool exist = AttributesToGenerate.TryGetValue(attributeName, out value); + if (value is null) + { + if (createValue) + { + value = new HashSet(); + } + + if (!exist || createValue) + { + AttributesToGenerate[attributeName] = value; + } + } + } + + internal static bool IsConvertibleBasicType(ITypeSymbol typeSymbol) + { + return typeSymbol.SpecialType switch + { + SpecialType.System_Boolean => true, + SpecialType.System_Byte => true, + SpecialType.System_Char => true, + SpecialType.System_DateTime => true, + SpecialType.System_Decimal => true, + SpecialType.System_Double => true, + SpecialType.System_Int16 => true, + SpecialType.System_Int32 => true, + SpecialType.System_Int64 => true, + SpecialType.System_SByte => true, + SpecialType.System_Single => true, + SpecialType.System_UInt16 => true, + SpecialType.System_UInt32 => true, + SpecialType.System_UInt64 => true, + SpecialType.System_String => true, + _ => false, + }; + } + + /// + /// Returns a non-randomized hash code for the given string. + /// We always return a positive value. + /// + internal static int GetNonRandomizedHashCode(string s) + { + uint result = 2166136261u; + foreach (char c in s) + { + result = (c ^ result) * 16777619; + } + + return Math.Abs((int)result); + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs b/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs index 010b89562a9179..47cb71c3411cde 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs @@ -25,6 +25,7 @@ internal sealed class Parser private readonly Compilation _compilation; private readonly Action _reportDiagnostic; private readonly SymbolHolder _symbolHolder; + private readonly OptionsSourceGenContext _optionsSourceGenContext; private readonly Dictionary _synthesizedValidators = new(SymbolEqualityComparer.Default); private readonly HashSet _visitedModelTypes = new(SymbolEqualityComparer.Default); @@ -32,12 +33,14 @@ public Parser( Compilation compilation, Action reportDiagnostic, SymbolHolder symbolHolder, + OptionsSourceGenContext optionsSourceGenContext, CancellationToken cancellationToken) { _compilation = compilation; _cancellationToken = cancellationToken; _reportDiagnostic = reportDiagnostic; _symbolHolder = symbolHolder; + _optionsSourceGenContext = optionsSourceGenContext; } public IReadOnlyList GetValidatorTypes(IEnumerable<(TypeDeclarationSyntax TypeSyntax, SemanticModel SemanticModel)> classes) @@ -288,7 +291,7 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s ? memberLocation : lowerLocationInCompilation; - var memberInfo = GetMemberInfo(member, speculate, location, validatorType); + var memberInfo = GetMemberInfo(member, speculate, location, modelType, validatorType); if (memberInfo is not null) { if (member.DeclaredAccessibility != Accessibility.Public) @@ -304,7 +307,7 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s return membersToValidate; } - private ValidatedMember? GetMemberInfo(ISymbol member, bool speculate, Location location, ITypeSymbol validatorType) + private ValidatedMember? GetMemberInfo(ISymbol member, bool speculate, Location location, ITypeSymbol modelType, ITypeSymbol validatorType) { ITypeSymbol memberType; switch (member) @@ -325,7 +328,7 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s break; */ default: - // we only care about properties and fields + // we only care about properties return null; } @@ -467,7 +470,26 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s continue; } - var validationAttr = new ValidationAttributeInfo(attributeType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)); + string attributeFullQualifiedName = attributeType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); + if (SymbolEqualityComparer.Default.Equals(attributeType, _symbolHolder.MaxLengthAttributeSymbol) || + SymbolEqualityComparer.Default.Equals(attributeType, _symbolHolder.MinLengthAttributeSymbol) || + (_symbolHolder.LengthAttributeSymbol is not null && SymbolEqualityComparer.Default.Equals(attributeType, _symbolHolder.LengthAttributeSymbol))) + { + if (!LengthBasedAttributeIsTrackedForSubstitution(memberType, location, attributeType, ref attributeFullQualifiedName)) + { + continue; + } + } + else if (SymbolEqualityComparer.Default.Equals(attributeType, _symbolHolder.CompareAttributeSymbol)) + { + TrackCompareAttributeForSubstitution(attribute, modelType, ref attributeFullQualifiedName); + } + else if (SymbolEqualityComparer.Default.Equals(attributeType, _symbolHolder.RangeAttributeSymbol)) + { + TrackRangeAttributeForSubstitution(attribute, memberType, ref attributeFullQualifiedName); + } + + var validationAttr = new ValidationAttributeInfo(attributeFullQualifiedName); validationAttrs.Add(validationAttr); ImmutableArray parameters = attribute.AttributeConstructor?.Parameters ?? ImmutableArray.Empty; @@ -567,6 +589,79 @@ private List GetMembersToValidate(ITypeSymbol modelType, bool s return null; } + private bool LengthBasedAttributeIsTrackedForSubstitution(ITypeSymbol memberType, Location location, ITypeSymbol attributeType, ref string attributeFullQualifiedName) + { + if (memberType.SpecialType == SpecialType.System_String || ConvertTo(memberType, _symbolHolder.ICollectionSymbol)) + { + _optionsSourceGenContext.EnsureTrackingAttribute(attributeType.Name, createValue: false, out _); + } + else if (ParserUtilities.TypeHasProperty(memberType, "Count", SpecialType.System_Int32)) + { + _optionsSourceGenContext.EnsureTrackingAttribute(attributeType.Name, createValue: true, out HashSet? trackedTypeList); + trackedTypeList!.Add(memberType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)); + } + else + { + Diag(DiagDescriptors.IncompatibleWithTypeForValidationAttribute, location, attributeType.Name, memberType.Name); + return false; + } + + attributeFullQualifiedName = $"{Emitter.StaticGeneratedValidationAttributesClassesNamespace}.{Emitter.StaticAttributeClassNamePrefix}{_optionsSourceGenContext.Suffix}_{attributeType.Name}"; + return true; + } + + private void TrackCompareAttributeForSubstitution(AttributeData attribute, ITypeSymbol modelType, ref string attributeFullQualifiedName) + { + ImmutableArray constructorParameters = attribute.AttributeConstructor?.Parameters ?? ImmutableArray.Empty; + if (constructorParameters.Length == 1 && constructorParameters[0].Name == "otherProperty" && constructorParameters[0].Type.SpecialType == SpecialType.System_String) + { + _optionsSourceGenContext.EnsureTrackingAttribute(attribute.AttributeClass!.Name, createValue: true, out HashSet? trackedTypeList); + trackedTypeList!.Add((modelType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), (string)attribute.ConstructorArguments[0].Value!)); + attributeFullQualifiedName = $"{Emitter.StaticGeneratedValidationAttributesClassesNamespace}.{Emitter.StaticAttributeClassNamePrefix}{_optionsSourceGenContext.Suffix}_{attribute.AttributeClass!.Name}"; + } + } + + private void TrackRangeAttributeForSubstitution(AttributeData attribute, ITypeSymbol memberType, ref string attributeFullQualifiedName) + { + ImmutableArray constructorParameters = attribute.AttributeConstructor?.Parameters ?? ImmutableArray.Empty; + SpecialType argumentSpecialType = SpecialType.None; + if (constructorParameters.Length == 2) + { + argumentSpecialType = constructorParameters[0].Type.SpecialType; + } + else if (constructorParameters.Length == 3) + { + object? argumentValue = null; + for (int i = 0; i < constructorParameters.Length; i++) + { + if (constructorParameters[i].Name == "type") + { + argumentValue = attribute.ConstructorArguments[i].Value; + break; + } + } + + if (argumentValue is INamedTypeSymbol namedTypeSymbol && OptionsSourceGenContext.IsConvertibleBasicType(namedTypeSymbol)) + { + argumentSpecialType = namedTypeSymbol.SpecialType; + } + } + + ITypeSymbol typeSymbol = memberType; + if (typeSymbol.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) + { + typeSymbol = ((INamedTypeSymbol)typeSymbol).TypeArguments[0]; + } + + if (argumentSpecialType != SpecialType.None && + OptionsSourceGenContext.IsConvertibleBasicType(typeSymbol) && + (constructorParameters.Length != 3 || typeSymbol.SpecialType == argumentSpecialType)) // When type is provided as a parameter, it has to match the property type. + { + _optionsSourceGenContext.EnsureTrackingAttribute(attribute.AttributeClass!.Name, createValue: false, out _); + attributeFullQualifiedName = $"{Emitter.StaticGeneratedValidationAttributesClassesNamespace}.{Emitter.StaticAttributeClassNamePrefix}{_optionsSourceGenContext.Suffix}_{attribute.AttributeClass!.Name}"; + } + } + private string? AddSynthesizedValidator(ITypeSymbol modelType, ISymbol member, Location location, ITypeSymbol validatorType) { var mt = modelType.WithNullableAnnotation(NullableAnnotation.None); diff --git a/src/libraries/Microsoft.Extensions.Options/gen/ParserUtilities.cs b/src/libraries/Microsoft.Extensions.Options/gen/ParserUtilities.cs index d79ad4cccb653d..675202538e12d2 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/ParserUtilities.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/ParserUtilities.cs @@ -68,6 +68,29 @@ internal static bool ImplementsInterface(this ITypeSymbol type, ITypeSymbol inte return false; } + internal static bool TypeHasProperty(ITypeSymbol typeSymbol, string propertyName, SpecialType returnType) + { + ITypeSymbol? type = typeSymbol; + do + { + if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) + { + type = ((INamedTypeSymbol)type).TypeArguments[0]; // extract the T from a Nullable + } + + if (type.GetMembers(propertyName).OfType().Any(property => + property.Type.SpecialType == returnType && property.DeclaredAccessibility == Accessibility.Public && + !property.IsStatic && property.GetMethod != null && property.Parameters.IsEmpty)) + { + return true; + } + + type = type.BaseType; + } while (type is not null && type.SpecialType != SpecialType.System_Object); + + return false; + } + // Check if parameter has either simplified (i.e. "int?") or explicit (Nullable) nullable type declaration: internal static bool IsNullableOfT(this ITypeSymbol type) => type.SpecialType == SpecialType.System_Nullable_T || type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T; diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Options/gen/Resources/Strings.resx index 6293431eb7f90e..7100030eecf132 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/Strings.resx @@ -213,4 +213,10 @@ The options validation source generator is not available in C# {0}. Please use language version {1} or greater. + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf index 953376c434d310..77769cb3ca4ab2 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf @@ -152,6 +152,16 @@ U člena potenciálně chybí přenositelné ověření. + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + Validator type {0} doesn't have a parameterless constructor. Typ validátoru {0} nemá konstruktor bez parametrů. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf index bbd4d29cfc247e..e5defa5eeb3e2f 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf @@ -152,6 +152,16 @@ Dem Member fehlt möglicherweise die transitive Validierung. + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + Validator type {0} doesn't have a parameterless constructor. Der Validierungssteuerelementtyp "{0}" hat keinen parameterlosen Konstruktor. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf index 0c4661573bbd40..728e01d7b598a9 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf @@ -152,6 +152,16 @@ Posiblemente falta la validación transitiva en el miembro. + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + Validator type {0} doesn't have a parameterless constructor. El tipo de validador {0} no tiene un constructor sin parámetros. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf index e1996eeca163cd..d7f738a55f661c 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf @@ -152,6 +152,16 @@ Le membre n’a peut-être pas de validation transitive. + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + Validator type {0} doesn't have a parameterless constructor. Le type de validateur {0} n’a pas de constructeur sans paramètre. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf index edcf16b967dd32..d3903a95f055cf 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf @@ -152,6 +152,16 @@ Il membro potrebbe non avere una convalida transitiva. + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + Validator type {0} doesn't have a parameterless constructor. Il tipo di convalida {0} non dispone di un costruttore senza parametri. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf index 89b2f23777fb2c..2afc63bf19fda0 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf @@ -152,6 +152,16 @@ メンバーに推移性の検証がない可能性があります。 + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + Validator type {0} doesn't have a parameterless constructor. バリデーター型 {0} にパラメーターなしのコンストラクターがありません。 diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf index 817bc64eba8ac4..6bb342f5931541 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf @@ -152,6 +152,16 @@ 멤버에 전이적 유효성 검사가 누락되었을 수 있습니다. + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + Validator type {0} doesn't have a parameterless constructor. 유효성 검사기 형식 {0}은(는) 매개 변수가 없는 생성자가 없습니다. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf index 190ca17b561792..1262d4d0852b49 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf @@ -152,6 +152,16 @@ W przypadku elementu członkowskiego może potencjalnie brakować weryfikacji przechodniej. + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + Validator type {0} doesn't have a parameterless constructor. Typ modułu sprawdzania poprawności {0} nie ma konstruktora bez parametrów. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf index 24a4203391c016..ced617baa9556c 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf @@ -152,6 +152,16 @@ Membro potencialmente ausente na validação transitiva. + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + Validator type {0} doesn't have a parameterless constructor. O tipo de validador {0} não tem um construtor sem parâmetros. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf index f14d71833a2355..cf3c21772acf20 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf @@ -152,6 +152,16 @@ Возможно, в элементе отсутствует транзитивная проверка. + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + Validator type {0} doesn't have a parameterless constructor. Тип проверяющего элемента управления {0} не имеет конструктора без параметров. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf index 79e094b36b3122..b9545e2def86bc 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf @@ -152,6 +152,16 @@ Üyede geçişli doğrulama eksik olabilir. + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + Validator type {0} doesn't have a parameterless constructor. {0} doğrulayıcı türü parametresiz bir oluşturucuya sahip değil. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf index 7688e0e628811f..98d7e55197f659 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -152,6 +152,16 @@ 成员可能缺少可传递验证。 + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + Validator type {0} doesn't have a parameterless constructor. 验证程序类型 {0} 没有无参数构造函数。 diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf index 663bff9c183861..a3b9657f861b08 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -152,6 +152,16 @@ 成員可能遺漏轉移的驗證。 + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + Validator type {0} doesn't have a parameterless constructor. 驗證程式類型 {0} 沒有無參數建構函式。 diff --git a/src/libraries/Microsoft.Extensions.Options/gen/SymbolHolder.cs b/src/libraries/Microsoft.Extensions.Options/gen/SymbolHolder.cs index 55d382e4036219..3447a07d398305 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/SymbolHolder.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/SymbolHolder.cs @@ -11,6 +11,13 @@ namespace Microsoft.Extensions.Options.Generators internal sealed record class SymbolHolder( INamedTypeSymbol OptionsValidatorSymbol, INamedTypeSymbol ValidationAttributeSymbol, + INamedTypeSymbol MaxLengthAttributeSymbol, + INamedTypeSymbol MinLengthAttributeSymbol, + INamedTypeSymbol CompareAttributeSymbol, + INamedTypeSymbol? LengthAttributeSymbol, + INamedTypeSymbol? UnconditionalSuppressMessageAttributeSymbol, + INamedTypeSymbol RangeAttributeSymbol, + INamedTypeSymbol ICollectionSymbol, INamedTypeSymbol DataTypeAttributeSymbol, INamedTypeSymbol ValidateOptionsSymbol, INamedTypeSymbol IValidatableObjectSymbol, diff --git a/src/libraries/Microsoft.Extensions.Options/gen/SymbolLoader.cs b/src/libraries/Microsoft.Extensions.Options/gen/SymbolLoader.cs index 94035cedacbf98..ea556228929756 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/SymbolLoader.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/SymbolLoader.cs @@ -9,6 +9,12 @@ internal static class SymbolLoader { public const string OptionsValidatorAttribute = "Microsoft.Extensions.Options.OptionsValidatorAttribute"; internal const string ValidationAttribute = "System.ComponentModel.DataAnnotations.ValidationAttribute"; + internal const string MaxLengthAttribute = "System.ComponentModel.DataAnnotations.MaxLengthAttribute"; + internal const string MinLengthAttribute = "System.ComponentModel.DataAnnotations.MinLengthAttribute"; + internal const string CompareAttribute = "System.ComponentModel.DataAnnotations.CompareAttribute"; + internal const string LengthAttribute = "System.ComponentModel.DataAnnotations.LengthAttribute"; + internal const string RangeAttribute = "System.ComponentModel.DataAnnotations.RangeAttribute"; + internal const string ICollectionType = "System.Collections.ICollection"; internal const string DataTypeAttribute = "System.ComponentModel.DataAnnotations.DataTypeAttribute"; internal const string IValidatableObjectType = "System.ComponentModel.DataAnnotations.IValidatableObject"; internal const string IValidateOptionsType = "Microsoft.Extensions.Options.IValidateOptions`1"; @@ -16,6 +22,7 @@ internal static class SymbolLoader internal const string ValidateObjectMembersAttribute = "Microsoft.Extensions.Options.ValidateObjectMembersAttribute"; internal const string ValidateEnumeratedItemsAttribute = "Microsoft.Extensions.Options.ValidateEnumeratedItemsAttribute"; internal const string GenericIEnumerableType = "System.Collections.Generic.IEnumerable`1"; + internal const string UnconditionalSuppressMessageAttributeType = "System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute"; public static bool TryLoad(Compilation compilation, out SymbolHolder? symbolHolder) { @@ -24,6 +31,12 @@ public static bool TryLoad(Compilation compilation, out SymbolHolder? symbolHold // required var optionsValidatorSymbol = GetSymbol(OptionsValidatorAttribute); var validationAttributeSymbol = GetSymbol(ValidationAttribute); + var maxLengthAttributeSymbol = GetSymbol(MaxLengthAttribute); + var minLengthAttributeSymbol = GetSymbol(MinLengthAttribute); + var compareAttributeSymbol = GetSymbol(CompareAttribute); + var lengthAttributeSymbol = GetSymbol(LengthAttribute); + var rangeAttributeSymbol = GetSymbol(RangeAttribute); + var iCollectionSymbol = GetSymbol(ICollectionType); var dataTypeAttributeSymbol = GetSymbol(DataTypeAttribute); var ivalidatableObjectSymbol = GetSymbol(IValidatableObjectType); var validateOptionsSymbol = GetSymbol(IValidateOptionsType); @@ -31,10 +44,27 @@ public static bool TryLoad(Compilation compilation, out SymbolHolder? symbolHold var typeSymbol = GetSymbol(TypeOfType); var validateObjectMembersAttribute = GetSymbol(ValidateObjectMembersAttribute); var validateEnumeratedItemsAttribute = GetSymbol(ValidateEnumeratedItemsAttribute); + var unconditionalSuppressMessageAttributeSymbol = GetSymbol(UnconditionalSuppressMessageAttributeType); + if (unconditionalSuppressMessageAttributeSymbol is not null) + { + var containingAssemblyName = unconditionalSuppressMessageAttributeSymbol.ContainingAssembly.Identity.Name; + if (!containingAssemblyName.Equals("System.Private.CoreLib", System.StringComparison.OrdinalIgnoreCase) && + !containingAssemblyName.Equals("System.Runtime", System.StringComparison.OrdinalIgnoreCase)) + { + // The compilation returns UnconditionalSuppressMessageAttribute symbol even if the attribute is not available like the case when running on .NET Framework. + // We need to make sure that the attribute is really available by checking the containing assembly which in .NET Core will be either System.Private.CoreLib or System.Runtime. + unconditionalSuppressMessageAttributeSymbol = null; + } + } #pragma warning disable S1067 // Expressions should not be too complex if (optionsValidatorSymbol == null || validationAttributeSymbol == null || + maxLengthAttributeSymbol == null || + minLengthAttributeSymbol == null || + compareAttributeSymbol == null || + rangeAttributeSymbol == null || + iCollectionSymbol == null || dataTypeAttributeSymbol == null || ivalidatableObjectSymbol == null || validateOptionsSymbol == null || @@ -51,6 +81,13 @@ public static bool TryLoad(Compilation compilation, out SymbolHolder? symbolHold symbolHolder = new( optionsValidatorSymbol, validationAttributeSymbol, + maxLengthAttributeSymbol, + minLengthAttributeSymbol, + compareAttributeSymbol, + lengthAttributeSymbol, + unconditionalSuppressMessageAttributeSymbol, + rangeAttributeSymbol, + iCollectionSymbol, dataTypeAttributeSymbol, validateOptionsSymbol, ivalidatableObjectSymbol, diff --git a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj index 7225edf84ba537..c7ea3e00049e3e 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj +++ b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj @@ -28,12 +28,13 @@ - + diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/DataAnnotationAttributesWithParams.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/DataAnnotationAttributesWithParams.g.cs new file mode 100644 index 00000000000000..c51c551222f42f --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/DataAnnotationAttributesWithParams.g.cs @@ -0,0 +1,135 @@ + + // + #nullable enable + #pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103 + namespace Test +{ + partial class MyOptionsValidator + { + /// + /// Validates a specific named options instance (or all when is ). + /// + /// The name of the options instance being validated. + /// The options instance. + /// Validation result. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] + public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Test.MyOptions options) + { + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; + var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); + var validationResults = new global::System.Collections.Generic.List(); + var validationAttributes = new global::System.Collections.Generic.List(1); + + context.MemberName = "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P1" : $"{name}.P1"; + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P2" : $"{name}.P2"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P3" : $"{name}.P3"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P4" : $"{name}.P4"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A4); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); + } + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Attributes + { + internal static readonly global::System.ComponentModel.DataAnnotations.RequiredAttribute A1 = new global::System.ComponentModel.DataAnnotations.RequiredAttribute(); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__LengthAttribute A2 = new __OptionValidationGeneratedAttributes.__SourceGen__LengthAttribute( + (int)10, + (int)20); + + internal static readonly global::System.ComponentModel.DataAnnotations.AllowedValuesAttribute A3 = new global::System.ComponentModel.DataAnnotations.AllowedValuesAttribute( + (int)10, (int)20, (int)30); + + internal static readonly global::System.ComponentModel.DataAnnotations.DeniedValuesAttribute A4 = new global::System.ComponentModel.DataAnnotations.DeniedValuesAttribute( + "One", "Ten", "Hundred"); + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Validators + { + } +} +namespace __OptionValidationGeneratedAttributes +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__LengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "The field {0} must be a string or collection type with a minimum length of '{1}' and maximum length of '{2}'."; + public __SourceGen__LengthAttribute(int minimumLength, int maximumLength) : base(() => DefaultErrorMessageString) { MinimumLength = minimumLength; MaximumLength = maximumLength; } + public int MinimumLength { get; } + public int MaximumLength { get; } + public override bool IsValid(object? value) + { + if (MinimumLength < 0) + { + throw new global::System.InvalidOperationException("LengthAttribute must have a MinimumLength value that is zero or greater."); + } + if (MaximumLength < MinimumLength) + { + throw new global::System.InvalidOperationException("LengthAttribute must have a MaximumLength value that is greater than or equal to MinimumLength."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return (uint)(length - MinimumLength) <= (uint)(MaximumLength - MinimumLength); + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, MinimumLength, MaximumLength); + } +} diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netcore.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netcore.g.cs new file mode 100644 index 00000000000000..2c5af12c5b5f24 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netcore.g.cs @@ -0,0 +1,175 @@ + + // + #nullable enable + #pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103 + namespace HelloWorld +{ + partial struct MyOptionsValidator + { + /// + /// Validates a specific named options instance (or all when is ). + /// + /// The name of the options instance being validated. + /// The options instance. + /// Validation result. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] + public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::HelloWorld.MyOptions options) + { + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; + var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); + var validationResults = new global::System.Collections.Generic.List(); + var validationAttributes = new global::System.Collections.Generic.List(1); + + context.MemberName = "Val1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.Val1" : $"{name}.Val1"; + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "Val2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.Val2" : $"{name}.Val2"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); + } + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Attributes + { + internal static readonly global::System.ComponentModel.DataAnnotations.RequiredAttribute A1 = new global::System.ComponentModel.DataAnnotations.RequiredAttribute(); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A2 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( + (int)1, + (int)3); + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Validators + { + } +} +namespace __OptionValidationGeneratedAttributes +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__RangeAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + public __SourceGen__RangeAttribute(int minimum, int maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(int); + } + public __SourceGen__RangeAttribute(double minimum, double maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(double); + } + public __SourceGen__RangeAttribute(global::System.Type type, string minimum, string maximum) : base() + { + OperandType = type; + NeedToConvertMinMax = true; + Minimum = minimum; + Maximum = maximum; + } + public object Minimum { get; private set; } + public object Maximum { get; private set; } + public bool MinimumIsExclusive { get; set; } + public bool MaximumIsExclusive { get; set; } + public global::System.Type OperandType { get; } + public bool ParseLimitsInInvariantCulture { get; set; } + public bool ConvertValueInInvariantCulture { get; set; } + public override string FormatErrorMessage(string name) => + string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); + private bool NeedToConvertMinMax { get; } + private bool Initialized { get; set; } + public override bool IsValid(object? value) + { + if (!Initialized) + { + if (Minimum is null || Maximum is null) + { + throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + if (NeedToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + Initialized = true; + } + + if (value is null or string { Length: 0 }) + { + return true; + } + + System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + object? convertedValue; + + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } + + var min = (global::System.IComparable)Minimum; + var max = (global::System.IComparable)Maximum; + + return + (MinimumIsExclusive ? min.CompareTo(convertedValue) < 0 : min.CompareTo(convertedValue) <= 0) && + (MaximumIsExclusive ? max.CompareTo(convertedValue) > 0 : max.CompareTo(convertedValue) >= 0); + } + private string GetValidationErrorMessage() + { + return (MinimumIsExclusive, MaximumIsExclusive) switch + { + (false, false) => "The field {0} must be between {1} and {2}.", + (true, false) => "The field {0} must be between {1} exclusive and {2}.", + (false, true) => "The field {0} must be between {1} and {2} exclusive.", + (true, true) => "The field {0} must be between {1} exclusive and {2} exclusive.", + }; + } + private object? ConvertValue(object? value, System.Globalization.CultureInfo formatProvider) + { + if (value is string stringValue) + { + value = global::System.Convert.ChangeType(stringValue, OperandType, formatProvider); + } + else + { + value = global::System.Convert.ChangeType(value, OperandType, formatProvider); + } + return value; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netfx.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netfx.g.cs new file mode 100644 index 00000000000000..9dc3ded5bd4624 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netfx.g.cs @@ -0,0 +1,173 @@ + + // + #nullable enable + #pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103 + namespace HelloWorld +{ + partial struct MyOptionsValidator + { + /// + /// Validates a specific named options instance (or all when is ). + /// + /// The name of the options instance being validated. + /// The options instance. + /// Validation result. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::HelloWorld.MyOptions options) + { + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; + var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); + var validationResults = new global::System.Collections.Generic.List(); + var validationAttributes = new global::System.Collections.Generic.List(1); + + context.MemberName = "Val1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.Val1" : $"{name}.Val1"; + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "Val2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.Val2" : $"{name}.Val2"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); + } + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Attributes + { + internal static readonly global::System.ComponentModel.DataAnnotations.RequiredAttribute A1 = new global::System.ComponentModel.DataAnnotations.RequiredAttribute(); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A2 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( + (int)1, + (int)3); + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Validators + { + } +} +namespace __OptionValidationGeneratedAttributes +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__RangeAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + public __SourceGen__RangeAttribute(int minimum, int maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(int); + } + public __SourceGen__RangeAttribute(double minimum, double maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(double); + } + public __SourceGen__RangeAttribute(global::System.Type type, string minimum, string maximum) : base() + { + OperandType = type; + NeedToConvertMinMax = true; + Minimum = minimum; + Maximum = maximum; + } + public object Minimum { get; private set; } + public object Maximum { get; private set; } + public bool MinimumIsExclusive { get; set; } + public bool MaximumIsExclusive { get; set; } + public global::System.Type OperandType { get; } + public bool ParseLimitsInInvariantCulture { get; set; } + public bool ConvertValueInInvariantCulture { get; set; } + public override string FormatErrorMessage(string name) => + string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); + private bool NeedToConvertMinMax { get; } + private bool Initialized { get; set; } + public override bool IsValid(object? value) + { + if (!Initialized) + { + if (Minimum is null || Maximum is null) + { + throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + if (NeedToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + Initialized = true; + } + + if (value is null or string { Length: 0 }) + { + return true; + } + + System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + object? convertedValue; + + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } + + var min = (global::System.IComparable)Minimum; + var max = (global::System.IComparable)Maximum; + + return + (MinimumIsExclusive ? min.CompareTo(convertedValue) < 0 : min.CompareTo(convertedValue) <= 0) && + (MaximumIsExclusive ? max.CompareTo(convertedValue) > 0 : max.CompareTo(convertedValue) >= 0); + } + private string GetValidationErrorMessage() + { + return (MinimumIsExclusive, MaximumIsExclusive) switch + { + (false, false) => "The field {0} must be between {1} and {2}.", + (true, false) => "The field {0} must be between {1} exclusive and {2}.", + (false, true) => "The field {0} must be between {1} and {2} exclusive.", + (true, true) => "The field {0} must be between {1} exclusive and {2} exclusive.", + }; + } + private object? ConvertValue(object? value, System.Globalization.CultureInfo formatProvider) + { + if (value is string stringValue) + { + value = global::System.Convert.ChangeType(stringValue, OperandType, formatProvider); + } + else + { + value = global::System.Convert.ChangeType(value, OperandType, formatProvider); + } + return value; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang10.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang10.g.cs new file mode 100644 index 00000000000000..cc9864a2619c45 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang10.g.cs @@ -0,0 +1,471 @@ + + // + #nullable enable + #pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103 + namespace ValidationTest +{ + partial class OptionsUsingGeneratedAttributesValidator + { + /// + /// Validates a specific named options instance (or all when is ). + /// + /// The name of the options instance being validated. + /// The options instance. + /// Validation result. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] + public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::ValidationTest.OptionsUsingGeneratedAttributes options) + { + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; + var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); + var validationResults = new global::System.Collections.Generic.List(); + var validationAttributes = new global::System.Collections.Generic.List(1); + + context.MemberName = "P0"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P0" : $"{name}.P0"; + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P0, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P1" : $"{name}.P1"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P2" : $"{name}.P2"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P3" : $"{name}.P3"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P4" : $"{name}.P4"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P5" : $"{name}.P5"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A4); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P6" : $"{name}.P6"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A5); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P7"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P7" : $"{name}.P7"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P7, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P8"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P8" : $"{name}.P8"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P8, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P9"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P9" : $"{name}.P9"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A4); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P9, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P10"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P10" : $"{name}.P10"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A4); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P10, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P11"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P11" : $"{name}.P11"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P11, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P12"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P12" : $"{name}.P12"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A4); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P12, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); + } + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + internal static class __Attributes_2C497155 + { + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_LengthAttribute A1 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_LengthAttribute( + (int)1, + (int)3); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_RangeAttribute A2 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_RangeAttribute( + (int)1, + (int)3); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_MinLengthAttribute A3 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_MinLengthAttribute( + (int)5); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_MaxLengthAttribute A4 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_MaxLengthAttribute( + (int)5); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_CompareAttribute A5 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_CompareAttribute( + "P5"); + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + internal static class __Validators_2C497155 + { + } +} +namespace __OptionValidationGeneratedAttributes +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property, AllowMultiple = false)] + internal class __SourceGen__2C497155_CompareAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "'{0}' and '{1}' do not match."; + public __SourceGen__2C497155_CompareAttribute(string otherProperty) : base(() => DefaultErrorMessageString) + { + if (otherProperty == null) + { + throw new global::System.ArgumentNullException(nameof(otherProperty)); + } + OtherProperty = otherProperty; + } + public string OtherProperty { get; } + public override bool RequiresValidationContext => true; + + protected override global::System.ComponentModel.DataAnnotations.ValidationResult? IsValid(object? value, global::System.ComponentModel.DataAnnotations.ValidationContext validationContext) + { + bool result = true; + + if (validationContext.ObjectInstance is global::ValidationTest.OptionsUsingGeneratedAttributes && OtherProperty == "P5") + { + result = Equals(value, ((global::ValidationTest.OptionsUsingGeneratedAttributes)validationContext.ObjectInstance).P5); + } + + if (!result) + { + string[]? memberNames = validationContext.MemberName is null ? null : new string[] { validationContext.MemberName }; + return new global::System.ComponentModel.DataAnnotations.ValidationResult(FormatErrorMessage(validationContext.DisplayName), memberNames); + } + + return null; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, OtherProperty); + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + internal class __SourceGen__2C497155_LengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "The field {0} must be a string or collection type with a minimum length of '{1}' and maximum length of '{2}'."; + public __SourceGen__2C497155_LengthAttribute(int minimumLength, int maximumLength) : base(() => DefaultErrorMessageString) { MinimumLength = minimumLength; MaximumLength = maximumLength; } + public int MinimumLength { get; } + public int MaximumLength { get; } + public override bool IsValid(object? value) + { + if (MinimumLength < 0) + { + throw new global::System.InvalidOperationException("LengthAttribute must have a MinimumLength value that is zero or greater."); + } + if (MaximumLength < MinimumLength) + { + throw new global::System.InvalidOperationException("LengthAttribute must have a MaximumLength value that is greater than or equal to MinimumLength."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::ValidationTest.FakeCount) + { + length = ((global::ValidationTest.FakeCount)value).Count; + } + else if (value is global::ValidationTest.FakeCountChild) + { + length = ((global::ValidationTest.FakeCountChild)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return (uint)(length - MinimumLength) <= (uint)(MaximumLength - MinimumLength); + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, MinimumLength, MaximumLength); + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + internal class __SourceGen__2C497155_MaxLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private const int MaxAllowableLength = -1; + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a maximum length of '{1}'."; + public __SourceGen__2C497155_MaxLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public __SourceGen__2C497155_MaxLengthAttribute(): base(() => DefaultErrorMessageString) { Length = MaxAllowableLength; } + public int Length { get; } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + public override bool IsValid(object? value) + { + if (Length == 0 || Length < -1) + { + throw new global::System.InvalidOperationException("MaxLengthAttribute must have a Length value that is greater than zero. Use MaxLength() without parameters to indicate that the string or array can have the maximum allowable length."); + } + if (value == null || MaxAllowableLength == Length) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::ValidationTest.FakeCount) + { + length = ((global::ValidationTest.FakeCount)value).Count; + } + else if (value is global::ValidationTest.FakeCountChild) + { + length = ((global::ValidationTest.FakeCountChild)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length <= Length; + } + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + internal class __SourceGen__2C497155_MinLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a minimum length of '{1}'."; + + public __SourceGen__2C497155_MinLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public int Length { get; } + public override bool IsValid(object? value) + { + if (Length < -1) + { + throw new global::System.InvalidOperationException("MinLengthAttribute must have a Length value that is zero or greater."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::ValidationTest.FakeCount) + { + length = ((global::ValidationTest.FakeCount)value).Count; + } + else if (value is global::ValidationTest.FakeCountChild) + { + length = ((global::ValidationTest.FakeCountChild)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length >= Length; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + internal class __SourceGen__2C497155_RangeAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + public __SourceGen__2C497155_RangeAttribute(int minimum, int maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(int); + } + public __SourceGen__2C497155_RangeAttribute(double minimum, double maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(double); + } + public __SourceGen__2C497155_RangeAttribute(global::System.Type type, string minimum, string maximum) : base() + { + OperandType = type; + NeedToConvertMinMax = true; + Minimum = minimum; + Maximum = maximum; + } + public object Minimum { get; private set; } + public object Maximum { get; private set; } + public bool MinimumIsExclusive { get; set; } + public bool MaximumIsExclusive { get; set; } + public global::System.Type OperandType { get; } + public bool ParseLimitsInInvariantCulture { get; set; } + public bool ConvertValueInInvariantCulture { get; set; } + public override string FormatErrorMessage(string name) => + string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); + private bool NeedToConvertMinMax { get; } + private bool Initialized { get; set; } + public override bool IsValid(object? value) + { + if (!Initialized) + { + if (Minimum is null || Maximum is null) + { + throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + if (NeedToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + Initialized = true; + } + + if (value is null or string { Length: 0 }) + { + return true; + } + + System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + object? convertedValue; + + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } + + var min = (global::System.IComparable)Minimum; + var max = (global::System.IComparable)Maximum; + + return + (MinimumIsExclusive ? min.CompareTo(convertedValue) < 0 : min.CompareTo(convertedValue) <= 0) && + (MaximumIsExclusive ? max.CompareTo(convertedValue) > 0 : max.CompareTo(convertedValue) >= 0); + } + private string GetValidationErrorMessage() + { + return (MinimumIsExclusive, MaximumIsExclusive) switch + { + (false, false) => "The field {0} must be between {1} and {2}.", + (true, false) => "The field {0} must be between {1} exclusive and {2}.", + (false, true) => "The field {0} must be between {1} and {2} exclusive.", + (true, true) => "The field {0} must be between {1} exclusive and {2} exclusive.", + }; + } + private object? ConvertValue(object? value, System.Globalization.CultureInfo formatProvider) + { + if (value is string stringValue) + { + value = global::System.Convert.ChangeType(stringValue, OperandType, formatProvider); + } + else + { + value = global::System.Convert.ChangeType(value, OperandType, formatProvider); + } + return value; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang11.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang11.g.cs new file mode 100644 index 00000000000000..2a33e51b0b6175 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang11.g.cs @@ -0,0 +1,471 @@ + + // + #nullable enable + #pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103 + namespace ValidationTest +{ + partial class OptionsUsingGeneratedAttributesValidator + { + /// + /// Validates a specific named options instance (or all when is ). + /// + /// The name of the options instance being validated. + /// The options instance. + /// Validation result. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] + public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::ValidationTest.OptionsUsingGeneratedAttributes options) + { + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; + var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); + var validationResults = new global::System.Collections.Generic.List(); + var validationAttributes = new global::System.Collections.Generic.List(1); + + context.MemberName = "P0"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P0" : $"{name}.P0"; + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P0, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P1" : $"{name}.P1"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P2" : $"{name}.P2"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P3" : $"{name}.P3"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P4" : $"{name}.P4"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P5" : $"{name}.P5"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A4); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P6" : $"{name}.P6"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A5); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P7"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P7" : $"{name}.P7"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P7, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P8"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P8" : $"{name}.P8"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P8, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P9"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P9" : $"{name}.P9"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A4); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P9, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P10"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P10" : $"{name}.P10"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A4); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P10, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P11"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P11" : $"{name}.P11"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P11, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P12"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P12" : $"{name}.P12"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A4); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P12, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); + } + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Attributes + { + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__LengthAttribute A1 = new __OptionValidationGeneratedAttributes.__SourceGen__LengthAttribute( + (int)1, + (int)3); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A2 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( + (int)1, + (int)3); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__MinLengthAttribute A3 = new __OptionValidationGeneratedAttributes.__SourceGen__MinLengthAttribute( + (int)5); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__MaxLengthAttribute A4 = new __OptionValidationGeneratedAttributes.__SourceGen__MaxLengthAttribute( + (int)5); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__CompareAttribute A5 = new __OptionValidationGeneratedAttributes.__SourceGen__CompareAttribute( + "P5"); + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Validators + { + } +} +namespace __OptionValidationGeneratedAttributes +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property, AllowMultiple = false)] + file class __SourceGen__CompareAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "'{0}' and '{1}' do not match."; + public __SourceGen__CompareAttribute(string otherProperty) : base(() => DefaultErrorMessageString) + { + if (otherProperty == null) + { + throw new global::System.ArgumentNullException(nameof(otherProperty)); + } + OtherProperty = otherProperty; + } + public string OtherProperty { get; } + public override bool RequiresValidationContext => true; + + protected override global::System.ComponentModel.DataAnnotations.ValidationResult? IsValid(object? value, global::System.ComponentModel.DataAnnotations.ValidationContext validationContext) + { + bool result = true; + + if (validationContext.ObjectInstance is global::ValidationTest.OptionsUsingGeneratedAttributes && OtherProperty == "P5") + { + result = Equals(value, ((global::ValidationTest.OptionsUsingGeneratedAttributes)validationContext.ObjectInstance).P5); + } + + if (!result) + { + string[]? memberNames = validationContext.MemberName is null ? null : new string[] { validationContext.MemberName }; + return new global::System.ComponentModel.DataAnnotations.ValidationResult(FormatErrorMessage(validationContext.DisplayName), memberNames); + } + + return null; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, OtherProperty); + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__LengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "The field {0} must be a string or collection type with a minimum length of '{1}' and maximum length of '{2}'."; + public __SourceGen__LengthAttribute(int minimumLength, int maximumLength) : base(() => DefaultErrorMessageString) { MinimumLength = minimumLength; MaximumLength = maximumLength; } + public int MinimumLength { get; } + public int MaximumLength { get; } + public override bool IsValid(object? value) + { + if (MinimumLength < 0) + { + throw new global::System.InvalidOperationException("LengthAttribute must have a MinimumLength value that is zero or greater."); + } + if (MaximumLength < MinimumLength) + { + throw new global::System.InvalidOperationException("LengthAttribute must have a MaximumLength value that is greater than or equal to MinimumLength."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::ValidationTest.FakeCount) + { + length = ((global::ValidationTest.FakeCount)value).Count; + } + else if (value is global::ValidationTest.FakeCountChild) + { + length = ((global::ValidationTest.FakeCountChild)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return (uint)(length - MinimumLength) <= (uint)(MaximumLength - MinimumLength); + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, MinimumLength, MaximumLength); + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__MaxLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private const int MaxAllowableLength = -1; + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a maximum length of '{1}'."; + public __SourceGen__MaxLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public __SourceGen__MaxLengthAttribute(): base(() => DefaultErrorMessageString) { Length = MaxAllowableLength; } + public int Length { get; } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + public override bool IsValid(object? value) + { + if (Length == 0 || Length < -1) + { + throw new global::System.InvalidOperationException("MaxLengthAttribute must have a Length value that is greater than zero. Use MaxLength() without parameters to indicate that the string or array can have the maximum allowable length."); + } + if (value == null || MaxAllowableLength == Length) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::ValidationTest.FakeCount) + { + length = ((global::ValidationTest.FakeCount)value).Count; + } + else if (value is global::ValidationTest.FakeCountChild) + { + length = ((global::ValidationTest.FakeCountChild)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length <= Length; + } + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__MinLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a minimum length of '{1}'."; + + public __SourceGen__MinLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public int Length { get; } + public override bool IsValid(object? value) + { + if (Length < -1) + { + throw new global::System.InvalidOperationException("MinLengthAttribute must have a Length value that is zero or greater."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::ValidationTest.FakeCount) + { + length = ((global::ValidationTest.FakeCount)value).Count; + } + else if (value is global::ValidationTest.FakeCountChild) + { + length = ((global::ValidationTest.FakeCountChild)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length >= Length; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__RangeAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + public __SourceGen__RangeAttribute(int minimum, int maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(int); + } + public __SourceGen__RangeAttribute(double minimum, double maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(double); + } + public __SourceGen__RangeAttribute(global::System.Type type, string minimum, string maximum) : base() + { + OperandType = type; + NeedToConvertMinMax = true; + Minimum = minimum; + Maximum = maximum; + } + public object Minimum { get; private set; } + public object Maximum { get; private set; } + public bool MinimumIsExclusive { get; set; } + public bool MaximumIsExclusive { get; set; } + public global::System.Type OperandType { get; } + public bool ParseLimitsInInvariantCulture { get; set; } + public bool ConvertValueInInvariantCulture { get; set; } + public override string FormatErrorMessage(string name) => + string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); + private bool NeedToConvertMinMax { get; } + private bool Initialized { get; set; } + public override bool IsValid(object? value) + { + if (!Initialized) + { + if (Minimum is null || Maximum is null) + { + throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + if (NeedToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + Initialized = true; + } + + if (value is null or string { Length: 0 }) + { + return true; + } + + System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + object? convertedValue; + + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } + + var min = (global::System.IComparable)Minimum; + var max = (global::System.IComparable)Maximum; + + return + (MinimumIsExclusive ? min.CompareTo(convertedValue) < 0 : min.CompareTo(convertedValue) <= 0) && + (MaximumIsExclusive ? max.CompareTo(convertedValue) > 0 : max.CompareTo(convertedValue) >= 0); + } + private string GetValidationErrorMessage() + { + return (MinimumIsExclusive, MaximumIsExclusive) switch + { + (false, false) => "The field {0} must be between {1} and {2}.", + (true, false) => "The field {0} must be between {1} exclusive and {2}.", + (false, true) => "The field {0} must be between {1} and {2} exclusive.", + (true, true) => "The field {0} must be between {1} exclusive and {2} exclusive.", + }; + } + private object? ConvertValue(object? value, System.Globalization.CultureInfo formatProvider) + { + if (value is string stringValue) + { + value = global::System.Convert.ChangeType(stringValue, OperandType, formatProvider); + } + else + { + value = global::System.Convert.ChangeType(value, OperandType, formatProvider); + } + return value; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang10.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang10.g.cs new file mode 100644 index 00000000000000..7f5eb90a202815 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang10.g.cs @@ -0,0 +1,386 @@ + + // + #nullable enable + #pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103 + namespace ValidationTest +{ + partial class OptionsUsingGeneratedAttributesValidator + { + /// + /// Validates a specific named options instance (or all when is ). + /// + /// The name of the options instance being validated. + /// The options instance. + /// Validation result. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::ValidationTest.OptionsUsingGeneratedAttributes options) + { + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; + var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); + var validationResults = new global::System.Collections.Generic.List(); + var validationAttributes = new global::System.Collections.Generic.List(1); + + context.MemberName = "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P3" : $"{name}.P3"; + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P4" : $"{name}.P4"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P5" : $"{name}.P5"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P6" : $"{name}.P6"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A4); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P7"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P7" : $"{name}.P7"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P7, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P8"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P8" : $"{name}.P8"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P8, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P9"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P9" : $"{name}.P9"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P9, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P10"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P10" : $"{name}.P10"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P10, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P11"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P11" : $"{name}.P11"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P11, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P12"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P12" : $"{name}.P12"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P12, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); + } + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + internal static class __Attributes_2C497155 + { + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_RangeAttribute A1 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_RangeAttribute( + (int)1, + (int)3); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_MinLengthAttribute A2 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_MinLengthAttribute( + (int)5); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_MaxLengthAttribute A3 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_MaxLengthAttribute( + (int)5); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_CompareAttribute A4 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_CompareAttribute( + "P5"); + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + internal static class __Validators_2C497155 + { + } +} +namespace __OptionValidationGeneratedAttributes +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property, AllowMultiple = false)] + internal class __SourceGen__2C497155_CompareAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "'{0}' and '{1}' do not match."; + public __SourceGen__2C497155_CompareAttribute(string otherProperty) : base(() => DefaultErrorMessageString) + { + if (otherProperty == null) + { + throw new global::System.ArgumentNullException(nameof(otherProperty)); + } + OtherProperty = otherProperty; + } + public string OtherProperty { get; } + public override bool RequiresValidationContext => true; + + protected override global::System.ComponentModel.DataAnnotations.ValidationResult? IsValid(object? value, global::System.ComponentModel.DataAnnotations.ValidationContext validationContext) + { + bool result = true; + + if (validationContext.ObjectInstance is global::ValidationTest.OptionsUsingGeneratedAttributes && OtherProperty == "P5") + { + result = Equals(value, ((global::ValidationTest.OptionsUsingGeneratedAttributes)validationContext.ObjectInstance).P5); + } + + if (!result) + { + string[]? memberNames = validationContext.MemberName is null ? null : new string[] { validationContext.MemberName }; + return new global::System.ComponentModel.DataAnnotations.ValidationResult(FormatErrorMessage(validationContext.DisplayName), memberNames); + } + + return null; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, OtherProperty); + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + internal class __SourceGen__2C497155_MaxLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private const int MaxAllowableLength = -1; + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a maximum length of '{1}'."; + public __SourceGen__2C497155_MaxLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public __SourceGen__2C497155_MaxLengthAttribute(): base(() => DefaultErrorMessageString) { Length = MaxAllowableLength; } + public int Length { get; } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + public override bool IsValid(object? value) + { + if (Length == 0 || Length < -1) + { + throw new global::System.InvalidOperationException("MaxLengthAttribute must have a Length value that is greater than zero. Use MaxLength() without parameters to indicate that the string or array can have the maximum allowable length."); + } + if (value == null || MaxAllowableLength == Length) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::ValidationTest.FakeCount) + { + length = ((global::ValidationTest.FakeCount)value).Count; + } + else if (value is global::ValidationTest.FakeCountChild) + { + length = ((global::ValidationTest.FakeCountChild)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length <= Length; + } + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + internal class __SourceGen__2C497155_MinLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a minimum length of '{1}'."; + + public __SourceGen__2C497155_MinLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public int Length { get; } + public override bool IsValid(object? value) + { + if (Length < -1) + { + throw new global::System.InvalidOperationException("MinLengthAttribute must have a Length value that is zero or greater."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::ValidationTest.FakeCount) + { + length = ((global::ValidationTest.FakeCount)value).Count; + } + else if (value is global::ValidationTest.FakeCountChild) + { + length = ((global::ValidationTest.FakeCountChild)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length >= Length; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + internal class __SourceGen__2C497155_RangeAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + public __SourceGen__2C497155_RangeAttribute(int minimum, int maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(int); + } + public __SourceGen__2C497155_RangeAttribute(double minimum, double maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(double); + } + public __SourceGen__2C497155_RangeAttribute(global::System.Type type, string minimum, string maximum) : base() + { + OperandType = type; + NeedToConvertMinMax = true; + Minimum = minimum; + Maximum = maximum; + } + public object Minimum { get; private set; } + public object Maximum { get; private set; } + public bool MinimumIsExclusive { get; set; } + public bool MaximumIsExclusive { get; set; } + public global::System.Type OperandType { get; } + public bool ParseLimitsInInvariantCulture { get; set; } + public bool ConvertValueInInvariantCulture { get; set; } + public override string FormatErrorMessage(string name) => + string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); + private bool NeedToConvertMinMax { get; } + private bool Initialized { get; set; } + public override bool IsValid(object? value) + { + if (!Initialized) + { + if (Minimum is null || Maximum is null) + { + throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + if (NeedToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + Initialized = true; + } + + if (value is null or string { Length: 0 }) + { + return true; + } + + System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + object? convertedValue; + + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } + + var min = (global::System.IComparable)Minimum; + var max = (global::System.IComparable)Maximum; + + return + (MinimumIsExclusive ? min.CompareTo(convertedValue) < 0 : min.CompareTo(convertedValue) <= 0) && + (MaximumIsExclusive ? max.CompareTo(convertedValue) > 0 : max.CompareTo(convertedValue) >= 0); + } + private string GetValidationErrorMessage() + { + return (MinimumIsExclusive, MaximumIsExclusive) switch + { + (false, false) => "The field {0} must be between {1} and {2}.", + (true, false) => "The field {0} must be between {1} exclusive and {2}.", + (false, true) => "The field {0} must be between {1} and {2} exclusive.", + (true, true) => "The field {0} must be between {1} exclusive and {2} exclusive.", + }; + } + private object? ConvertValue(object? value, System.Globalization.CultureInfo formatProvider) + { + if (value is string stringValue) + { + value = global::System.Convert.ChangeType(stringValue, OperandType, formatProvider); + } + else + { + value = global::System.Convert.ChangeType(value, OperandType, formatProvider); + } + return value; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang11.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang11.g.cs new file mode 100644 index 00000000000000..3ab56e21320a07 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang11.g.cs @@ -0,0 +1,386 @@ + + // + #nullable enable + #pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103 + namespace ValidationTest +{ + partial class OptionsUsingGeneratedAttributesValidator + { + /// + /// Validates a specific named options instance (or all when is ). + /// + /// The name of the options instance being validated. + /// The options instance. + /// Validation result. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::ValidationTest.OptionsUsingGeneratedAttributes options) + { + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; + var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); + var validationResults = new global::System.Collections.Generic.List(); + var validationAttributes = new global::System.Collections.Generic.List(1); + + context.MemberName = "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P3" : $"{name}.P3"; + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P4" : $"{name}.P4"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P5" : $"{name}.P5"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P6" : $"{name}.P6"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A4); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P7"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P7" : $"{name}.P7"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P7, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P8"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P8" : $"{name}.P8"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P8, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P9"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P9" : $"{name}.P9"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P9, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P10"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P10" : $"{name}.P10"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P10, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P11"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P11" : $"{name}.P11"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P11, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P12"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P12" : $"{name}.P12"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P12, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); + } + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Attributes + { + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A1 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( + (int)1, + (int)3); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__MinLengthAttribute A2 = new __OptionValidationGeneratedAttributes.__SourceGen__MinLengthAttribute( + (int)5); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__MaxLengthAttribute A3 = new __OptionValidationGeneratedAttributes.__SourceGen__MaxLengthAttribute( + (int)5); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__CompareAttribute A4 = new __OptionValidationGeneratedAttributes.__SourceGen__CompareAttribute( + "P5"); + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Validators + { + } +} +namespace __OptionValidationGeneratedAttributes +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property, AllowMultiple = false)] + file class __SourceGen__CompareAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "'{0}' and '{1}' do not match."; + public __SourceGen__CompareAttribute(string otherProperty) : base(() => DefaultErrorMessageString) + { + if (otherProperty == null) + { + throw new global::System.ArgumentNullException(nameof(otherProperty)); + } + OtherProperty = otherProperty; + } + public string OtherProperty { get; } + public override bool RequiresValidationContext => true; + + protected override global::System.ComponentModel.DataAnnotations.ValidationResult? IsValid(object? value, global::System.ComponentModel.DataAnnotations.ValidationContext validationContext) + { + bool result = true; + + if (validationContext.ObjectInstance is global::ValidationTest.OptionsUsingGeneratedAttributes && OtherProperty == "P5") + { + result = Equals(value, ((global::ValidationTest.OptionsUsingGeneratedAttributes)validationContext.ObjectInstance).P5); + } + + if (!result) + { + string[]? memberNames = validationContext.MemberName is null ? null : new string[] { validationContext.MemberName }; + return new global::System.ComponentModel.DataAnnotations.ValidationResult(FormatErrorMessage(validationContext.DisplayName), memberNames); + } + + return null; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, OtherProperty); + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__MaxLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private const int MaxAllowableLength = -1; + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a maximum length of '{1}'."; + public __SourceGen__MaxLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public __SourceGen__MaxLengthAttribute(): base(() => DefaultErrorMessageString) { Length = MaxAllowableLength; } + public int Length { get; } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + public override bool IsValid(object? value) + { + if (Length == 0 || Length < -1) + { + throw new global::System.InvalidOperationException("MaxLengthAttribute must have a Length value that is greater than zero. Use MaxLength() without parameters to indicate that the string or array can have the maximum allowable length."); + } + if (value == null || MaxAllowableLength == Length) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::ValidationTest.FakeCount) + { + length = ((global::ValidationTest.FakeCount)value).Count; + } + else if (value is global::ValidationTest.FakeCountChild) + { + length = ((global::ValidationTest.FakeCountChild)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length <= Length; + } + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__MinLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a minimum length of '{1}'."; + + public __SourceGen__MinLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public int Length { get; } + public override bool IsValid(object? value) + { + if (Length < -1) + { + throw new global::System.InvalidOperationException("MinLengthAttribute must have a Length value that is zero or greater."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::ValidationTest.FakeCount) + { + length = ((global::ValidationTest.FakeCount)value).Count; + } + else if (value is global::ValidationTest.FakeCountChild) + { + length = ((global::ValidationTest.FakeCountChild)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length >= Length; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__RangeAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + public __SourceGen__RangeAttribute(int minimum, int maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(int); + } + public __SourceGen__RangeAttribute(double minimum, double maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(double); + } + public __SourceGen__RangeAttribute(global::System.Type type, string minimum, string maximum) : base() + { + OperandType = type; + NeedToConvertMinMax = true; + Minimum = minimum; + Maximum = maximum; + } + public object Minimum { get; private set; } + public object Maximum { get; private set; } + public bool MinimumIsExclusive { get; set; } + public bool MaximumIsExclusive { get; set; } + public global::System.Type OperandType { get; } + public bool ParseLimitsInInvariantCulture { get; set; } + public bool ConvertValueInInvariantCulture { get; set; } + public override string FormatErrorMessage(string name) => + string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); + private bool NeedToConvertMinMax { get; } + private bool Initialized { get; set; } + public override bool IsValid(object? value) + { + if (!Initialized) + { + if (Minimum is null || Maximum is null) + { + throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + if (NeedToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + Initialized = true; + } + + if (value is null or string { Length: 0 }) + { + return true; + } + + System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + object? convertedValue; + + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } + + var min = (global::System.IComparable)Minimum; + var max = (global::System.IComparable)Maximum; + + return + (MinimumIsExclusive ? min.CompareTo(convertedValue) < 0 : min.CompareTo(convertedValue) <= 0) && + (MaximumIsExclusive ? max.CompareTo(convertedValue) > 0 : max.CompareTo(convertedValue) >= 0); + } + private string GetValidationErrorMessage() + { + return (MinimumIsExclusive, MaximumIsExclusive) switch + { + (false, false) => "The field {0} must be between {1} and {2}.", + (true, false) => "The field {0} must be between {1} exclusive and {2}.", + (false, true) => "The field {0} must be between {1} and {2} exclusive.", + (true, true) => "The field {0} must be between {1} exclusive and {2} exclusive.", + }; + } + private object? ConvertValue(object? value, System.Globalization.CultureInfo formatProvider) + { + if (value is string stringValue) + { + value = global::System.Convert.ChangeType(stringValue, OperandType, formatProvider); + } + else + { + value = global::System.Convert.ChangeType(value, OperandType, formatProvider); + } + return value; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs index aa51c9dfbae73a..da893126a14b88 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs @@ -52,77 +52,15 @@ public partial struct MyOptionsValidator : IValidateOptions } """; - string generatedSource = """ - - // - #nullable enable - #pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103 - namespace HelloWorld -{ - partial struct MyOptionsValidator - { - /// - /// Validates a specific named options instance (or all when is ). - /// - /// The name of the options instance being validated. - /// The options instance. - /// Validation result. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] - public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::HelloWorld.MyOptions options) - { - global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; - var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); - var validationResults = new global::System.Collections.Generic.List(); - var validationAttributes = new global::System.Collections.Generic.List(1); - - context.MemberName = "Val1"; - context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.Val1" : $"{name}.Val1"; - validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val1, context, validationResults, validationAttributes)) - { - (builder ??= new()).AddResults(validationResults); - } - - context.MemberName = "Val2"; - context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.Val2" : $"{name}.Val2"; - validationResults.Clear(); - validationAttributes.Clear(); - validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val2, context, validationResults, validationAttributes)) - { - (builder ??= new()).AddResults(validationResults); - } - - return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); - } - } -} -namespace __OptionValidationStaticInstances -{ - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] - file static class __Attributes - { - internal static readonly global::System.ComponentModel.DataAnnotations.RequiredAttribute A1 = new global::System.ComponentModel.DataAnnotations.RequiredAttribute(); - - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A2 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( - (int)1, - (int)3); - } -} -namespace __OptionValidationStaticInstances -{ - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] - file static class __Validators - { - } -} - -"""; - var (diagnostics, generatedSources) = await RunGeneratorOnOptionsSource(source); Assert.Empty(diagnostics); _ = Assert.Single(generatedSources); +#if NETCOREAPP + string generatedSource = File.ReadAllText(@"Baselines/EmitterWithCustomValidator.netcore.g.cs"); +#else + string generatedSource = File.ReadAllText(@"Baselines/EmitterWithCustomValidator.netfx.g.cs"); +#endif // NETCOREAPP Assert.Equal(generatedSource.Replace("\r\n", "\n"), generatedSources[0].SourceText.ToString().Replace("\r\n", "\n")); } @@ -1443,7 +1381,7 @@ internal sealed partial class ExtOptionsValidator : IValidateOptions Assert.Single(diagnostics); Assert.Equal(DiagDescriptors.InaccessibleValidationAttribute.Id, diagnostics[0].Id); string generatedSource = generatedSources[0].SourceText.ToString(); - Assert.Contains("global::System.ComponentModel.DataAnnotations.RangeAttribute", generatedSource); + Assert.Contains("__OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute", generatedSource); Assert.Contains("global::System.ComponentModel.DataAnnotations.RequiredAttribute", generatedSource); Assert.DoesNotContain("Timeout", generatedSource); @@ -1666,113 +1604,22 @@ public partial class MyOptionsValidator : IValidateOptions Assert.Empty(diagnostics); Assert.Single(generatedSources); - var generatedSource = """ - - // - #nullable enable - #pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103 - namespace Test -{ - partial class MyOptionsValidator - { - /// - /// Validates a specific named options instance (or all when is ). - /// - /// The name of the options instance being validated. - /// The options instance. - /// Validation result. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] - public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Test.MyOptions options) - { - global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; - var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); - var validationResults = new global::System.Collections.Generic.List(); - var validationAttributes = new global::System.Collections.Generic.List(1); - - context.MemberName = "P1"; - context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P1" : $"{name}.P1"; - validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) - { - (builder ??= new()).AddResults(validationResults); - } - - context.MemberName = "P2"; - context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P2" : $"{name}.P2"; - validationResults.Clear(); - validationAttributes.Clear(); - validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) - { - (builder ??= new()).AddResults(validationResults); - } - - context.MemberName = "P3"; - context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P3" : $"{name}.P3"; - validationResults.Clear(); - validationAttributes.Clear(); - validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) - { - (builder ??= new()).AddResults(validationResults); - } - - context.MemberName = "P4"; - context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P4" : $"{name}.P4"; - validationResults.Clear(); - validationAttributes.Clear(); - validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A4); - if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) - { - (builder ??= new()).AddResults(validationResults); - } - - return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); - } - } -} -namespace __OptionValidationStaticInstances -{ - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] - file static class __Attributes - { - internal static readonly global::System.ComponentModel.DataAnnotations.RequiredAttribute A1 = new global::System.ComponentModel.DataAnnotations.RequiredAttribute(); - - internal static readonly global::System.ComponentModel.DataAnnotations.LengthAttribute A2 = new global::System.ComponentModel.DataAnnotations.LengthAttribute( - (int)10, - (int)20); - - internal static readonly global::System.ComponentModel.DataAnnotations.AllowedValuesAttribute A3 = new global::System.ComponentModel.DataAnnotations.AllowedValuesAttribute( - (int)10, (int)20, (int)30); - - internal static readonly global::System.ComponentModel.DataAnnotations.DeniedValuesAttribute A4 = new global::System.ComponentModel.DataAnnotations.DeniedValuesAttribute( - "One", "Ten", "Hundred"); - } -} -namespace __OptionValidationStaticInstances -{ - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] - file static class __Validators - { - } -} - -"""; + string generatedSource = File.ReadAllText(@"Baselines/DataAnnotationAttributesWithParams.g.cs"); Assert.Equal(generatedSource.Replace("\r\n", "\n"), generatedSources[0].SourceText.ToString().Replace("\r\n", "\n")); } - private static CSharpCompilation CreateCompilationForOptionsSource(string assemblyName, string source, string? refAssemblyPath = null) + private static CSharpCompilation CreateCompilationForOptionsSource(string assemblyName, string source, string? refAssemblyPath = null, LanguageVersion languageVersion = LanguageVersion.Default) { // Ensure the generated source compiles var compilation = CSharpCompilation - .Create(Path.GetRandomFileName()+".dll", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) + .Create($"{assemblyName}.dll", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) .AddReferences(MetadataReference.CreateFromFile(AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == "System.Runtime").Location)) .AddReferences(MetadataReference.CreateFromFile(typeof(string).Assembly.Location)) .AddReferences(MetadataReference.CreateFromFile(typeof(RequiredAttribute).Assembly.Location)) .AddReferences(MetadataReference.CreateFromFile(typeof(OptionsValidatorAttribute).Assembly.Location)) .AddReferences(MetadataReference.CreateFromFile(typeof(IValidateOptions).Assembly.Location)) .AddReferences(MetadataReference.CreateFromFile(typeof(System.CodeDom.Compiler.GeneratedCodeAttribute).Assembly.Location)) - .AddSyntaxTrees(CSharpSyntaxTree.ParseText(source)); + .AddSyntaxTrees(CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(languageVersion))); if (refAssemblyPath is not null) { @@ -1861,4 +1708,109 @@ private static CSharpCompilation CreateCompilationForOptionsSource(string assemb return result; } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + [InlineData(LanguageVersion.CSharp10)] + [InlineData(LanguageVersion.CSharp11)] + public async Task GeneratedAttributesTest(LanguageVersion languageVersion) + { + +#if NETCOREAPP + string lengthAttribute = $$""" + [LengthAttribute(1, 3)] + public string? P0 { get; set; } + + [LengthAttribute(1, 3)] + public FakeCount? P1 { get; set; } + + [LengthAttribute(1, 3)] + public FakeCountChild? P2 { get; set; } + """; +#else +string lengthAttribute = ""; +#endif //NETCOREAPP + + string source = $$""" + using System.Collections.Generic; + using Microsoft.Extensions.Options; + using System.ComponentModel.DataAnnotations; + + #nullable enable + + namespace ValidationTest + { + public class FakeCount + { + public FakeCount(int count) { Count = count; } + public int Count { get; } + } + public class FakeCountChild : FakeCount + { + public FakeCountChild(int count) : base(count) { } + } + + public class OptionsUsingGeneratedAttributes + { + {{lengthAttribute}} + + [RangeAttribute(1, 3)] + public int P3 { get; set; } + + [MinLengthAttribute(5)] + public string? P4 { get; set; } + + [MaxLengthAttribute(5)] + public string? P5 { get; set; } + + [CompareAttribute("P5")] + public string? P6 { get; set; } + + [MinLengthAttribute(5)] + public FakeCount? P7 { get; set; } + + [MinLengthAttribute(5)] + public FakeCountChild? P8 { get; set; } + + [MaxLengthAttribute(5)] + public FakeCount? P9 { get; set; } + + [MaxLengthAttribute(5)] + public FakeCountChild? P10 { get; set; } + + [MinLengthAttribute(5)] + public List? P11 { get; set; } + + [MaxLengthAttribute(5)] + public List? P12 { get; set; } + } + + [OptionsValidator] + public sealed partial class OptionsUsingGeneratedAttributesValidator : IValidateOptions + { + } + } + """; + + var (diagnostics, generatedSources) = await RunGeneratorOnOptionsSource(source, null, languageVersion); + Assert.Empty(diagnostics); + Assert.Single(generatedSources); + + string emittedSource = generatedSources[0].SourceText.ToString(); + SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(emittedSource, new CSharpParseOptions(languageVersion)); + var diags = syntaxTree.GetDiagnostics().ToArray(); + Assert.Empty(diags); + +#if NETCOREAPP + string generatedSource = File.ReadAllText(languageVersion == LanguageVersion.CSharp10 ? @"Baselines/GeneratedAttributesTest.netcore.lang10.g.cs" : @"Baselines/GeneratedAttributesTest.netcore.lang11.g.cs"); +#else + string generatedSource = File.ReadAllText(languageVersion == LanguageVersion.CSharp10 ? @"Baselines/GeneratedAttributesTest.netfx.lang10.g.cs" : @"Baselines/GeneratedAttributesTest.netfx.lang11.g.cs"); +#endif // NET8_0_OR_GREATER + Assert.Equal(generatedSource.Replace("\r\n", "\n"), emittedSource.Replace("\r\n", "\n")); + + CSharpCompilation compilation = CreateCompilationForOptionsSource(Path.GetRandomFileName(), source + emittedSource, refAssemblyPath: null, languageVersion); + var emitResult = compilation.Emit(new MemoryStream()); + + Assert.True(emitResult.Success); + // Console.WriteLine(emittedSource); + } } diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Microsoft.Extensions.Options.SourceGeneration.Unit.Tests.csproj b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Microsoft.Extensions.Options.SourceGeneration.Unit.Tests.csproj index d76cbd45302f91..f3a5f33b4a2b45 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Microsoft.Extensions.Options.SourceGeneration.Unit.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Microsoft.Extensions.Options.SourceGeneration.Unit.Tests.csproj @@ -14,6 +14,7 @@ + @@ -35,6 +36,12 @@ OutputItemType="Analyzer" ReferenceOutputAssembly="true" SetTargetFramework="TargetFramework=netstandard2.0"/> + + + PreserveNewest + + + diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs index 6109bccd296463..78783d7a537e29 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs @@ -266,6 +266,214 @@ public void TestNewDataAnnotationFailures() }, result.Failures); } #endif // NET8_0_OR_GREATER + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + public void TestCustomGeneratedAttributes() + { + OptionsUsingGeneratedAttributes noFailures = new OptionsUsingGeneratedAttributes() + { +#if NET8_0_OR_GREATER + P0 = "123", + P11 = new DateTime(2023, 2, 1), + P12 = 6, + P13 = 9, + P14 = new List() { "1", "2" }, + P15 = new FakeCount(5), + P16 = new FakeCountChild(5), + P17 = new int[] { 1, 2 }, + P18 = new List() { "1", "2", "3" }, + P19 = new FakeCount(3), + P20 = new FakeCountChild(3), + P23 = new List() { "1", "2", "3", "4" }, + P24 = new FakeCount(4), + P25 = new FakeCountChild(4), +#endif // NET8_0_OR_GREATER + P1 = 2, + P2 = "12345", + P3 = "12345", + P4 = "12345", + P5 = 4, + P6 = 4, + P7 = 15, + P8 = 15, + P9 = 2.5m, + P10 = 14.0, + P21 = new int[] { 1, 2, 3 }, + P22 = new int[] { 1, 2, 3, 4 }, + P26 = 14.0, + }; + List results = new(); + Assert.True(Validator.TryValidateObject(noFailures, new ValidationContext(noFailures), results, true)); + + OptionsUsingGeneratedAttributesValidator validator = new(); + Assert.True(validator.Validate("OptionsUsingGeneratedAttributes", noFailures).Succeeded); + + OptionsUsingGeneratedAttributes failing = new OptionsUsingGeneratedAttributes() + { +#if NET8_0_OR_GREATER + P0 = "", + P11 = new DateTime(2023, 1, 1), + P12 = 5, + P13 = 10, + P14 = new List() { "1" }, + P15 = new FakeCount(1), + P16 = new FakeCountChild(11), + P17 = new int[] { 1 }, + P18 = new List() { "1", "2" }, + P19 = new FakeCount(2), + P20 = new FakeCountChild(1), + P23 = new List() { "1", "2", "3", "4", "5" }, + P24 = new FakeCount(5), + P25 = new FakeCountChild(5), +#endif // NET8_0_OR_GREATER + P1 = 4, + P2 = "1234", + P3 = "123456", + P4 = "12345", + P5 = 10, + P6 = 10, + P7 = 5, + P8 = 5, + P9 = 4.0m, + P10 = 20.0, + P21 = new int[] { 1, 2 }, + P22 = new int[] { 1, 2, 3, 4, 5 }, + P26 = 20.0, + }; + + Assert.False(Validator.TryValidateObject(failing, new ValidationContext(failing), results, true)); + + ValidateOptionsResult generatorResult = validator.Validate("OptionsUsingGeneratedAttributes", failing); + Assert.True(generatorResult.Failed); + + Assert.Equal(new [] { +#if NET8_0_OR_GREATER + "P0: The field OptionsUsingGeneratedAttributes.P0 must be a string or collection type with a minimum length of '1' and maximum length of '3'.", + "P11: The field OptionsUsingGeneratedAttributes.P11 must be between 1/30/2023 12:00:00 AM and 12/30/2023 12:00:00 AM.", + "P12: The field OptionsUsingGeneratedAttributes.P12 must be between 5 exclusive and 10.", + "P13: The field OptionsUsingGeneratedAttributes.P13 must be between 5 and 10 exclusive.", + "P14: The field OptionsUsingGeneratedAttributes.P14 must be a string or collection type with a minimum length of '2' and maximum length of '10'.", + "P15: The field OptionsUsingGeneratedAttributes.P15 must be a string or collection type with a minimum length of '2' and maximum length of '10'.", + "P16: The field OptionsUsingGeneratedAttributes.P16 must be a string or collection type with a minimum length of '2' and maximum length of '10'.", + "P17: The field OptionsUsingGeneratedAttributes.P17 must be a string or collection type with a minimum length of '2' and maximum length of '10'.", + "P18: The field OptionsUsingGeneratedAttributes.P18 must be a string or array type with a minimum length of '3'.", + "P19: The field OptionsUsingGeneratedAttributes.P19 must be a string or array type with a minimum length of '3'.", + "P20: The field OptionsUsingGeneratedAttributes.P20 must be a string or array type with a minimum length of '3'.", + "P23: The field OptionsUsingGeneratedAttributes.P23 must be a string or array type with a maximum length of '4'.", + "P24: The field OptionsUsingGeneratedAttributes.P24 must be a string or array type with a maximum length of '4'.", + "P25: The field OptionsUsingGeneratedAttributes.P25 must be a string or array type with a maximum length of '4'.", +#endif // NET8_0_OR_GREATER + "P1: The field OptionsUsingGeneratedAttributes.P1 must be between 1 and 3.", + "P2: The field OptionsUsingGeneratedAttributes.P2 must be a string or array type with a minimum length of '5'.", + "P3: The field OptionsUsingGeneratedAttributes.P3 must be a string or array type with a maximum length of '5'.", + "P4: 'OptionsUsingGeneratedAttributes.P4' and 'P2' do not match.", + "P5: The field OptionsUsingGeneratedAttributes.P5 must be between 2 and 8.", + "P6: The field OptionsUsingGeneratedAttributes.P6 must be between 2 and 8.", + "P7: The field OptionsUsingGeneratedAttributes.P7 must be between 10 and 20.", + "P8: The field OptionsUsingGeneratedAttributes.P8 must be between 10 and 20.", + "P9: The field OptionsUsingGeneratedAttributes.P9 must be between 1.5 and 3.14.", + "P10: The field OptionsUsingGeneratedAttributes.P10 must be between 12.4 and 16.5.", + "P21: The field OptionsUsingGeneratedAttributes.P21 must be a string or array type with a minimum length of '3'.", + "P22: The field OptionsUsingGeneratedAttributes.P22 must be a string or array type with a maximum length of '4'.", + "P26: The field OptionsUsingGeneratedAttributes.P26 must be between 12.4 and 16.5.", + }, generatorResult.Failures); + + Assert.Equal(results.Count(), generatorResult.Failures.Count()); + } + } + + public class FakeCount(int count) { public int Count { get { return count; } } } + public class FakeCountChild(int count) : FakeCount(count) { } + + public class OptionsUsingGeneratedAttributes + { +#if NET8_0_OR_GREATER + [LengthAttribute(1, 3)] + public string? P0 { get; set; } + + [RangeAttribute(typeof(DateTime), "01/30/2023", "12/30/2023", ParseLimitsInInvariantCulture = true, ConvertValueInInvariantCulture = true)] + public DateTime P11 { get; set; } + + [RangeAttribute(5, 10, MinimumIsExclusive = true)] + public int P12 { get; set; } + + [RangeAttribute(5, 10, MaximumIsExclusive = true)] + public int P13 { get; set; } + + [LengthAttribute(2, 10)] + public List P14 { get; set; } + + [LengthAttribute(2, 10)] + public FakeCount P15 { get; set; } + + [LengthAttribute(2, 10)] + public FakeCountChild P16 { get; set; } + + [LengthAttribute(2, 10)] + public int[] P17 { get; set; } + + [MinLengthAttribute(3)] + public List P18 { get; set; } + + [MinLengthAttribute(3)] + public FakeCount P19 { get; set; } + + [MinLengthAttribute(3)] + public FakeCountChild P20 { get; set; } + + [MaxLengthAttribute(4)] + public List P23 { get; set; } + + [MaxLengthAttribute(4)] + public FakeCount P24 { get; set; } + + [MaxLengthAttribute(4)] + public FakeCountChild P25 { get; set; } +#endif // NET8_0_OR_GREATER + + [RangeAttribute(1, 3)] + public int P1 { get; set; } + + [MinLengthAttribute(5)] + public string? P2 { get; set; } + + [MaxLengthAttribute(5)] + public string? P3 { get; set; } + + [CompareAttribute("P2")] + public string? P4 { get; set; } + + [RangeAttribute(typeof(byte), "2", "8")] + public byte P5 { get; set; } + + [RangeAttribute(typeof(sbyte), "2", "8")] + public sbyte P6 { get; set; } + + [RangeAttribute(typeof(short), "10", "20")] + public short P7 { get; set; } + + [RangeAttribute(typeof(ulong), "10", "20")] + public ulong P8 { get; set; } + + [RangeAttribute(typeof(decimal), "1.5", "3.14")] + public decimal P9 { get; set; } + + [RangeAttribute(typeof(double), "12.40", "16.50")] + public double P10 { get; set; } + + [MinLengthAttribute(3)] + public int[] P21 { get; set; } + + [MaxLengthAttribute(4)] + public int[] P22 { get; set; } + + [RangeAttribute(typeof(double), "12.40", "16.50")] + public double? P26 { get; set; } + } + + [OptionsValidator] + public partial class OptionsUsingGeneratedAttributesValidator : IValidateOptions + { } public class MyOptions @@ -356,4 +564,5 @@ public partial class NewAttributesValidator : IValidateOptions The options validation source generator is not available in C# {0}. Please use language version {1} or greater. - \ No newline at end of file + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs index cc1ebda6414e6b..c487888c9f16bb 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs @@ -12,6 +12,8 @@ internal sealed partial class __ThirdModelNoNamespaceValidator__ /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::ThirdModelNoNamespace options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -40,6 +42,8 @@ partial class FirstValidatorNoNamespace /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::FirstModelNoNamespace options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -78,6 +82,8 @@ partial class SecondValidatorNoNamespace /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::SecondModelNoNamespace options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -108,6 +114,8 @@ partial class FirstValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::CustomAttr.FirstModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -149,6 +157,8 @@ internal sealed partial class __SecondModelValidator__ /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Enumeration.SecondModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -181,6 +191,8 @@ internal sealed partial class __ThirdModelValidator__ /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Enumeration.ThirdModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -211,6 +223,8 @@ partial struct FirstValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Enumeration.FirstModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -363,6 +377,8 @@ partial struct SecondValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Enumeration.SecondModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -394,6 +410,8 @@ partial struct FirstValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::FileScopedNamespace.FirstModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -425,6 +443,8 @@ partial struct FirstValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::FunnyStrings.FirstModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -456,6 +476,8 @@ internal sealed partial class __SecondModelValidator__ /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Generics.SecondModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -487,6 +509,8 @@ partial class FirstValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Generics.FirstModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -523,6 +547,8 @@ partial struct MultiValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::MultiModelValidator.FirstModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -553,6 +579,8 @@ partial struct MultiValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::MultiModelValidator.SecondModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -585,6 +613,8 @@ internal sealed partial class __ThirdModelValidator__ /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.ThirdModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -618,6 +648,8 @@ partial record struct FifthValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.SecondModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -654,6 +686,8 @@ partial struct FirstValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.FirstModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -701,6 +735,8 @@ partial struct FourthValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.SecondModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -737,6 +773,8 @@ partial struct SecondValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.SecondModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -774,6 +812,8 @@ partial struct ThirdValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Nested.Container1.SecondModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -807,6 +847,8 @@ partial class FirstValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RandomMembers.FirstModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -839,6 +881,8 @@ internal sealed partial class __ThirdModelValidator__ /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RecordTypes.ThirdModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -870,6 +914,8 @@ partial record struct FirstValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RecordTypes.FirstModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -913,6 +959,8 @@ partial record struct SecondValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RecordTypes.SecondModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -944,6 +992,8 @@ partial record class ThirdValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RecordTypes.SecondModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -976,6 +1026,8 @@ internal sealed partial class __SecondModelValidator__ /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RepeatedTypes.SecondModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1012,6 +1064,8 @@ internal sealed partial class __ThirdModelValidator__ /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RepeatedTypes.ThirdModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1043,6 +1097,8 @@ partial class FirstValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::RepeatedTypes.FirstModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1108,6 +1164,8 @@ partial struct FirstValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::SelfValidation.FirstModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1141,6 +1199,8 @@ internal sealed partial class __RangeAttributeModelDoubleValidator__ /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RangeAttributeModelDouble options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1172,6 +1232,8 @@ internal sealed partial class __RequiredAttributeModelValidator__ /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RequiredAttributeModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1203,6 +1265,8 @@ internal sealed partial class __TypeWithoutOptionsValidatorValidator__ /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.TypeWithoutOptionsValidator options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1248,6 +1312,8 @@ partial class AttributePropertyModelValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.AttributePropertyModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1288,6 +1354,8 @@ partial class ComplexModelValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.ComplexModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1318,6 +1386,8 @@ partial class CustomTypeCustomValidationAttributeModelValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.CustomTypeCustomValidationAttributeModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1348,6 +1418,8 @@ partial class CustomValidationAttributeModelValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.CustomValidationAttributeModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1378,6 +1450,8 @@ partial class DataTypeAttributeModelValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.DataTypeAttributeModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1408,6 +1482,8 @@ partial class DerivedModelValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.DerivedModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1458,6 +1534,8 @@ partial class EmailAttributeModelValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.EmailAttributeModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1488,6 +1566,8 @@ partial class LeafModelValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.LeafModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1538,6 +1618,8 @@ partial class MultipleAttributeModelValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.MultipleAttributeModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1599,6 +1681,8 @@ partial class RangeAttributeModelDateValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RangeAttributeModelDate options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1629,6 +1713,8 @@ partial class RangeAttributeModelDoubleValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RangeAttributeModelDouble options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1659,6 +1745,8 @@ partial class RangeAttributeModelIntValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RangeAttributeModelInt options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1689,6 +1777,8 @@ partial class RegularExpressionAttributeModelValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RegularExpressionAttributeModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1719,6 +1809,8 @@ partial class RequiredAttributeModelValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.RequiredAttributeModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1750,6 +1842,8 @@ internal sealed partial class __SecondModelValidator__ /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::ValueTypes.SecondModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1781,6 +1875,8 @@ partial struct FirstValidator /// The options instance. /// Validation result. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::ValueTypes.FirstModel options) { global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; @@ -1820,7 +1916,7 @@ file static class __Attributes { internal static readonly global::System.ComponentModel.DataAnnotations.RequiredAttribute A1 = new global::System.ComponentModel.DataAnnotations.RequiredAttribute(); - internal static readonly global::System.ComponentModel.DataAnnotations.MinLengthAttribute A2 = new global::System.ComponentModel.DataAnnotations.MinLengthAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__MinLengthAttribute A2 = new __OptionValidationGeneratedAttributes.__SourceGen__MinLengthAttribute( (int)5); internal static readonly global::CustomAttr.CustomAttribute A3 = new global::CustomAttr.CustomAttribute( @@ -1833,30 +1929,30 @@ file static class __Attributes false, "X"); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A5 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A5 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (int)0, (int)10); internal static readonly global::System.ComponentModel.DataAnnotations.RegularExpressionAttribute A6 = new global::System.ComponentModel.DataAnnotations.RegularExpressionAttribute( "\"\r\n\\\\"); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A7 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A7 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (double)0.5, (double)0.9); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A8 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A8 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( typeof(global::System.DateTime), "1/2/2004", "3/4/2004"); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A9 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A9 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (int)1, (int)3) { ErrorMessage = "ErrorMessage" }; - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A10 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A10 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (int)1, (int)3) { @@ -1880,19 +1976,19 @@ file static class __Attributes internal static readonly global::System.ComponentModel.DataAnnotations.DataTypeAttribute A15 = new global::System.ComponentModel.DataAnnotations.DataTypeAttribute( (global::System.ComponentModel.DataAnnotations.DataType)11); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A16 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A16 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (int)1, (int)3); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A17 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A17 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (int)3, (int)5); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A18 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A18 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (int)5, (int)9); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A19 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A19 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( typeof(global::System.DateTime), "1/2/2004", "3/4/2004") @@ -1924,3 +2020,150 @@ file static class __Validators internal static readonly global::RecordTypes.ThirdValidator V7 = new global::RecordTypes.ThirdValidator(); } } +namespace __OptionValidationGeneratedAttributes +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__MinLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a minimum length of '{1}'."; + + public __SourceGen__MinLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public int Length { get; } + public override bool IsValid(object? value) + { + if (Length < -1) + { + throw new global::System.InvalidOperationException("MinLengthAttribute must have a Length value that is zero or greater."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length >= Length; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__RangeAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + public __SourceGen__RangeAttribute(int minimum, int maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(int); + } + public __SourceGen__RangeAttribute(double minimum, double maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(double); + } + public __SourceGen__RangeAttribute(global::System.Type type, string minimum, string maximum) : base() + { + OperandType = type; + NeedToConvertMinMax = true; + Minimum = minimum; + Maximum = maximum; + } + public object Minimum { get; private set; } + public object Maximum { get; private set; } + public bool MinimumIsExclusive { get; set; } + public bool MaximumIsExclusive { get; set; } + public global::System.Type OperandType { get; } + public bool ParseLimitsInInvariantCulture { get; set; } + public bool ConvertValueInInvariantCulture { get; set; } + public override string FormatErrorMessage(string name) => + string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); + private bool NeedToConvertMinMax { get; } + private bool Initialized { get; set; } + public override bool IsValid(object? value) + { + if (!Initialized) + { + if (Minimum is null || Maximum is null) + { + throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + if (NeedToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + Initialized = true; + } + + if (value is null or string { Length: 0 }) + { + return true; + } + + System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + object? convertedValue; + + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } + + var min = (global::System.IComparable)Minimum; + var max = (global::System.IComparable)Maximum; + + return + (MinimumIsExclusive ? min.CompareTo(convertedValue) < 0 : min.CompareTo(convertedValue) <= 0) && + (MaximumIsExclusive ? max.CompareTo(convertedValue) > 0 : max.CompareTo(convertedValue) >= 0); + } + private string GetValidationErrorMessage() + { + return (MinimumIsExclusive, MaximumIsExclusive) switch + { + (false, false) => "The field {0} must be between {1} and {2}.", + (true, false) => "The field {0} must be between {1} exclusive and {2}.", + (false, true) => "The field {0} must be between {1} and {2} exclusive.", + (true, true) => "The field {0} must be between {1} exclusive and {2} exclusive.", + }; + } + private object? ConvertValue(object? value, System.Globalization.CultureInfo formatProvider) + { + if (value is string stringValue) + { + value = global::System.Convert.ChangeType(stringValue, OperandType, formatProvider); + } + else + { + value = global::System.Convert.ChangeType(value, OperandType, formatProvider); + } + return value; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs index ebdcb1ad6d6ba7..7e998cea22cddf 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs @@ -1820,7 +1820,7 @@ file static class __Attributes { internal static readonly global::System.ComponentModel.DataAnnotations.RequiredAttribute A1 = new global::System.ComponentModel.DataAnnotations.RequiredAttribute(); - internal static readonly global::System.ComponentModel.DataAnnotations.MinLengthAttribute A2 = new global::System.ComponentModel.DataAnnotations.MinLengthAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__MinLengthAttribute A2 = new __OptionValidationGeneratedAttributes.__SourceGen__MinLengthAttribute( (int)5); internal static readonly global::CustomAttr.CustomAttribute A3 = new global::CustomAttr.CustomAttribute( @@ -1833,30 +1833,30 @@ file static class __Attributes false, "X"); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A5 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A5 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (int)0, (int)10); internal static readonly global::System.ComponentModel.DataAnnotations.RegularExpressionAttribute A6 = new global::System.ComponentModel.DataAnnotations.RegularExpressionAttribute( "\"\r\n\\\\"); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A7 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A7 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (double)0.5, (double)0.9); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A8 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A8 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( typeof(global::System.DateTime), "1/2/2004", "3/4/2004"); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A9 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A9 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (int)1, (int)3) { ErrorMessage = "ErrorMessage" }; - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A10 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A10 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (int)1, (int)3) { @@ -1880,15 +1880,15 @@ file static class __Attributes internal static readonly global::System.ComponentModel.DataAnnotations.DataTypeAttribute A15 = new global::System.ComponentModel.DataAnnotations.DataTypeAttribute( (global::System.ComponentModel.DataAnnotations.DataType)11); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A16 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A16 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (int)1, (int)3); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A17 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A17 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (int)3, (int)5); - internal static readonly global::System.ComponentModel.DataAnnotations.RangeAttribute A18 = new global::System.ComponentModel.DataAnnotations.RangeAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A18 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( (int)5, (int)9); @@ -1916,3 +1916,150 @@ file static class __Validators internal static readonly global::RecordTypes.ThirdValidator V7 = new global::RecordTypes.ThirdValidator(); } } +namespace __OptionValidationGeneratedAttributes +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__MinLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a minimum length of '{1}'."; + + public __SourceGen__MinLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public int Length { get; } + public override bool IsValid(object? value) + { + if (Length < -1) + { + throw new global::System.InvalidOperationException("MinLengthAttribute must have a Length value that is zero or greater."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length >= Length; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__RangeAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + public __SourceGen__RangeAttribute(int minimum, int maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(int); + } + public __SourceGen__RangeAttribute(double minimum, double maximum) : base() + { + Minimum = minimum; + Maximum = maximum; + OperandType = typeof(double); + } + public __SourceGen__RangeAttribute(global::System.Type type, string minimum, string maximum) : base() + { + OperandType = type; + NeedToConvertMinMax = true; + Minimum = minimum; + Maximum = maximum; + } + public object Minimum { get; private set; } + public object Maximum { get; private set; } + public bool MinimumIsExclusive { get; set; } + public bool MaximumIsExclusive { get; set; } + public global::System.Type OperandType { get; } + public bool ParseLimitsInInvariantCulture { get; set; } + public bool ConvertValueInInvariantCulture { get; set; } + public override string FormatErrorMessage(string name) => + string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); + private bool NeedToConvertMinMax { get; } + private bool Initialized { get; set; } + public override bool IsValid(object? value) + { + if (!Initialized) + { + if (Minimum is null || Maximum is null) + { + throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + if (NeedToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + Initialized = true; + } + + if (value is null or string { Length: 0 }) + { + return true; + } + + System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + object? convertedValue; + + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } + + var min = (global::System.IComparable)Minimum; + var max = (global::System.IComparable)Maximum; + + return + (MinimumIsExclusive ? min.CompareTo(convertedValue) < 0 : min.CompareTo(convertedValue) <= 0) && + (MaximumIsExclusive ? max.CompareTo(convertedValue) > 0 : max.CompareTo(convertedValue) >= 0); + } + private string GetValidationErrorMessage() + { + return (MinimumIsExclusive, MaximumIsExclusive) switch + { + (false, false) => "The field {0} must be between {1} and {2}.", + (true, false) => "The field {0} must be between {1} exclusive and {2}.", + (false, true) => "The field {0} must be between {1} and {2} exclusive.", + (true, true) => "The field {0} must be between {1} exclusive and {2} exclusive.", + }; + } + private object? ConvertValue(object? value, System.Globalization.CultureInfo formatProvider) + { + if (value is string stringValue) + { + value = global::System.Convert.ChangeType(stringValue, OperandType, formatProvider); + } + else + { + value = global::System.Convert.ChangeType(value, OperandType, formatProvider); + } + return value; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Resources/Strings.resx index 6b8167e94b119a..90e5b01ed3b1b7 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Resources/Strings.resx @@ -216,4 +216,10 @@ The options validation source generator is not available in C# {0}. Please use language version {1} or greater. - \ No newline at end of file + + The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + + + The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + + diff --git a/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/ConfigureTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/ConfigureTests.cs index 870b27bbe9e100..7a39d8a8810fd3 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/ConfigureTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/ConfigureTests.cs @@ -4,6 +4,8 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; class Program { @@ -37,6 +39,22 @@ optionsC is null || return -1; } + LocalOptionsValidator localOptionsValidator = new LocalOptionsValidator(); + OptionsUsingValidationAttributes optionsUsingValidationAttributes = new OptionsUsingValidationAttributes + { + P1 = "12345", + P2 = new List { "1234", "12345" }, + P3 = "123456", + P4 = "12345", + P5 = 7 + }; + + ValidateOptionsResult result = localOptionsValidator.Validate("", optionsUsingValidationAttributes); + if (result.Failed) + { + return -2; + } + return 100; } @@ -76,3 +94,29 @@ private class OptionsD public string OptionString { get; set; } } } + +public class OptionsUsingValidationAttributes +{ + [Required] + [MinLength(5)] + public string P1 { get; set; } + + [Required] + [MaxLength(5)] + public List P2 { get; set; } + + [Length(2, 8)] + public string P3 { get; set; } + + [Compare("P1")] + public string P4 { get; set; } + + [Range(1, 10, MinimumIsExclusive = true, MaximumIsExclusive = true)] + public int P5 { get; set; } +} + +[OptionsValidator] +public partial class LocalOptionsValidator : IValidateOptions +{ +} + diff --git a/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/Microsoft.Extensions.Options.TrimmingTests.proj b/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/Microsoft.Extensions.Options.TrimmingTests.proj index 669ac862ad7b16..15b6dc0a6ea0e2 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/Microsoft.Extensions.Options.TrimmingTests.proj +++ b/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/Microsoft.Extensions.Options.TrimmingTests.proj @@ -7,10 +7,15 @@ Microsoft.Extensions.DependencyInjection - + + + + <_additionalProjectReference Include="<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.Options\gen\Microsoft.Extensions.Options.SourceGeneration.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="true" SetTargetFramework="TargetFramework=netstandard2.0" />" /> + + From d618afa20b3ef437ab8f04f51d75ca4950b38982 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 17:03:23 -0700 Subject: [PATCH 361/783] [release/8.0] Fix a memory leak in runtime interop stubs when using an array of structs of types that use old-style managed marshalers (#93150) * [release/6.0] Fix a memory leak in runtime interop stubs when using an array of structs of types that use old-style managed marshalers * We already normalize null refs early, so we don't need to normalize here. --------- Co-authored-by: Jeremy Koritzinsky --- src/coreclr/vm/ilmarshalers.h | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/coreclr/vm/ilmarshalers.h b/src/coreclr/vm/ilmarshalers.h index f3c9f31628f156..61ff10ac2b2b86 100644 --- a/src/coreclr/vm/ilmarshalers.h +++ b/src/coreclr/vm/ilmarshalers.h @@ -3138,39 +3138,13 @@ class ILMngdMarshaler : public ILMarshaler void EmitClearNative(ILCodeStream* pslILEmit) override { WRAPPER_NO_CONTRACT; - ILCodeLabel* pNoManagedValueLabel = nullptr; - if (IsFieldMarshal(m_dwMarshalFlags)) - { - pNoManagedValueLabel = pslILEmit->NewCodeLabel(); - pslILEmit->EmitLDARG(StructMarshalStubs::MANAGED_STRUCT_ARGIDX); - pslILEmit->EmitBRFALSE(pNoManagedValueLabel); - } - EmitCallMngdMarshalerMethod(pslILEmit, GetClearNativeMethod()); - - if (IsFieldMarshal(m_dwMarshalFlags)) - { - pslILEmit->EmitLabel(pNoManagedValueLabel); - } } void EmitClearNativeContents(ILCodeStream* pslILEmit) override { WRAPPER_NO_CONTRACT; - ILCodeLabel* pNoManagedValueLabel = nullptr; - if (IsFieldMarshal(m_dwMarshalFlags)) - { - pNoManagedValueLabel = pslILEmit->NewCodeLabel(); - pslILEmit->EmitLDARG(StructMarshalStubs::MANAGED_STRUCT_ARGIDX); - pslILEmit->EmitBRFALSE(pNoManagedValueLabel); - } - EmitCallMngdMarshalerMethod(pslILEmit, GetClearNativeContentsMethod()); - - if (IsFieldMarshal(m_dwMarshalFlags)) - { - pslILEmit->EmitLabel(pNoManagedValueLabel); - } } bool NeedsClearCLR() override From 2504043c3c7277e6fc4f350a71a6e229aa0aa39c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 17:06:30 -0700 Subject: [PATCH 362/783] Handle binding to initialized abstract members (#93120) If an abstract member is encountered in an object graph we should only throw if it's not already initialized. Co-authored-by: Eric StJohn --- .../gen/Emitter/CoreBindingHelpers.cs | 10 ++++------ .../ConfigurationBinderTests.TestClasses.cs | 5 +++++ .../tests/Common/ConfigurationBinderTests.cs | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs index 1e14094c664408..499d4085bbd362 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs @@ -1047,15 +1047,13 @@ void EmitBindingLogic(string instanceToBindExpr, InitializationKind initKind) else { Debug.Assert(!type.IsValueType); - + EmitStartBlock($"if ({instanceToBindExpr} is not null)"); + EmitBindCoreCall(); + EmitEndBlock(); if (type is ObjectSpec { InitExceptionMessage: string exMsg }) { + EmitStartBlock("else"); _writer.WriteLine($@"throw new {Identifier.InvalidOperationException}(""{exMsg}"");"); - } - else - { - EmitStartBlock($"if ({instanceToBindExpr} is not null)"); - EmitBindCoreCall(); EmitEndBlock(); } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs index 48474033ec1f8e..7d10f66c822fc0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs @@ -842,6 +842,11 @@ internal sealed class DerivedWithAnotherProp : AbstractBase { public int Value2 { get; set; } } + + internal class ClassWithAbstractProp + { + public AbstractBase AbstractProp { get; set; } + } internal class ClassWithAbstractCtorParam { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs index 7e635c1f0bdaa0..296cb790c22ba5 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs @@ -2324,6 +2324,25 @@ public static void TestBindingAbstractMember_AsCtorParam() Assert.Throws(configuration.Get); } + [Fact] + public static void TestBindingInitializedAbstractMember() + { + IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{ ""AbstractProp"": {""Value"":1} }"); + ClassWithAbstractProp c = new(); + c.AbstractProp = new Derived(); + configuration.Bind(c); + Assert.Equal(1, c.AbstractProp.Value); + } + + [Fact] + public static void TestBindingUninitializedAbstractMember() + { + IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{ ""AbstractProp"": {""Value"":1} }"); + ClassWithAbstractProp c = new(); + c.AbstractProp = null; + Assert.Throws(() => configuration.Bind(c)); + } + [Fact] public void GetIConfigurationSection() { From a53475c779afb17ef6f058863fae90c6be4c6726 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 17:11:02 -0700 Subject: [PATCH 363/783] Avoid membarrier on lower Android versions (#93096) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hopefully fixes #92196. I don't actually have an ARM64 device with an old Android version so I can't testing it actually fixes the problem, but it's a plausible fix. Co-authored-by: Michal Strehovský --- src/coreclr/gc/unix/gcenv.unix.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/coreclr/gc/unix/gcenv.unix.cpp b/src/coreclr/gc/unix/gcenv.unix.cpp index 285b783485802a..b45cd40d8073fe 100644 --- a/src/coreclr/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/gc/unix/gcenv.unix.cpp @@ -168,6 +168,17 @@ enum membarrier_cmd bool CanFlushUsingMembarrier() { + +#ifdef TARGET_ANDROID + // Avoid calling membarrier on older Android versions where membarrier + // may be barred by seccomp causing the process to be killed. + int apiLevel = android_get_device_api_level(); + if (apiLevel < __ANDROID_API_Q__) + { + return false; + } +#endif + // Starting with Linux kernel 4.14, process memory barriers can be generated // using MEMBARRIER_CMD_PRIVATE_EXPEDITED. From b886d5af2caf6f2974e1db47ff1d16299049dc9f Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Wed, 11 Oct 2023 17:12:22 -0700 Subject: [PATCH 364/783] [android][ios] Fix dispose problem with NativeHttpHandlers (#93262) (#93291) https://github.com/dotnet/runtime/pull/90298 made sure the MetricsHandler was the top level handler for all NativeHttpHandler requests similar to what is done with SocketsHttpHandler. After creating the MetricsHandler, the code mistakenly disposed of `_nativeHandler`, which resulted in `Dispose` being called multiple times and eventually throwing a `Cannot access a disposed object` exception. Fixes https://github.com/dotnet/runtime/issues/93252 --- .../src/System/Net/Http/HttpClientHandler.AnyMobile.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs index dd7d005dbc3c27..4b04787d3acdce 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs @@ -51,10 +51,7 @@ private HttpMessageHandler Handler MetricsHandler metricsHandler = new MetricsHandler(handler, _nativeMeterFactory, out _); // Ensure a single handler is used for all requests. - if (Interlocked.CompareExchange(ref _nativeMetricsHandler, metricsHandler, null) != null) - { - handler.Dispose(); - } + Interlocked.CompareExchange(ref _nativeMetricsHandler, metricsHandler, null); } return _nativeMetricsHandler; @@ -87,7 +84,7 @@ protected override void Dispose(bool disposing) if (IsNativeHandlerEnabled) { - _nativeHandler!.Dispose(); + Handler.Dispose(); } else { From 256bf22a3ddf920516752701da2b95e1847ff708 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 17:13:32 -0700 Subject: [PATCH 365/783] [release/8.0] Update dependencies from dotnet/roslyn (#93267) * Update dependencies from https://github.com/dotnet/roslyn build 20231009.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23504.4 -> To Version 4.8.0-3.23509.1 * Update dependencies from https://github.com/dotnet/roslyn build 20231010.8 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23504.4 -> To Version 4.8.0-3.23510.8 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ffffa99e8a4f3e..ac36c66090d197 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - 81d9274600db701a8b08ed8af3fd6b00a775cc33 + d49b29ecbf9bd72fe6023ad1b8aad9a8db7e7c3a - + https://github.com/dotnet/roslyn - 81d9274600db701a8b08ed8af3fd6b00a775cc33 + d49b29ecbf9bd72fe6023ad1b8aad9a8db7e7c3a - + https://github.com/dotnet/roslyn - 81d9274600db701a8b08ed8af3fd6b00a775cc33 + d49b29ecbf9bd72fe6023ad1b8aad9a8db7e7c3a https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index 4dd8db8ddc99e5..ecf378222daa3d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -44,9 +44,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23504.4 - 4.8.0-3.23504.4 - 4.8.0-3.23504.4 + 4.8.0-3.23510.8 + 4.8.0-3.23510.8 + 4.8.0-3.23510.8 diff --git a/eng/Versions.props b/eng/Versions.props index ecf378222daa3d..39c2e819e8eccf 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23507.6 - 1.0.0-prerelease.23507.6 - 1.0.0-prerelease.23507.6 - 1.0.0-prerelease.23507.6 - 1.0.0-prerelease.23507.6 - 1.0.0-prerelease.23507.6 + 1.0.0-prerelease.23511.2 + 1.0.0-prerelease.23511.2 + 1.0.0-prerelease.23511.2 + 1.0.0-prerelease.23511.2 + 1.0.0-prerelease.23511.2 + 1.0.0-prerelease.23511.2 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From 735d1edeecf9186ef80d5c9543eb5dbda4dbc8a8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Oct 2023 16:10:11 -0600 Subject: [PATCH 368/783] [release/8.0] JIT: Fix exponential blowup of memory dependency arrays in VNForMapSelectWork (#93388) * JIT: Fix exponential blowup of memory dependency arrays in VNForMapSelectWork Switch to sets when accumulating the memory dependencies found in VNForMapSelectWork. Otherwise we might duplicate each memory dependency for every path back to the store that induced it, and there can be an exponential number of those. Fix #93342 * Add test * Use SmallValueNumSet in MapSelectWorkCacheEntry * Revert "Use SmallValueNumSet in MapSelectWorkCacheEntry" This reverts commit b4292d762c2a0ca641c128766abc8f45236652c0. * Fix function header --------- Co-authored-by: Jakob Botsch Nielsen --- src/coreclr/jit/valuenum.cpp | 158 +++++++++++++----- src/coreclr/jit/valuenum.h | 18 +- .../JitBlue/Runtime_93342/Runtime_93342.cs | 104 ++++++++++++ .../Runtime_93342/Runtime_93342.csproj | 8 + 4 files changed, 239 insertions(+), 49 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_93342/Runtime_93342.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_93342/Runtime_93342.csproj diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 2c638535d786e4..6943c3c5e07e26 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -2860,6 +2860,81 @@ ValueNum ValueNumStore::VNForMapPhysicalSelect( return result; } +typedef JitHashTable, bool> ValueNumSet; + +class SmallValueNumSet +{ + union { + ValueNum m_inlineElements[4]; + ValueNumSet* m_set; + }; + unsigned m_numElements = 0; + +public: + unsigned Count() + { + return m_numElements; + } + + template + void ForEach(Func func) + { + if (m_numElements <= ArrLen(m_inlineElements)) + { + for (unsigned i = 0; i < m_numElements; i++) + { + func(m_inlineElements[i]); + } + } + else + { + for (ValueNum vn : ValueNumSet::KeyIteration(m_set)) + { + func(vn); + } + } + } + + void Add(Compiler* comp, ValueNum vn) + { + if (m_numElements <= ArrLen(m_inlineElements)) + { + for (unsigned i = 0; i < m_numElements; i++) + { + if (m_inlineElements[i] == vn) + { + return; + } + } + + if (m_numElements < ArrLen(m_inlineElements)) + { + m_inlineElements[m_numElements] = vn; + m_numElements++; + } + else + { + ValueNumSet* set = new (comp, CMK_ValueNumber) ValueNumSet(comp->getAllocator(CMK_ValueNumber)); + for (ValueNum oldVn : m_inlineElements) + { + set->Set(oldVn, true); + } + + set->Set(vn, true); + + m_set = set; + m_numElements++; + assert(m_numElements == set->GetCount()); + } + } + else + { + m_set->Set(vn, true, ValueNumSet::SetKind::Overwrite); + m_numElements = m_set->GetCount(); + } + } +}; + //------------------------------------------------------------------------------ // VNForMapSelectInner: Select value from a map and record loop memory dependencies. // @@ -2874,10 +2949,10 @@ ValueNum ValueNumStore::VNForMapPhysicalSelect( // ValueNum ValueNumStore::VNForMapSelectInner(ValueNumKind vnk, var_types type, ValueNum map, ValueNum index) { - int budget = m_mapSelectBudget; - bool usedRecursiveVN = false; - ArrayStack memoryDependencies(m_alloc); - ValueNum result = VNForMapSelectWork(vnk, type, map, index, &budget, &usedRecursiveVN, &memoryDependencies); + int budget = m_mapSelectBudget; + bool usedRecursiveVN = false; + SmallValueNumSet memoryDependencies; + ValueNum result = VNForMapSelectWork(vnk, type, map, index, &budget, &usedRecursiveVN, memoryDependencies); // The remaining budget should always be between [0..m_mapSelectBudget] assert((budget >= 0) && (budget <= m_mapSelectBudget)); @@ -2888,11 +2963,9 @@ ValueNum ValueNumStore::VNForMapSelectInner(ValueNumKind vnk, var_types type, Va if ((m_pComp->compCurBB != nullptr) && (m_pComp->compCurTree != nullptr) && m_pComp->compCurBB->bbNatLoopNum != BasicBlock::NOT_IN_LOOP) { - for (int i = 0; i < memoryDependencies.Height(); i++) - { - m_pComp->optRecordLoopMemoryDependence(m_pComp->compCurTree, m_pComp->compCurBB, - memoryDependencies.Bottom(i)); - } + memoryDependencies.ForEach([this](ValueNum vn) { + m_pComp->optRecordLoopMemoryDependence(m_pComp->compCurTree, m_pComp->compCurBB, vn); + }); } return result; @@ -2903,19 +2976,16 @@ ValueNum ValueNumStore::VNForMapSelectInner(ValueNumKind vnk, var_types type, Va // cache entry. // // Arguments: -// alloc - Allocator to use if memory is required. -// deps - Array stack containing the memory dependencies. -// startIndex - Start index into 'deps' of memory dependencies. +// comp - Compiler instance +// set - Set of memory dependencies to store in the entry. // -void ValueNumStore::MapSelectWorkCacheEntry::SetMemoryDependencies(CompAllocator alloc, - ArrayStack& deps, - unsigned startIndex) +void ValueNumStore::MapSelectWorkCacheEntry::SetMemoryDependencies(Compiler* comp, SmallValueNumSet& set) { - m_numMemoryDependencies = deps.Height() - startIndex; + m_numMemoryDependencies = set.Count(); ValueNum* arr; if (m_numMemoryDependencies > ArrLen(m_inlineMemoryDependencies)) { - m_memoryDependencies = new (alloc) ValueNum[m_numMemoryDependencies]; + m_memoryDependencies = new (comp, CMK_ValueNumber) ValueNum[m_numMemoryDependencies]; arr = m_memoryDependencies; } @@ -2924,27 +2994,29 @@ void ValueNumStore::MapSelectWorkCacheEntry::SetMemoryDependencies(CompAllocator arr = m_inlineMemoryDependencies; } - for (unsigned i = 0; i < m_numMemoryDependencies; i++) - { - arr[i] = deps.Bottom(startIndex + i); - } + size_t i = 0; + set.ForEach([&i, arr](ValueNum vn) { + arr[i] = vn; + i++; + }); } //------------------------------------------------------------------------------ // GetMemoryDependencies: Push all of the memory dependencies cached in this -// entry into the specified array stack. +// entry into the specified set. // // Arguments: -// result - Array stack to push memory dependencies into. +// comp - Compiler instance +// result - Set to add memory dependencies to. // -void ValueNumStore::MapSelectWorkCacheEntry::GetMemoryDependencies(ArrayStack& result) +void ValueNumStore::MapSelectWorkCacheEntry::GetMemoryDependencies(Compiler* comp, SmallValueNumSet& result) { ValueNum* arr = m_numMemoryDependencies <= ArrLen(m_inlineMemoryDependencies) ? m_inlineMemoryDependencies : m_memoryDependencies; for (unsigned i = 0; i < m_numMemoryDependencies; i++) { - result.Push(arr[i]); + result.Add(comp, arr[i]); } } @@ -2959,7 +3031,7 @@ void ValueNumStore::MapSelectWorkCacheEntry::GetMemoryDependencies(ArrayStack* memoryDependencies) +ValueNum ValueNumStore::VNForMapSelectWork(ValueNumKind vnk, + var_types type, + ValueNum map, + ValueNum index, + int* pBudget, + bool* pUsedRecursiveVN, + SmallValueNumSet& memoryDependencies) { TailCall: // This label allows us to directly implement a tail call by setting up the arguments, and doing a goto to here. @@ -2997,13 +3069,12 @@ ValueNum ValueNumStore::VNForMapSelectWork(ValueNumKind vnk, assert(selLim == 0 || m_numMapSels < selLim); #endif - int firstMemoryDependency = memoryDependencies->Height(); MapSelectWorkCacheEntry entry; VNDefFuncApp<2> fstruct(VNF_MapSelect, map, index); if (GetMapSelectWorkCache()->Lookup(fstruct, &entry)) { - entry.GetMemoryDependencies(*memoryDependencies); + entry.GetMemoryDependencies(m_pComp, memoryDependencies); return entry.Result; } @@ -3029,6 +3100,8 @@ ValueNum ValueNumStore::VNForMapSelectWork(ValueNumKind vnk, return RecursiveVN; } + SmallValueNumSet recMemoryDependencies; + VNFuncApp funcApp; if (GetVNFunc(map, &funcApp)) { @@ -3047,7 +3120,7 @@ ValueNum ValueNumStore::VNForMapSelectWork(ValueNumKind vnk, funcApp.m_args[0], map, funcApp.m_args[1], funcApp.m_args[2], index, funcApp.m_args[2]); #endif - memoryDependencies->Push(funcApp.m_args[0]); + memoryDependencies.Add(m_pComp, funcApp.m_args[0]); return funcApp.m_args[2]; } @@ -3191,7 +3264,7 @@ ValueNum ValueNumStore::VNForMapSelectWork(ValueNumKind vnk, bool allSame = true; ValueNum argRest = phiFuncApp.m_args[1]; ValueNum sameSelResult = VNForMapSelectWork(vnk, type, phiArgVN, index, pBudget, - pUsedRecursiveVN, memoryDependencies); + pUsedRecursiveVN, recMemoryDependencies); // It is possible that we just now exceeded our budget, if so we need to force an early exit // and stop calling VNForMapSelectWork @@ -3233,7 +3306,7 @@ ValueNum ValueNumStore::VNForMapSelectWork(ValueNumKind vnk, { bool usedRecursiveVN = false; ValueNum curResult = VNForMapSelectWork(vnk, type, phiArgVN, index, pBudget, - &usedRecursiveVN, memoryDependencies); + &usedRecursiveVN, recMemoryDependencies); *pUsedRecursiveVN |= usedRecursiveVN; if (sameSelResult == ValueNumStore::RecursiveVN) @@ -3261,11 +3334,14 @@ ValueNum ValueNumStore::VNForMapSelectWork(ValueNumKind vnk, if (!*pUsedRecursiveVN) { entry.Result = sameSelResult; - entry.SetMemoryDependencies(m_alloc, *memoryDependencies, firstMemoryDependency); + entry.SetMemoryDependencies(m_pComp, recMemoryDependencies); GetMapSelectWorkCache()->Set(fstruct, entry); } + recMemoryDependencies.ForEach( + [this, &memoryDependencies](ValueNum vn) { memoryDependencies.Add(m_pComp, vn); }); + return sameSelResult; } // Otherwise, fall through to creating the select(phi(m1, m2), x) function application. @@ -3294,11 +3370,13 @@ ValueNum ValueNumStore::VNForMapSelectWork(ValueNumKind vnk, fapp->m_args[1] = fstruct.m_args[1]; entry.Result = c->m_baseVN + offsetWithinChunk; - entry.SetMemoryDependencies(m_alloc, *memoryDependencies, firstMemoryDependency); + entry.SetMemoryDependencies(m_pComp, recMemoryDependencies); GetMapSelectWorkCache()->Set(fstruct, entry); } + recMemoryDependencies.ForEach([this, &memoryDependencies](ValueNum vn) { memoryDependencies.Add(m_pComp, vn); }); + return entry.Result; } diff --git a/src/coreclr/jit/valuenum.h b/src/coreclr/jit/valuenum.h index 8417579ea2ff7a..04fed7bfbc1f67 100644 --- a/src/coreclr/jit/valuenum.h +++ b/src/coreclr/jit/valuenum.h @@ -684,13 +684,13 @@ class ValueNumStore ValueNum VNForMapSelectInner(ValueNumKind vnk, var_types type, ValueNum map, ValueNum index); // A method that does the work for VNForMapSelect and may call itself recursively. - ValueNum VNForMapSelectWork(ValueNumKind vnk, - var_types type, - ValueNum map, - ValueNum index, - int* pBudget, - bool* pUsedRecursiveVN, - ArrayStack* loopMemoryDependencies); + ValueNum VNForMapSelectWork(ValueNumKind vnk, + var_types type, + ValueNum map, + ValueNum index, + int* pBudget, + bool* pUsedRecursiveVN, + class SmallValueNumSet& loopMemoryDependencies); // A specialized version of VNForFunc that is used for VNF_MapStore and provides some logging when verbose is set ValueNum VNForMapStore(ValueNum map, ValueNum index, ValueNum value); @@ -1821,8 +1821,8 @@ class ValueNumStore public: ValueNum Result; - void SetMemoryDependencies(CompAllocator alloc, ArrayStack& deps, unsigned startIndex); - void GetMemoryDependencies(ArrayStack& deps); + void SetMemoryDependencies(Compiler* comp, class SmallValueNumSet& deps); + void GetMemoryDependencies(Compiler* comp, class SmallValueNumSet& deps); }; typedef JitHashTable, VNDefFuncAppKeyFuncs<2>, MapSelectWorkCacheEntry> MapSelectWorkCache; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_93342/Runtime_93342.cs b/src/tests/JIT/Regression/JitBlue/Runtime_93342/Runtime_93342.cs new file mode 100644 index 00000000000000..6a68d7f5650797 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_93342/Runtime_93342.cs @@ -0,0 +1,104 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using Xunit; + +public class Runtime_93342 +{ + private int foo; + private int bar; + private int baz; + + [Fact] + public static void TestEntryPoint() + { + new Runtime_93342().Run(); + } + + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + private void Run() + { + if (foo == 1) + { + bar += 11; + baz += 11; + } + if (foo == 2) + bar += 12; + if (foo == 3) + bar += 13; + if (foo == 4) + bar += 14; + if (foo == 5) + bar += 15; + if (foo == 6) + bar += 16; + if (foo == 7) + bar += 17; + if (foo == 8) + bar += 18; + if (foo == 9) + bar += 19; + if (foo == 10) + bar += 20; + if (foo == 11) + bar += 21; + if (foo == 12) + bar += 22; + if (foo == 13) + bar += 23; + if (foo == 14) + bar += 24; + if (foo == 15) + bar += 25; + if (foo == 16) + bar += 26; + if (foo == 17) + bar += 27; + if (foo == 18) + bar += 28; + if (foo == 19) + bar += 29; + if (foo == 20) + bar += 30; + if (foo == 21) + bar += 31; + if (foo == 22) + bar += 32; + if (foo == 23) + bar += 33; + if (foo == 24) + bar += 34; + if (foo == 25) + bar += 35; + if (foo == 26) + bar += 36; + if (foo == 27) + bar += 37; + if (foo == 28) + bar += 38; + if (foo == 29) + bar += 39; + if (foo == 30) + bar += 40; + if (foo == 31) + bar += 41; + if (foo == 32) + bar += 42; + if (foo == 33) + bar += 43; + if (foo == 34) + bar += 44; + if (foo == 35) + bar += 45; + if (foo == 36) + bar += 46; + if (foo == 37) + bar += 47; + + bar = baz; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_93342/Runtime_93342.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_93342/Runtime_93342.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_93342/Runtime_93342.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From c47e96c35229db89c5ec55465ac9422035331553 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Fri, 13 Oct 2023 08:30:31 +0200 Subject: [PATCH 369/783] Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2290133 (#93422) --- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf index 98d7e55197f659..76a26db32a673c 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -154,12 +154,12 @@ The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. - The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + 验证特性 {0} 只能应用于字符串、数组或 ICollection 类型的属性。将它与 {1} 类型一起使用可能会导致运行时故障。 The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. - The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + 验证特性仅适用于字符串、数组或 ICollection 类型的属性;它不能与其他类型一起使用。 From fb1d8b43df3e6578929f0a1451f850ac1bd4017b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 17:31:21 -0600 Subject: [PATCH 370/783] [release/8.0] Fix Options Source Gen with Length attributes applied on properties of Interface type (#93482) * Fix Options Source Gen with LengthAttributes applied on properties of Interface type * Add more to the test case --------- Co-authored-by: Tarek Mahmoud Sayed --- .../gen/ParserUtilities.cs | 14 +- ...yTypeForLengthAttributesTests.netcore.g.cs | 252 ++++++++++++++++++ ...rtyTypeForLengthAttributesTests.netfx.g.cs | 177 ++++++++++++ .../tests/SourceGeneration.Unit.Tests/Main.cs | 44 +++ .../OptionsRuntimeTests.cs | 39 +++ 5 files changed, 525 insertions(+), 1 deletion(-) create mode 100644 src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/UsingInterfaceAsPropertyTypeForLengthAttributesTests.netcore.g.cs create mode 100644 src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/UsingInterfaceAsPropertyTypeForLengthAttributesTests.netfx.g.cs diff --git a/src/libraries/Microsoft.Extensions.Options/gen/ParserUtilities.cs b/src/libraries/Microsoft.Extensions.Options/gen/ParserUtilities.cs index 675202538e12d2..0b63cc90c800ed 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/ParserUtilities.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/ParserUtilities.cs @@ -80,7 +80,7 @@ internal static bool TypeHasProperty(ITypeSymbol typeSymbol, string propertyName if (type.GetMembers(propertyName).OfType().Any(property => property.Type.SpecialType == returnType && property.DeclaredAccessibility == Accessibility.Public && - !property.IsStatic && property.GetMethod != null && property.Parameters.IsEmpty)) + property.Kind == SymbolKind.Property && !property.IsStatic && property.GetMethod != null && property.Parameters.IsEmpty)) { return true; } @@ -88,6 +88,18 @@ internal static bool TypeHasProperty(ITypeSymbol typeSymbol, string propertyName type = type.BaseType; } while (type is not null && type.SpecialType != SpecialType.System_Object); + // When we have an interface type, we need to check all the interfaces that it extends. + // Like IList extends ICollection where the property we're looking for is defined. + foreach (var interfaceType in typeSymbol.AllInterfaces) + { + if (interfaceType.GetMembers(propertyName).OfType().Any(property => + property.Type.SpecialType == returnType && property.Kind == SymbolKind.Property && + !property.IsStatic && property.GetMethod != null && property.Parameters.IsEmpty)) + { + return true; + } + } + return false; } diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/UsingInterfaceAsPropertyTypeForLengthAttributesTests.netcore.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/UsingInterfaceAsPropertyTypeForLengthAttributesTests.netcore.g.cs new file mode 100644 index 00000000000000..1cd942fab0f1bb --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/UsingInterfaceAsPropertyTypeForLengthAttributesTests.netcore.g.cs @@ -0,0 +1,252 @@ + + // + #nullable enable + #pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103 + namespace Test +{ + partial class MyOptionsValidator + { + /// + /// Validates a specific named options instance (or all when is ). + /// + /// The name of the options instance being validated. + /// The options instance. + /// Validation result. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] + public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Test.MyOptions options) + { + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; + var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); + var validationResults = new global::System.Collections.Generic.List(); + var validationAttributes = new global::System.Collections.Generic.List(1); + + context.MemberName = "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P1" : $"{name}.P1"; + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P2" : $"{name}.P2"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P3" : $"{name}.P3"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P4" : $"{name}.P4"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P5" : $"{name}.P5"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P6" : $"{name}.P6"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A3); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); + } + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Attributes + { + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__LengthAttribute A1 = new __OptionValidationGeneratedAttributes.__SourceGen__LengthAttribute( + (int)10, + (int)20); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__MinLengthAttribute A2 = new __OptionValidationGeneratedAttributes.__SourceGen__MinLengthAttribute( + (int)4); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__MaxLengthAttribute A3 = new __OptionValidationGeneratedAttributes.__SourceGen__MaxLengthAttribute( + (int)5); + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Validators + { + } +} +namespace __OptionValidationGeneratedAttributes +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__LengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "The field {0} must be a string or collection type with a minimum length of '{1}' and maximum length of '{2}'."; + public __SourceGen__LengthAttribute(int minimumLength, int maximumLength) : base(() => DefaultErrorMessageString) { MinimumLength = minimumLength; MaximumLength = maximumLength; } + public int MinimumLength { get; } + public int MaximumLength { get; } + public override bool IsValid(object? value) + { + if (MinimumLength < 0) + { + throw new global::System.InvalidOperationException("LengthAttribute must have a MinimumLength value that is zero or greater."); + } + if (MaximumLength < MinimumLength) + { + throw new global::System.InvalidOperationException("LengthAttribute must have a MaximumLength value that is greater than or equal to MinimumLength."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::System.Collections.Generic.IList) + { + length = ((global::System.Collections.Generic.IList)value).Count; + } + else if (value is global::System.Collections.Generic.ICollection) + { + length = ((global::System.Collections.Generic.ICollection)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return (uint)(length - MinimumLength) <= (uint)(MaximumLength - MinimumLength); + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, MinimumLength, MaximumLength); + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__MaxLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private const int MaxAllowableLength = -1; + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a maximum length of '{1}'."; + public __SourceGen__MaxLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public __SourceGen__MaxLengthAttribute(): base(() => DefaultErrorMessageString) { Length = MaxAllowableLength; } + public int Length { get; } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + public override bool IsValid(object? value) + { + if (Length == 0 || Length < -1) + { + throw new global::System.InvalidOperationException("MaxLengthAttribute must have a Length value that is greater than zero. Use MaxLength() without parameters to indicate that the string or array can have the maximum allowable length."); + } + if (value == null || MaxAllowableLength == Length) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::System.Collections.Generic.IList) + { + length = ((global::System.Collections.Generic.IList)value).Count; + } + else if (value is global::System.Collections.Generic.ICollection) + { + length = ((global::System.Collections.Generic.ICollection)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length <= Length; + } + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__MinLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a minimum length of '{1}'."; + + public __SourceGen__MinLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public int Length { get; } + public override bool IsValid(object? value) + { + if (Length < -1) + { + throw new global::System.InvalidOperationException("MinLengthAttribute must have a Length value that is zero or greater."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::System.Collections.Generic.IList) + { + length = ((global::System.Collections.Generic.IList)value).Count; + } + else if (value is global::System.Collections.Generic.ICollection) + { + length = ((global::System.Collections.Generic.ICollection)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length >= Length; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + } +} diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/UsingInterfaceAsPropertyTypeForLengthAttributesTests.netfx.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/UsingInterfaceAsPropertyTypeForLengthAttributesTests.netfx.g.cs new file mode 100644 index 00000000000000..603680a9ec732c --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/UsingInterfaceAsPropertyTypeForLengthAttributesTests.netfx.g.cs @@ -0,0 +1,177 @@ + + // + #nullable enable + #pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103 + namespace Test +{ + partial class MyOptionsValidator + { + /// + /// Validates a specific named options instance (or all when is ). + /// + /// The name of the options instance being validated. + /// The options instance. + /// Validation result. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::Test.MyOptions options) + { + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; + var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); + var validationResults = new global::System.Collections.Generic.List(); + var validationAttributes = new global::System.Collections.Generic.List(1); + + context.MemberName = "P2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P2" : $"{name}.P2"; + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P3" : $"{name}.P3"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P5"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P5" : $"{name}.P5"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P5, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P6"; + context.DisplayName = string.IsNullOrEmpty(name) ? "MyOptions.P6" : $"{name}.P6"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A2); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P6, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); + } + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Attributes + { + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__MinLengthAttribute A1 = new __OptionValidationGeneratedAttributes.__SourceGen__MinLengthAttribute( + (int)4); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__MaxLengthAttribute A2 = new __OptionValidationGeneratedAttributes.__SourceGen__MaxLengthAttribute( + (int)5); + } +} +namespace __OptionValidationStaticInstances +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + file static class __Validators + { + } +} +namespace __OptionValidationGeneratedAttributes +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__MaxLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private const int MaxAllowableLength = -1; + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a maximum length of '{1}'."; + public __SourceGen__MaxLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public __SourceGen__MaxLengthAttribute(): base(() => DefaultErrorMessageString) { Length = MaxAllowableLength; } + public int Length { get; } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + public override bool IsValid(object? value) + { + if (Length == 0 || Length < -1) + { + throw new global::System.InvalidOperationException("MaxLengthAttribute must have a Length value that is greater than zero. Use MaxLength() without parameters to indicate that the string or array can have the maximum allowable length."); + } + if (value == null || MaxAllowableLength == Length) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::System.Collections.Generic.IList) + { + length = ((global::System.Collections.Generic.IList)value).Count; + } + else if (value is global::System.Collections.Generic.ICollection) + { + length = ((global::System.Collections.Generic.ICollection)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length <= Length; + } + } + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] + file class __SourceGen__MinLengthAttribute : global::System.ComponentModel.DataAnnotations.ValidationAttribute + { + private static string DefaultErrorMessageString => "The field {0} must be a string or array type with a minimum length of '{1}'."; + + public __SourceGen__MinLengthAttribute(int length) : base(() => DefaultErrorMessageString) { Length = length; } + public int Length { get; } + public override bool IsValid(object? value) + { + if (Length < -1) + { + throw new global::System.InvalidOperationException("MinLengthAttribute must have a Length value that is zero or greater."); + } + if (value == null) + { + return true; + } + + int length; + if (value is string stringValue) + { + length = stringValue.Length; + } + else if (value is System.Collections.ICollection collectionValue) + { + length = collectionValue.Count; + } + else if (value is global::System.Collections.Generic.IList) + { + length = ((global::System.Collections.Generic.IList)value).Count; + } + else if (value is global::System.Collections.Generic.ICollection) + { + length = ((global::System.Collections.Generic.ICollection)value).Count; + } + else + { + throw new global::System.InvalidCastException($"The field of type {value.GetType()} must be a string, array, or ICollection type."); + } + + return length >= Length; + } + public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Length); + } +} diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs index da893126a14b88..623251707f87ba 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs @@ -1813,4 +1813,48 @@ public sealed partial class OptionsUsingGeneratedAttributesValidator : IValidate Assert.True(emitResult.Success); // Console.WriteLine(emittedSource); } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + public async Task UsingInterfaceAsPropertyTypeForLengthAttributesTests() + { + var (diagnostics, generatedSources) = await RunGenerator(@""" + using System.Collections.Generic; + + public class MyOptions + { + [Length(10, 20)] + public IList P1 { get; set; } + + [MinLength(4)] + public IList P2 { get; set; } + + [MaxLength(5)] + public IList P3 { get; set; } + + [Length(10, 20)] + public ICollection P4 { get; set; } + + [MinLength(4)] + public ICollection P5 { get; set; } + + [MaxLength(5)] + public ICollection P6 { get; set; } + } + + [OptionsValidator] + public partial class MyOptionsValidator : IValidateOptions + { + } + """); + + Assert.Empty(diagnostics); + Assert.Single(generatedSources); + +#if NETCOREAPP + string generatedSource = File.ReadAllText(@"Baselines/UsingInterfaceAsPropertyTypeForLengthAttributesTests.netcore.g.cs"); +#else + string generatedSource = File.ReadAllText(@"Baselines/UsingInterfaceAsPropertyTypeForLengthAttributesTests.netfx.g.cs"); +#endif // NETCOREAPP + Assert.Equal(generatedSource.Replace("\r\n", "\n"), generatedSources[0].SourceText.ToString().Replace("\r\n", "\n")); + } } diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs index 78783d7a537e29..d9bd0808cf77f6 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs @@ -287,6 +287,12 @@ public void TestCustomGeneratedAttributes() P23 = new List() { "1", "2", "3", "4" }, P24 = new FakeCount(4), P25 = new FakeCountChild(4), + P27 = new List { "1", "2" }, + P28 = new HashSet { "1", "2" }, + P29 = new List { "1", "2", "3" }, + P30 = new HashSet { "1", "2", "3" }, + P31 = new List { 1, 2, 3, 4 }, + P32 = new HashSet { 1, 2, 3, 4 }, #endif // NET8_0_OR_GREATER P1 = 2, P2 = "12345", @@ -325,6 +331,12 @@ public void TestCustomGeneratedAttributes() P23 = new List() { "1", "2", "3", "4", "5" }, P24 = new FakeCount(5), P25 = new FakeCountChild(5), + P27 = new List { "1" }, + P28 = new HashSet { "1" }, + P29 = new List { "1", "2" }, + P30 = new HashSet { "1", "2" }, + P31 = new List { 1, 2, 3, 4, 5 }, + P32 = new HashSet { 1, 2, 3, 4, 5 }, #endif // NET8_0_OR_GREATER P1 = 4, P2 = "1234", @@ -362,6 +374,12 @@ public void TestCustomGeneratedAttributes() "P23: The field OptionsUsingGeneratedAttributes.P23 must be a string or array type with a maximum length of '4'.", "P24: The field OptionsUsingGeneratedAttributes.P24 must be a string or array type with a maximum length of '4'.", "P25: The field OptionsUsingGeneratedAttributes.P25 must be a string or array type with a maximum length of '4'.", + "P27: The field OptionsUsingGeneratedAttributes.P27 must be a string or collection type with a minimum length of '2' and maximum length of '10'.", + "P28: The field OptionsUsingGeneratedAttributes.P28 must be a string or collection type with a minimum length of '2' and maximum length of '10'.", + "P29: The field OptionsUsingGeneratedAttributes.P29 must be a string or array type with a minimum length of '3'.", + "P30: The field OptionsUsingGeneratedAttributes.P30 must be a string or array type with a minimum length of '3'.", + "P31: The field OptionsUsingGeneratedAttributes.P31 must be a string or array type with a maximum length of '4'.", + "P32: The field OptionsUsingGeneratedAttributes.P32 must be a string or array type with a maximum length of '4'.", #endif // NET8_0_OR_GREATER "P1: The field OptionsUsingGeneratedAttributes.P1 must be between 1 and 3.", "P2: The field OptionsUsingGeneratedAttributes.P2 must be a string or array type with a minimum length of '5'.", @@ -412,6 +430,9 @@ public class OptionsUsingGeneratedAttributes [LengthAttribute(2, 10)] public int[] P17 { get; set; } + // Although MinLength and MaxLength attributes defined in NETFX but the implementation there has a bug which can produce exception like the following when using types like List: + // System.InvalidCastException : Unable to cast object of type 'System.Collections.Generic.List`1[System.String]' to type 'System.Array'. + [MinLengthAttribute(3)] public List P18 { get; set; } @@ -429,6 +450,24 @@ public class OptionsUsingGeneratedAttributes [MaxLengthAttribute(4)] public FakeCountChild P25 { get; set; } + + [LengthAttribute(2, 10)] + public IList P27 { get; set; } + + [LengthAttribute(2, 10)] + public ICollection P28 { get; set; } + + [MinLengthAttribute(3)] + public IList P29 { get; set; } + + [MinLengthAttribute(3)] + public ICollection P30 { get; set; } + + [MaxLengthAttribute(4)] + public IList P31 { get; set; } + + [MaxLengthAttribute(4)] + public ICollection P32 { get; set; } #endif // NET8_0_OR_GREATER [RangeAttribute(1, 3)] From ae26d3e6dabec5dd0f030aed8849480f1a12461b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 17:31:33 -0600 Subject: [PATCH 371/783] Optimize Options Source Gen when no need to run (#93481) Co-authored-by: Tarek Mahmoud Sayed --- src/libraries/Microsoft.Extensions.Options/gen/Generator.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Generator.cs b/src/libraries/Microsoft.Extensions.Options/gen/Generator.cs index e9c1f55fcca512..02fb554ca0b487 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Generator.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/Generator.cs @@ -32,6 +32,11 @@ public void Initialize(IncrementalGeneratorInitializationContext context) private static void HandleAnnotatedTypes(Compilation compilation, ImmutableArray<(TypeDeclarationSyntax? TypeSyntax, SemanticModel SemanticModel)> types, SourceProductionContext context) { + if (types.Length == 0) + { + return; + } + if (!SymbolLoader.TryLoad(compilation, out var symbolHolder)) { // Not eligible compilation From a73130949273dc4c2653c931177e89558bd17db0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 17:32:36 -0600 Subject: [PATCH 372/783] Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231012.4 (#93470) optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23511.2 -> To Version 1.0.0-prerelease.23512.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e72471e5f27861..e3156fbc00396b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -334,21 +334,21 @@ https://github.com/dotnet/arcade 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 40e7efea1d9c81ef4321f0212807e65c9ddfe922 + 17ea99c28d05ae088ff372f517e63f91c7b715ae - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 40e7efea1d9c81ef4321f0212807e65c9ddfe922 + 17ea99c28d05ae088ff372f517e63f91c7b715ae - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 40e7efea1d9c81ef4321f0212807e65c9ddfe922 + 17ea99c28d05ae088ff372f517e63f91c7b715ae - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 40e7efea1d9c81ef4321f0212807e65c9ddfe922 + 17ea99c28d05ae088ff372f517e63f91c7b715ae https://github.com/dotnet/hotreload-utils @@ -384,13 +384,13 @@ d10b02ae5cc670609d920a672985ed4456bdd6b6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 40e7efea1d9c81ef4321f0212807e65c9ddfe922 + 17ea99c28d05ae088ff372f517e63f91c7b715ae - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 40e7efea1d9c81ef4321f0212807e65c9ddfe922 + 17ea99c28d05ae088ff372f517e63f91c7b715ae diff --git a/eng/Versions.props b/eng/Versions.props index 39c2e819e8eccf..7078c2d2f01eb5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23511.2 - 1.0.0-prerelease.23511.2 - 1.0.0-prerelease.23511.2 - 1.0.0-prerelease.23511.2 - 1.0.0-prerelease.23511.2 - 1.0.0-prerelease.23511.2 + 1.0.0-prerelease.23512.4 + 1.0.0-prerelease.23512.4 + 1.0.0-prerelease.23512.4 + 1.0.0-prerelease.23512.4 + 1.0.0-prerelease.23512.4 + 1.0.0-prerelease.23512.4 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From 9e8d54809efebe65583af88ab0720fd729c3fca7 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Fri, 13 Oct 2023 19:34:03 -0400 Subject: [PATCH 373/783] [release/8.0][wasm] Update workload description to include target framework (#93359) * [wasm] Update workload description to include target framework Issue: https://github.com/dotnet/runtime/issues/93314 * Update description for wasm-experimental, and wasi-experimental also --- .../WorkloadManifest.json.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in index 5af8dcbd94e17e..076e642d2b6209 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in @@ -5,7 +5,7 @@ }, "workloads": { "wasm-tools": { - "description": ".NET WebAssembly build tools", + "description": ".NET WebAssembly build tools for net8.0", "packs": [ "Microsoft.NET.Runtime.WebAssembly.Sdk", "Microsoft.NETCore.App.Runtime.Mono.browser-wasm", @@ -15,7 +15,7 @@ "platforms": [ "win-x64", "win-arm64", "linux-x64", "linux-arm64", "osx-x64", "osx-arm64"] }, "wasm-experimental": { - "description": ".NET WebAssembly experimental tooling", + "description": ".NET WebAssembly experimental tooling for net8.0", "packs": [ "Microsoft.NET.Runtime.WebAssembly.Templates", "Microsoft.NETCore.App.Runtime.Mono.multithread.browser-wasm", @@ -24,7 +24,7 @@ "platforms": [ "win-x64", "win-arm64", "linux-x64", "linux-arm64", "osx-x64", "osx-arm64" ] }, "wasi-experimental": { - "description": ".NET WASI experimental", + "description": ".NET WASI experimental for net8.0", "packs": [ "Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk", "Microsoft.NETCore.App.Runtime.Mono.wasi-wasm", From 60b77a63df30362ed1c66a834fcb8f8956ea113b Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 14 Oct 2023 01:35:38 +0200 Subject: [PATCH 374/783] [release/8.0] Adjust System.Net metrics for OTel conformance and consistency (#93414) * Rename `server.socket.address` to `network.peer.address` (#93255) * Report Exception.FullName for http.client.request.duration/error.type (#93322) * Adjust the DNS lookup duration metric (#93254) --- .../System/Net/Http/Metrics/MetricsHandler.cs | 2 +- .../Metrics/ConnectionMetrics.cs | 10 +++--- .../tests/FunctionalTests/MetricsTest.cs | 14 ++++---- .../src/System/Net/Dns.cs | 34 +++++++++++-------- .../src/System/Net/NameResolutionMetrics.cs | 26 ++++++++++++-- .../src/System/Net/NameResolutionTelemetry.cs | 6 ++-- .../tests/FunctionalTests/MetricsTest.cs | 17 +++++++--- 7 files changed, 71 insertions(+), 38 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs index 1f353f167150e5..4de6df347972fe 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs @@ -169,7 +169,7 @@ private static bool TryGetErrorType(HttpResponseMessage? response, Exception? ex HttpRequestError.ConfigurationLimitExceeded => "configuration_limit_exceeded", // Fall back to the exception type name in case of HttpRequestError.Unknown or when exception is not an HttpRequestException. - _ => exception.GetType().Name + _ => exception.GetType().FullName! }; return true; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Metrics/ConnectionMetrics.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Metrics/ConnectionMetrics.cs index a9498cdc948dfb..12dbdface7398f 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Metrics/ConnectionMetrics.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Metrics/ConnectionMetrics.cs @@ -14,10 +14,10 @@ internal sealed class ConnectionMetrics private readonly object _schemeTag; private readonly object _hostTag; private readonly object? _portTag; - private readonly object? _socketAddressTag; + private readonly object? _peerAddressTag; private bool _currentlyIdle; - public ConnectionMetrics(SocketsHttpHandlerMetrics metrics, string protocolVersion, string scheme, string host, int? port, string? socketAddress) + public ConnectionMetrics(SocketsHttpHandlerMetrics metrics, string protocolVersion, string scheme, string host, int? port, string? peerAddress) { _metrics = metrics; _openConnectionsEnabled = _metrics.OpenConnections.Enabled; @@ -25,7 +25,7 @@ public ConnectionMetrics(SocketsHttpHandlerMetrics metrics, string protocolVersi _schemeTag = scheme; _hostTag = host; _portTag = port; - _socketAddressTag = socketAddress; + _peerAddressTag = peerAddress; } // TagList is a huge struct, so we avoid storing it in a field to reduce the amount we allocate on the heap. @@ -42,9 +42,9 @@ private TagList GetTags() tags.Add("server.port", _portTag); } - if (_socketAddressTag is not null) + if (_peerAddressTag is not null) { - tags.Add("server.socket.address", _socketAddressTag); + tags.Add("network.peer.address", _peerAddressTag); } return tags; diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs index 76b646dd21a74f..4bf2638f9d3515 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs @@ -47,9 +47,9 @@ protected static void VerifyTag(KeyValuePair[] tags, string } } - private static void VerifySocketAddress(KeyValuePair[] tags) + private static void VerifyPeerAddress(KeyValuePair[] tags) { - string ipString = (string)tags.Single(t => t.Key == "server.socket.address").Value; + string ipString = (string)tags.Single(t => t.Key == "network.peer.address").Value; IPAddress ip = IPAddress.Parse(ipString); Assert.True(ip.Equals(IPAddress.Loopback.MapToIPv6()) || ip.Equals(IPAddress.Loopback) || @@ -122,7 +122,7 @@ protected static void VerifyOpenConnections(string actualName, object measuremen VerifySchemeHostPortTags(tags, uri); VerifyTag(tags, "network.protocol.version", GetVersionString(protocolVersion)); VerifyTag(tags, "http.connection.state", state); - VerifySocketAddress(tags); + VerifyPeerAddress(tags); } protected static void VerifyConnectionDuration(string instrumentName, object measurement, KeyValuePair[] tags, Uri uri, Version? protocolVersion) @@ -132,7 +132,7 @@ protected static void VerifyConnectionDuration(string instrumentName, object mea Assert.InRange(value, double.Epsilon, 60); VerifySchemeHostPortTags(tags, uri); VerifyTag(tags, "network.protocol.version", GetVersionString(protocolVersion)); - VerifySocketAddress(tags); + VerifyPeerAddress(tags); } protected static void VerifyTimeInQueue(string instrumentName, object measurement, KeyValuePair[] tags, Uri uri, Version? protocolVersion, string method = "GET") @@ -670,8 +670,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => _output.WriteLine($"Client exception: {clientException}"); string[] expectedExceptionTypes = TestAsync - ? [nameof(TaskCanceledException)] - : [nameof(TaskCanceledException), nameof(OperationCanceledException)]; + ? [typeof(TaskCanceledException).FullName] + : [typeof(TaskCanceledException).FullName, typeof(OperationCanceledException).FullName]; Measurement m = Assert.Single(recorder.GetMeasurements()); VerifyRequestDuration(m, uri, acceptedErrorTypes: expectedExceptionTypes); @@ -852,7 +852,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.True(ex is HttpRequestException or TaskCanceledException); Measurement m = Assert.Single(recorder.GetMeasurements()); - VerifyRequestDuration(m, uri, acceptedErrorTypes: [nameof(TaskCanceledException), "response_ended"]); + VerifyRequestDuration(m, uri, acceptedErrorTypes: [typeof(TaskCanceledException).FullName, "response_ended"]); }, async server => { try diff --git a/src/libraries/System.Net.NameResolution/src/System/Net/Dns.cs b/src/libraries/System.Net.NameResolution/src/System/Net/Dns.cs index f4b09f346b3d9a..8227d58ebb61b6 100644 --- a/src/libraries/System.Net.NameResolution/src/System/Net/Dns.cs +++ b/src/libraries/System.Net.NameResolution/src/System/Net/Dns.cs @@ -23,13 +23,13 @@ public static string GetHostName() { name = NameResolutionPal.GetHostName(); } - catch when (LogFailure(string.Empty, startingTimestamp)) + catch (Exception ex) when (LogFailure(string.Empty, startingTimestamp, ex)) { Debug.Fail("LogFailure should return false"); throw; } - NameResolutionTelemetry.Log.AfterResolution(string.Empty, startingTimestamp, successful: true); + NameResolutionTelemetry.Log.AfterResolution(string.Empty, startingTimestamp); if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(null, name); return name; @@ -394,13 +394,13 @@ private static object GetHostEntryOrAddressesCore(string hostName, bool justAddr Aliases = aliases }; } - catch when (LogFailure(hostName, startingTimestamp)) + catch (Exception ex) when (LogFailure(hostName, startingTimestamp, ex)) { Debug.Fail("LogFailure should return false"); throw; } - NameResolutionTelemetry.Log.AfterResolution(hostName, startingTimestamp, successful: true); + NameResolutionTelemetry.Log.AfterResolution(hostName, startingTimestamp); return result; } @@ -434,13 +434,13 @@ private static object GetHostEntryOrAddressesCore(IPAddress address, bool justAd } Debug.Assert(name != null); } - catch when (LogFailure(address, startingTimestamp)) + catch (Exception ex) when (LogFailure(address, startingTimestamp, ex)) { Debug.Fail("LogFailure should return false"); throw; } - NameResolutionTelemetry.Log.AfterResolution(address, startingTimestamp, successful: true); + NameResolutionTelemetry.Log.AfterResolution(address, startingTimestamp); // Do the forward lookup to get the IPs for that host name startingTimestamp = NameResolutionTelemetry.Log.BeforeResolution(name); @@ -464,13 +464,13 @@ private static object GetHostEntryOrAddressesCore(IPAddress address, bool justAd AddressList = addresses }; } - catch when (LogFailure(name, startingTimestamp)) + catch (Exception ex) when (LogFailure(name, startingTimestamp, ex)) { Debug.Fail("LogFailure should return false"); throw; } - NameResolutionTelemetry.Log.AfterResolution(name, startingTimestamp, successful: true); + NameResolutionTelemetry.Log.AfterResolution(name, startingTimestamp); // One of three things happened: // 1. Success. @@ -577,7 +577,7 @@ private static Task GetHostEntryOrAddressesCoreAsync(string hostName, bool justR } private static Task? GetAddrInfoWithTelemetryAsync(string hostName, bool justAddresses, AddressFamily addressFamily, CancellationToken cancellationToken) - where T : class + where T : class { long startingTimestamp = Stopwatch.GetTimestamp(); Task? task = NameResolutionPal.GetAddrInfoAsync(hostName, justAddresses, addressFamily, cancellationToken); @@ -594,15 +594,19 @@ private static Task GetHostEntryOrAddressesCoreAsync(string hostName, bool justR static async Task CompleteAsync(Task task, string hostName, long startingTimestamp) { _ = NameResolutionTelemetry.Log.BeforeResolution(hostName); - T? result = null; + Exception? exception = null; try { - result = await ((Task)task).ConfigureAwait(false); - return result; + return await ((Task)task).ConfigureAwait(false); + } + catch (Exception ex) + { + exception = ex; + throw; } finally { - NameResolutionTelemetry.Log.AfterResolution(hostName, startingTimestamp, successful: result is not null); + NameResolutionTelemetry.Log.AfterResolution(hostName, startingTimestamp, exception); } } } @@ -627,9 +631,9 @@ private static void ValidateHostName(string hostName) } } - private static bool LogFailure(object hostNameOrAddress, long? startingTimestamp) + private static bool LogFailure(object hostNameOrAddress, long? startingTimestamp, Exception exception) { - NameResolutionTelemetry.Log.AfterResolution(hostNameOrAddress, startingTimestamp, successful: false); + NameResolutionTelemetry.Log.AfterResolution(hostNameOrAddress, startingTimestamp, exception); return false; } diff --git a/src/libraries/System.Net.NameResolution/src/System/Net/NameResolutionMetrics.cs b/src/libraries/System.Net.NameResolution/src/System/Net/NameResolutionMetrics.cs index 180f492b3408e2..fe1048e90b22de 100644 --- a/src/libraries/System.Net.NameResolution/src/System/Net/NameResolutionMetrics.cs +++ b/src/libraries/System.Net.NameResolution/src/System/Net/NameResolutionMetrics.cs @@ -13,15 +13,35 @@ internal static class NameResolutionMetrics private static readonly Meter s_meter = new("System.Net.NameResolution"); private static readonly Histogram s_lookupDuration = s_meter.CreateHistogram( - name: "dns.lookups.duration", + name: "dns.lookup.duration", unit: "s", description: "Measures the time taken to perform a DNS lookup."); public static bool IsEnabled() => s_lookupDuration.Enabled; - public static void AfterResolution(TimeSpan duration, string hostName) + public static void AfterResolution(TimeSpan duration, string hostName, Exception? exception) { - s_lookupDuration.Record(duration.TotalSeconds, KeyValuePair.Create("dns.question.name", (object?)hostName)); + var hostNameTag = KeyValuePair.Create("dns.question.name", (object?)hostName); + + if (exception is null) + { + s_lookupDuration.Record(duration.TotalSeconds, hostNameTag); + } + else + { + var errorTypeTag = KeyValuePair.Create("error.type", (object?)GetErrorType(exception)); + s_lookupDuration.Record(duration.TotalSeconds, hostNameTag, errorTypeTag); + } } + + private static string GetErrorType(Exception exception) => (exception as SocketException)?.SocketErrorCode switch + { + SocketError.HostNotFound => "host_not_found", + SocketError.TryAgain => "try_again", + SocketError.AddressFamilyNotSupported => "address_family_not_supported", + SocketError.NoRecovery => "no_recovery", + + _ => exception.GetType().FullName! + }; } } diff --git a/src/libraries/System.Net.NameResolution/src/System/Net/NameResolutionTelemetry.cs b/src/libraries/System.Net.NameResolution/src/System/Net/NameResolutionTelemetry.cs index ef43b59d15a139..73ed325712ac52 100644 --- a/src/libraries/System.Net.NameResolution/src/System/Net/NameResolutionTelemetry.cs +++ b/src/libraries/System.Net.NameResolution/src/System/Net/NameResolutionTelemetry.cs @@ -81,7 +81,7 @@ public long BeforeResolution(object hostNameOrAddress) } [NonEvent] - public void AfterResolution(object hostNameOrAddress, long? startingTimestamp, bool successful) + public void AfterResolution(object hostNameOrAddress, long? startingTimestamp, Exception? exception = null) { Debug.Assert(startingTimestamp.HasValue); if (startingTimestamp == 0) @@ -99,7 +99,7 @@ public void AfterResolution(object hostNameOrAddress, long? startingTimestamp, b if (IsEnabled(EventLevel.Informational, EventKeywords.None)) { - if (!successful) + if (exception is not null) { ResolutionFailed(); } @@ -110,7 +110,7 @@ public void AfterResolution(object hostNameOrAddress, long? startingTimestamp, b if (NameResolutionMetrics.IsEnabled()) { - NameResolutionMetrics.AfterResolution(duration, GetHostnameFromStateObject(hostNameOrAddress)); + NameResolutionMetrics.AfterResolution(duration, GetHostnameFromStateObject(hostNameOrAddress), exception); } } diff --git a/src/libraries/System.Net.NameResolution/tests/FunctionalTests/MetricsTest.cs b/src/libraries/System.Net.NameResolution/tests/FunctionalTests/MetricsTest.cs index d3c0990dbf9c4c..a19d9edc476abc 100644 --- a/src/libraries/System.Net.NameResolution/tests/FunctionalTests/MetricsTest.cs +++ b/src/libraries/System.Net.NameResolution/tests/FunctionalTests/MetricsTest.cs @@ -14,7 +14,7 @@ namespace System.Net.NameResolution.Tests { public class MetricsTest { - private const string DnsLookupDuration = "dns.lookups.duration"; + private const string DnsLookupDuration = "dns.lookup.duration"; [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] public static void ResolveValidHostName_MetricsRecorded() @@ -57,17 +57,26 @@ public static async Task ResolveInvalidHostName_MetricsRecorded() Assert.ThrowsAny(() => Dns.EndGetHostEntry(Dns.BeginGetHostEntry(InvalidHostName, null, null))); Assert.ThrowsAny(() => Dns.EndGetHostAddresses(Dns.BeginGetHostAddresses(InvalidHostName, null, null))); - double[] measurements = GetMeasurementsForHostname(recorder, InvalidHostName); + double[] measurements = GetMeasurementsForHostname(recorder, InvalidHostName, "host_not_found"); Assert.Equal(6, measurements.Length); Assert.All(measurements, m => Assert.True(m > double.Epsilon)); } - private static double[] GetMeasurementsForHostname(InstrumentRecorder recorder, string hostname) + private static double[] GetMeasurementsForHostname(InstrumentRecorder recorder, string hostname, string? expectedErrorType = null) { return recorder .GetMeasurements() - .Where(m => m.Tags.ToArray().Any(t => t.Key == "dns.question.name" && t.Value is string hostnameTag && hostnameTag == hostname)) + .Where(m => + { + KeyValuePair[] tags = m.Tags.ToArray(); + if (!tags.Any(t => t.Key == "dns.question.name" && t.Value is string hostnameTag && hostnameTag == hostname)) + { + return false; + } + string? actualErrorType = tags.FirstOrDefault(t => t.Key == "error.type").Value as string; + return expectedErrorType == actualErrorType; + }) .Select(m => m.Value) .ToArray(); } From 1878c5515e78fbc527c721f38dca94e9fceb55d8 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Sat, 14 Oct 2023 10:22:08 +0200 Subject: [PATCH 375/783] Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2291029 (#93496) * Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2290974 * Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 2290974 --- .../gen/Resources/xlf/Strings.cs.xlf | 4 ++-- .../gen/Resources/xlf/Strings.de.xlf | 4 ++-- .../gen/Resources/xlf/Strings.es.xlf | 4 ++-- .../gen/Resources/xlf/Strings.fr.xlf | 4 ++-- .../gen/Resources/xlf/Strings.it.xlf | 4 ++-- .../gen/Resources/xlf/Strings.ja.xlf | 4 ++-- .../gen/Resources/xlf/Strings.ko.xlf | 4 ++-- .../gen/Resources/xlf/Strings.pl.xlf | 4 ++-- .../gen/Resources/xlf/Strings.pt-BR.xlf | 4 ++-- .../gen/Resources/xlf/Strings.ru.xlf | 4 ++-- .../gen/Resources/xlf/Strings.tr.xlf | 4 ++-- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 4 ++-- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf index 77769cb3ca4ab2..c8490d951761cb 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.cs.xlf @@ -154,12 +154,12 @@ The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. - The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + Ověřovací atribut {0} by měl být použit pouze na vlastnosti typu string, array nebo ICollection. Použití s typem {1} může vést k selháním modulu runtime. The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. - The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + Ověřovací atribut se vztahuje pouze na vlastnosti typu string, array nebo ICollection; nelze použít s jinými typy. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf index e5defa5eeb3e2f..eb7a7f423a3e70 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.de.xlf @@ -154,12 +154,12 @@ The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. - The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + Das Validierungsattribut {0} sollte nur auf Eigenschaften vom Typ "string", "array" oder "ICollection" angewendet werden. Die Verwendung mit dem Typ {1} kann zu Laufzeitfehlern führen. The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. - The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + Das Validierungsattribut gilt nur für Eigenschaften vom Typ "string", "array" oder "ICollection"; es kann nicht mit anderen Typen verwendet werden. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf index 728e01d7b598a9..19c69bb8c864f9 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.es.xlf @@ -154,12 +154,12 @@ The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. - The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + El atributo de validación {0} solo se debe aplicar a propiedades de tipo cadena, matriz o ICollection. Si la usa con el tipo {1}, podrían producirse errores en tiempo de ejecución. The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. - The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + El atributo de validación solo es aplicable a propiedades de tipo cadena, matriz o ICollection; no se puede usar con otros tipos. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf index d7f738a55f661c..651ab8b303719a 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.fr.xlf @@ -154,12 +154,12 @@ The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. - The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + L’attribut de validation {0} doit uniquement être appliqué aux propriétés de type chaîne, tableau ou ICollection. Son utilisation avec le type {1} peut entraîner des échecs d’exécution. The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. - The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + L’attribut de validation s’applique uniquement aux propriétés de type chaîne, tableau ou ICollection ; il ne peut pas être utilisé avec d’autres types. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf index d3903a95f055cf..575f60469e48dc 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.it.xlf @@ -154,12 +154,12 @@ The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. - The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + L'attributo {0} di convalida deve essere applicato solo alle proprietà di tipo stringa, matrice o ICollection. L'uso con il tipo {1} potrebbe causare errori di runtime. The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. - The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + L'attributo di convalida è applicabile solo alle proprietà di tipo stringa, matrice o ICollection; non può essere usato con altri tipi. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf index 2afc63bf19fda0..8251ac27c6da15 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ja.xlf @@ -154,12 +154,12 @@ The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. - The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + 検証属性 {0} は、型文字列、配列、または ICollection のプロパティにしか適用できません。型 {1} と共に使用すると、ランタイム エラーが発生する可能性があります。 The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. - The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + 検証属性は、型文字列、配列、または ICollection のプロパティにのみ適用でき、他の型では使用できません。 diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf index 6bb342f5931541..4c8ce2865d1070 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ko.xlf @@ -154,12 +154,12 @@ The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. - The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + 유효성 검사 특성 {0}은(는) 문자열, 배열 또는 ICollection 형식의 속성에만 적용해야 합니다. {1} 형식과 함께 사용하면 런타임 오류가 발생할 수 있습니다. The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. - The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + 유효성 검사 특성은 문자열, 배열 또는 ICollection 형식의 속성에만 적용할 수 있습니다. 다른 형식과 함께 사용할 수 없습니다. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf index 1262d4d0852b49..e07e568d131874 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pl.xlf @@ -154,12 +154,12 @@ The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. - The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + Atrybut sprawdzania poprawności {0} powinien być stosowany tylko do właściwości typu ciąg, tablica lub ICollection. Użycie go z typem {1} może prowadzić do błędów środowiska uruchomieniowego. The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. - The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + Atrybut sprawdzania poprawności ma zastosowanie tylko do właściwości typu ciąg, tablica lub ICollection; nie można go używać z innymi typami. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf index ced617baa9556c..d422309a40995b 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.pt-BR.xlf @@ -154,12 +154,12 @@ The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. - The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + O atributo de validação {0} deve ser aplicado somente às propriedades do tipo cadeia de caracteres, matriz ou ICollection. Usá-lo com o tipo {1} pode levar a falhas de runtime. The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. - The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + O atributo de validação só é aplicável às propriedades do tipo cadeia de caracteres, matriz ou ICollection; não pode ser usado com outros tipos. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf index cf3c21772acf20..bd3a0be55eb270 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.ru.xlf @@ -154,12 +154,12 @@ The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. - The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + Атрибут проверки {0} следует применять только к свойствам строки типа, массива или ICollection. Использование его с типом {1} может привести к сбоям во время выполнения. The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. - The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + Атрибут проверки применим только к свойствам строки типа, массива или ICollection; его нельзя использовать с другими типами. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf index b9545e2def86bc..e478a77cd3c238 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.tr.xlf @@ -154,12 +154,12 @@ The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. - The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + Doğrulama özniteliği {0} yalnızca string, dizi veya ICollection türündeki özelliklere uygulanmalıdır. {1} türüyle kullanılması çalışma zamanı hatalarına neden olabilir. The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. - The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + Doğrulama özniteliği yalnızca string, dizi veya ICollection türündeki özelliklere uygulanabilir; diğer türlerle kullanılamaz. diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf index a3b9657f861b08..9997092e3be6f3 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/Microsoft.Extensions.Options/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -154,12 +154,12 @@ The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. - The validation attribute {0} should only be applied to properties of type string, array, or ICollection. Using it with the type {1} could lead to runtime failures. + 驗證屬性 {0} 只能套用至類型字串、陣列或 ICollection 的屬性。搭配 {1} 類型使用可能會導致執行階段失敗。 The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. - The validation attribute is only applicable to properties of type string, array, or ICollection; it cannot be used with other types. + 驗證屬性只適用於類型字串、陣列或 ICollection 的屬性;無法與其他類型搭配使用。 From 324f912f4d01a43009ea79c0d43434860b51b450 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Mon, 16 Oct 2023 11:30:50 -0700 Subject: [PATCH 376/783] Workaround for https://github.com/dotnet/runtime/issues/93442 (#93528) --- src/coreclr/inc/safemath.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/coreclr/inc/safemath.h b/src/coreclr/inc/safemath.h index 3f6d5c5716bdb4..fcd51af3de8cb0 100644 --- a/src/coreclr/inc/safemath.h +++ b/src/coreclr/inc/safemath.h @@ -688,6 +688,10 @@ template class ClrSafeInt INDEBUG( mutable bool m_checkedOverflow; ) }; +#if defined(_MSC_VER) && defined(HOST_ARM64) // Workaround for https://github.com/dotnet/runtime/issues/93442 +#pragma optimize("", off) +#endif + template <> inline bool ClrSafeInt::multiply(int64_t lhs, int64_t rhs, int64_t &result) { @@ -874,6 +878,10 @@ inline bool ClrSafeInt::multiply(uint8_t lhs, uint8_t rhs, uint8_t &res return true; } +#if defined(_MSC_VER) && defined(HOST_ARM64) // Workaround for https://github.com/dotnet/runtime/issues/93442 +#pragma optimize("", on) +#endif + // Allows creation of a ClrSafeInt corresponding to the type of the argument. template ClrSafeInt AsClrSafeInt(T t) From 5a43d62dca5370bc6f683c5fb4102f8f1ef24ada Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 13:02:05 -0700 Subject: [PATCH 377/783] TcpReceiveSendGetsCanceledByDispose: update test for change in Linux kernel. (#93502) Co-authored-by: Tom Deseyn --- .../tests/FunctionalTests/SendReceive/SendReceive.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendReceive/SendReceive.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendReceive/SendReceive.cs index d5fbf0b1c83981..32a7bdcfbb6acf 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendReceive/SendReceive.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendReceive/SendReceive.cs @@ -1019,11 +1019,12 @@ public async Task TcpReceiveSendGetsCanceledByDispose(bool receiveOrSend, bool i return; } - // RHEL7 kernel has a bug preventing close(AF_UNKNOWN) to succeed with IPv6 sockets. - // In this case Dispose will trigger a graceful shutdown, which means that receive will succeed on socket2. - // This bug is fixed in kernel 3.10.0-1160.25+. - // TODO: Remove this, once CI machines are updated to a newer kernel. - bool mayShutdownGraceful = UsesSync && PlatformDetection.IsRedHatFamily7 && receiveOrSend && (ipv6Server || dualModeClient); + // .NET uses connect(AF_UNSPEC) to abort on-going operations on Linux. + // Linux 6.4+ introduced a change (4faeee0cf8a5d88d63cdbc3bab124fb0e6aed08c) which disallows + // this operation while operations are on-going. + // When the connect fails, .NET falls back to use shutdown(SHUT_RDWR). + // This causes the receive on socket2 to succeed instead of failing with ConnectionReset. + bool mayShutdownGraceful = UsesSync && PlatformDetection.IsLinux && receiveOrSend; // We try this a couple of times to deal with a timing race: if the Dispose happens // before the operation is started, the peer won't see a ConnectionReset SocketException and we won't From 567f81e719091bd1ba3c751d49bacee2c6a45e66 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 13:05:12 -0700 Subject: [PATCH 378/783] Mention Frozen.* types in PACKAGE.md for System.Collections.Immutable (#93561) Co-authored-by: Nikita Balabaev --- src/libraries/System.Collections.Immutable/src/PACKAGE.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Collections.Immutable/src/PACKAGE.md b/src/libraries/System.Collections.Immutable/src/PACKAGE.md index 202fb6d0137833..0ca0b161aa448d 100644 --- a/src/libraries/System.Collections.Immutable/src/PACKAGE.md +++ b/src/libraries/System.Collections.Immutable/src/PACKAGE.md @@ -53,6 +53,10 @@ The main types provided by this library are: * `System.Collections.Immutable.ImmutableSortedSet` * `System.Collections.Immutable.ImmutableStack` * `System.Collections.Immutable.ImmutableStack` +* `System.Collections.Frozen.FrozenDictionary` +* `System.Collections.Frozen.FrozenDictionary` +* `System.Collections.Frozen.FrozenSet` +* `System.Collections.Frozen.FrozenSet` ## Additional Documentation @@ -65,4 +69,4 @@ The main types provided by this library are: -System.Collections.Immutable is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +System.Collections.Immutable is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 9e5c7414bcec1310dd13672118374268bc32a23b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 11:29:11 -0700 Subject: [PATCH 379/783] [release/8.0] [hot reload][debugger] Resolve field types before use (#93559) * adding test case failing * fixup test - expect null value, not empty string * [debugger] resolve field types before use * don't shadow names --------- Co-authored-by: Thays Grazia Co-authored-by: Aleksey Kliger --- src/mono/mono/component/debugger-agent.c | 49 +++++++++++++++++++ .../DebuggerTestSuite/HotReloadTests.cs | 3 +- .../MethodBody2_v2.cs | 1 + 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index a210242c1eb691..9a6906f6e272ef 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -5258,6 +5258,13 @@ buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain, nfields = 0; iter = NULL; while ((f = mono_class_get_fields_internal (klass, &iter))) { + if (G_UNLIKELY (!f->type)) { + ERROR_DECL(error); + mono_field_resolve_type (f, error); + mono_error_cleanup (error); + if (!f->type) + continue; + } if (f->type->attrs & FIELD_ATTRIBUTE_STATIC) continue; if (mono_field_is_deleted (f)) @@ -5275,6 +5282,13 @@ buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain, iter = NULL; while ((f = mono_class_get_fields_internal (klass, &iter))) { + if (G_UNLIKELY (!f->type)) { + ERROR_DECL(error); + mono_field_resolve_type (f, error); + mono_error_cleanup (error); + if (!f->type) + continue; + } if (f->type->attrs & FIELD_ATTRIBUTE_STATIC) continue; if (mono_field_is_deleted (f)) @@ -5375,6 +5389,13 @@ decode_vtype (MonoType *t, MonoDomain *domain, gpointer void_addr, gpointer void nfields = decode_int (buf, &buf, limit); while ((f = mono_class_get_fields_internal (klass, &iter))) { + if (G_UNLIKELY (!f->type)) { + ERROR_DECL(error); + mono_field_resolve_type (f, error); + mono_error_cleanup (error); + if (!f->type) + continue; + } if (f->type->attrs & FIELD_ATTRIBUTE_STATIC) continue; if (mono_field_is_deleted (f)) @@ -5476,6 +5497,13 @@ decode_vtype_compute_size (MonoType *t, MonoDomain *domain, gpointer void_buf, g nfields = decode_int (buf, &buf, limit); while ((f = mono_class_get_fields_internal (klass, &iter))) { + if (G_UNLIKELY (!f->type)) { + ERROR_DECL(error); + mono_field_resolve_type (f, error); + mono_error_cleanup (error); + if (!f->type) + continue; + } if (f->type->attrs & FIELD_ATTRIBUTE_STATIC) continue; if (mono_field_is_deleted (f)) @@ -8481,6 +8509,13 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint buffer_add_int (buf, nfields); while ((f = mono_class_get_fields_internal (klass, &iter))) { + if (G_UNLIKELY (!f->type)) { + ERROR_DECL(field_error); + mono_field_resolve_type (f, field_error); + mono_error_cleanup (field_error); + if (!f->type) + continue; + } buffer_add_fieldid (buf, domain, f); buffer_add_string (buf, f->name); buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (f->type)); @@ -8861,6 +8896,13 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint int nfields = 0; gpointer iter = NULL; while ((f = mono_class_get_fields_internal (klass, &iter))) { + if (G_UNLIKELY (!f->type)) { + ERROR_DECL(field_error); + mono_field_resolve_type (f, field_error); + mono_error_cleanup (field_error); + if (!f->type) + continue; + } if (f->type->attrs & FIELD_ATTRIBUTE_STATIC) continue; if (mono_field_is_deleted (f)) @@ -8871,6 +8913,13 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint iter = NULL; while ((f = mono_class_get_fields_internal (klass, &iter))) { + if (G_UNLIKELY (!f->type)) { + ERROR_DECL(field_error); + mono_field_resolve_type (f, field_error); + mono_error_cleanup (field_error); + if (!f->type) + continue; + } if (f->type->attrs & FIELD_ATTRIBUTE_STATIC) continue; if (mono_field_is_deleted (f)) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/HotReloadTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/HotReloadTests.cs index bfeb9ec9b4d5ea..ade5c6adc8bbd5 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/HotReloadTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/HotReloadTests.cs @@ -596,7 +596,8 @@ await SendCommandAndCheck (JObject.FromObject(new { }), "Debugger.resume", scrip await CheckProps (c, new { Field1 = TNumber(123), Field2 = TString("spqr"), - }, "c", num_fields: 2); + Field3 = TString(null), + }, "c", num_fields: 3); }); } diff --git a/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly3/MethodBody2_v2.cs b/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly3/MethodBody2_v2.cs index 379adbe266908e..cbde71233f4b45 100644 --- a/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly3/MethodBody2_v2.cs +++ b/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly3/MethodBody2_v2.cs @@ -22,6 +22,7 @@ public C() } public double Field1; public string Field2; + public string Field3; } } From 5a61c77fbcd33080bb9fe7b4d1209192c5245905 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 12:09:03 -0700 Subject: [PATCH 380/783] [release/8.0] Update dependencies from dnceng/internal/dotnet-optimization (#93549) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231015.2 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23512.4 -> To Version 1.0.0-prerelease.23515.2 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231015.2 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23512.4 -> To Version 1.0.0-prerelease.23515.2 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e3156fbc00396b..6c23f85837740b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -334,21 +334,21 @@ https://github.com/dotnet/arcade 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 17ea99c28d05ae088ff372f517e63f91c7b715ae + 0e20c85562e8c4615c2a3a9e28371a34d9d0a398 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 17ea99c28d05ae088ff372f517e63f91c7b715ae + 0e20c85562e8c4615c2a3a9e28371a34d9d0a398 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 17ea99c28d05ae088ff372f517e63f91c7b715ae + 0e20c85562e8c4615c2a3a9e28371a34d9d0a398 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 17ea99c28d05ae088ff372f517e63f91c7b715ae + 0e20c85562e8c4615c2a3a9e28371a34d9d0a398 https://github.com/dotnet/hotreload-utils @@ -384,13 +384,13 @@ d10b02ae5cc670609d920a672985ed4456bdd6b6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 17ea99c28d05ae088ff372f517e63f91c7b715ae + 0e20c85562e8c4615c2a3a9e28371a34d9d0a398 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 17ea99c28d05ae088ff372f517e63f91c7b715ae + 0e20c85562e8c4615c2a3a9e28371a34d9d0a398 diff --git a/eng/Versions.props b/eng/Versions.props index 7078c2d2f01eb5..39b67f83490a20 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23512.4 - 1.0.0-prerelease.23512.4 - 1.0.0-prerelease.23512.4 - 1.0.0-prerelease.23512.4 - 1.0.0-prerelease.23512.4 - 1.0.0-prerelease.23512.4 + 1.0.0-prerelease.23515.2 + 1.0.0-prerelease.23515.2 + 1.0.0-prerelease.23515.2 + 1.0.0-prerelease.23515.2 + 1.0.0-prerelease.23515.2 + 1.0.0-prerelease.23515.2 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From fbd7b654ce41c6d76510f948e94f9eb9a904244e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 14:48:56 -0700 Subject: [PATCH 381/783] [release/8.0] Update dependencies from 7 repositories (#93282) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/dotnet/cecil build 20231009.2 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23502.1 -> To Version 0.11.4-alpha.23509.2 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20231009.1 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23502.1 -> To Version 8.0.0-alpha.0.23509.1 * Update dependencies from https://github.com/dotnet/icu build 20231009.2 Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rc.2.23468.2 -> To Version 8.0.0-rtm.23509.2 * Update dependencies from https://github.com/dotnet/cecil build 20231009.2 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23502.1 -> To Version 0.11.4-alpha.23509.2 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20231009.1 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23502.1 -> To Version 8.0.0-alpha.0.23509.1 * Update dependencies from https://github.com/dotnet/icu build 20231009.2 Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rc.2.23468.2 -> To Version 8.0.0-rtm.23509.2 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20231010.2 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23471.1 -> To Version 8.0.0-alpha.1.23510.2 * Update dependencies from https://github.com/dotnet/emsdk build 20231011.2 Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rtm.23504.4 -> To Version 8.0.0-rtm.23511.2 * Update dependencies from https://github.com/dotnet/emsdk build 20231011.3 Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rtm.23504.4 -> To Version 8.0.0-rtm.23511.3 * Update dependencies from https://github.com/dotnet/cecil build 20231009.2 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23502.1 -> To Version 0.11.4-alpha.23509.2 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20231009.1 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23502.1 -> To Version 8.0.0-alpha.0.23509.1 * Update dependencies from https://github.com/dotnet/icu build 20231011.1 Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rc.2.23468.2 -> To Version 8.0.0-rtm.23511.1 * Update dependencies from https://github.com/dotnet/arcade build 20231005.1 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23477.4 -> To Version 8.0.0-beta.23505.1 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20231010.2 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23471.1 -> To Version 8.0.0-alpha.1.23510.2 * Update dependencies from https://github.com/dotnet/cecil build 20231009.2 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23502.1 -> To Version 0.11.4-alpha.23509.2 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20231009.1 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23502.1 -> To Version 8.0.0-alpha.0.23509.1 * Update dependencies from https://github.com/dotnet/icu build 20231011.1 Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rc.2.23468.2 -> To Version 8.0.0-rtm.23511.1 * Update dependencies from https://github.com/dotnet/arcade build 20231005.1 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23477.4 -> To Version 8.0.0-beta.23505.1 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20231010.2 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23471.1 -> To Version 8.0.0-alpha.1.23510.2 * Update dependencies from https://github.com/dotnet/cecil build 20231009.2 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23502.1 -> To Version 0.11.4-alpha.23509.2 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20231009.1 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23502.1 -> To Version 8.0.0-alpha.0.23509.1 * Update dependencies from https://github.com/dotnet/icu build 20231011.1 Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rc.2.23468.2 -> To Version 8.0.0-rtm.23511.1 * Update dependencies from https://github.com/dotnet/arcade build 20231005.1 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23477.4 -> To Version 8.0.0-beta.23505.1 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20231010.2 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23471.1 -> To Version 8.0.0-alpha.1.23510.2 * Update dependencies from https://github.com/dotnet/cecil build 20231009.2 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23502.1 -> To Version 0.11.4-alpha.23509.2 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20231009.1 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23502.1 -> To Version 8.0.0-alpha.0.23509.1 * Update dependencies from https://github.com/dotnet/icu build 20231011.1 Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rc.2.23468.2 -> To Version 8.0.0-rtm.23511.1 * Update dependencies from https://github.com/dotnet/arcade build 20231005.1 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23477.4 -> To Version 8.0.0-beta.23505.1 * Update dependencies from https://github.com/dotnet/cecil build 20231009.2 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23502.1 -> To Version 0.11.4-alpha.23509.2 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20231009.1 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23502.1 -> To Version 8.0.0-alpha.0.23509.1 * Update dependencies from https://github.com/dotnet/icu build 20231011.1 Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rc.2.23468.2 -> To Version 8.0.0-rtm.23511.1 * Update dependencies from https://github.com/dotnet/arcade build 20231005.1 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23477.4 -> To Version 8.0.0-beta.23505.1 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20231010.2 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23471.1 -> To Version 8.0.0-alpha.1.23510.2 * Update dependencies from https://github.com/dotnet/cecil build 20231009.2 Microsoft.DotNet.Cecil From Version 0.11.4-alpha.23502.1 -> To Version 0.11.4-alpha.23509.2 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20231009.1 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23502.1 -> To Version 8.0.0-alpha.0.23509.1 * Update dependencies from https://github.com/dotnet/icu build 20231011.1 Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rc.2.23468.2 -> To Version 8.0.0-rtm.23511.1 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231016.2 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23472.1 -> To Version 3.11.0-beta1.23516.2 * Update dependencies from https://github.com/dotnet/arcade build 20231005.1 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23477.4 -> To Version 8.0.0-beta.23505.1 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20231016.4 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23471.1 -> To Version 8.0.0-alpha.1.23516.4 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231016.2 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23472.1 -> To Version 3.11.0-beta1.23516.2 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- eng/Version.Details.xml | 100 ++++++++++++++++++++-------------------- eng/Versions.props | 42 ++++++++--------- eng/common/sdk-task.ps1 | 2 +- eng/common/tools.ps1 | 6 +-- global.json | 6 +-- 5 files changed, 78 insertions(+), 78 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6c23f85837740b..522c6f2c4704db 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/icu - ac7697a28716e68e986d3db72cbc10324f8961fe + feea7b8dcee39fd35ee6c415197e47d19102bb0b https://github.com/dotnet/msquic @@ -85,19 +85,19 @@ 02fe27cd6a9b001c8feb7938e6ef4b3799745759b - + https://github.com/dotnet/cecil - 64a8874f3c485657e732ca56a5f24e2095740103 + 45dd3a73dd5b64b010c4251303b3664bb30df029 - + https://github.com/dotnet/emsdk - 0c28b5cfe0f9173000450a3edc808dc8c2b9286e + 1b7f3a6560f6fb5f32b2758603c0376037f555ea - + https://github.com/dotnet/source-build-reference-packages - 7b55da982fc6e71c1776c4de89111aee0eecb45a + b4fa7f2e1e65ef49881be2ab2df27624280a8c55 @@ -107,9 +107,9 @@ - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 @@ -117,69 +117,69 @@ 73f0850939d96131c28cf6ea6ee5aacb4da0083a - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 https://github.com/dotnet/runtime-assets @@ -330,9 +330,9 @@ https://github.com/dotnet/xharness 480b9159eb7e69b182a87581d5a336e97e0b6dae - + https://github.com/dotnet/arcade - 60a2e897fb13b2042e64d3be6a4f9d43f39b6f07 + e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization @@ -350,9 +350,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 0e20c85562e8c4615c2a3a9e28371a34d9d0a398 - + https://github.com/dotnet/hotreload-utils - 94979ba9c2904e39ddb9aa255a288caacd6ce166 + 0808f735fcb35276120b2e1221d6c3395d5543d6 https://github.com/dotnet/runtime-assets @@ -371,13 +371,13 @@ https://github.com/dotnet/roslyn d49b29ecbf9bd72fe6023ad1b8aad9a8db7e7c3a - + https://github.com/dotnet/roslyn-analyzers - 4a7701fd72094614897b33e4cb1d9640c221d862 + 4ff28092cdb2006c30869fb35b2fd6b7b11382b1 - + https://github.com/dotnet/roslyn-analyzers - 4a7701fd72094614897b33e4cb1d9640c221d862 + 4ff28092cdb2006c30869fb35b2fd6b7b11382b1 https://github.com/dotnet/sdk diff --git a/eng/Versions.props b/eng/Versions.props index 39b67f83490a20..ee654173fa1667 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -36,8 +36,8 @@ - 3.11.0-beta1.23472.1 - 8.0.0-preview.23472.1 + 3.11.0-beta1.23516.2 + 8.0.0-preview.23516.2 8.0.100-preview.7.23329.3 - 8.0.0-beta.23477.4 - 8.0.0-beta.23477.4 - 8.0.0-beta.23477.4 - 8.0.0-beta.23477.4 - 8.0.0-beta.23477.4 - 2.5.1-beta.23477.4 - 8.0.0-beta.23477.4 - 8.0.0-beta.23477.4 - 8.0.0-beta.23477.4 - 8.0.0-beta.23477.4 - 8.0.0-beta.23477.4 - 8.0.0-beta.23477.4 - 8.0.0-beta.23477.4 - 8.0.0-beta.23477.4 - 8.0.0-beta.23477.4 + 8.0.0-beta.23505.1 + 8.0.0-beta.23505.1 + 8.0.0-beta.23505.1 + 8.0.0-beta.23505.1 + 8.0.0-beta.23505.1 + 2.5.1-beta.23505.1 + 8.0.0-beta.23505.1 + 8.0.0-beta.23505.1 + 8.0.0-beta.23505.1 + 8.0.0-beta.23505.1 + 8.0.0-beta.23505.1 + 8.0.0-beta.23505.1 + 8.0.0-beta.23505.1 + 8.0.0-beta.23505.1 + 8.0.0-beta.23505.1 6.0.0-preview.1.102 @@ -186,7 +186,7 @@ 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 - 8.0.0-alpha.0.23502.1 + 8.0.0-alpha.0.23509.1 2.4.2 1.0.0 2.4.5 @@ -213,11 +213,11 @@ 8.0.0-rc.1.23406.6 - 0.11.4-alpha.23502.1 + 0.11.4-alpha.23509.2 8.0.0-rc.1.23406.6 - 8.0.0-rc.2.23468.2 + 8.0.0-rtm.23511.1 2.2.2 8.0.0-alpha.1.23468.1 @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.0-rtm.23504.4 + 8.0.0-rtm.23511.3 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1 index ff5342eb5c1947..91f8196cc808db 100644 --- a/eng/common/sdk-task.ps1 +++ b/eng/common/sdk-task.ps1 @@ -64,7 +64,7 @@ try { $GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty } if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) { - $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.7.2" -MemberType NoteProperty + $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.7.2-1" -MemberType NoteProperty } if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") { $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 19e9fa66239be6..84cfe7cd9cb463 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -379,13 +379,13 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = } # Minimum VS version to require. - $vsMinVersionReqdStr = '17.6' + $vsMinVersionReqdStr = '17.7' $vsMinVersionReqd = [Version]::new($vsMinVersionReqdStr) # If the version of msbuild is going to be xcopied, # use this version. Version matches a package here: - # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/RoslynTools.MSBuild/versions/17.7.2 - $defaultXCopyMSBuildVersion = '17.7.2' + # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/RoslynTools.MSBuild/versions/17.7.2-1 + $defaultXCopyMSBuildVersion = '17.7.2-1' if (!$vsRequirements) { if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') { diff --git a/global.json b/global.json index 38d6bdc6407177..b3fdf36ccb3d25 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.100-rc.1.23455.8" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23477.4", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23477.4", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23477.4", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23505.1", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23505.1", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23505.1", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From 6f7af556d2761b0c93299cb88c61e4b747d6176a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 17:34:16 -0600 Subject: [PATCH 382/783] Update dependencies from https://github.com/dotnet/roslyn build 20231017.7 (#93628) Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23510.8 -> To Version 4.8.0-3.23517.7 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 522c6f2c4704db..94201ffdba61fa 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - d49b29ecbf9bd72fe6023ad1b8aad9a8db7e7c3a + 0cf3dfae65b73d0332c77b2b4b06036b018b60a2 - + https://github.com/dotnet/roslyn - d49b29ecbf9bd72fe6023ad1b8aad9a8db7e7c3a + 0cf3dfae65b73d0332c77b2b4b06036b018b60a2 - + https://github.com/dotnet/roslyn - d49b29ecbf9bd72fe6023ad1b8aad9a8db7e7c3a + 0cf3dfae65b73d0332c77b2b4b06036b018b60a2 https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index ee654173fa1667..cf634b3b5112d1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -44,9 +44,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23510.8 - 4.8.0-3.23510.8 - 4.8.0-3.23510.8 + 4.8.0-3.23517.7 + 4.8.0-3.23517.7 + 4.8.0-3.23517.7 - 4.8.0-3.23517.7 - 4.8.0-3.23517.7 - 4.8.0-3.23517.7 + 4.8.0-3.23518.2 + 4.8.0-3.23518.2 + 4.8.0-3.23518.2 From c6e7ebdcb1b99c72990ae9f5ff95a75d5bb0f3ce Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:55:59 -0700 Subject: [PATCH 389/783] Update dependencies from https://github.com/dotnet/roslyn build 20231018.7 (#93700) Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23518.2 -> To Version 4.8.0-3.23518.7 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index bea4b99e52d3f4..49823b9b22dab3 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -358,18 +358,18 @@ https://github.com/dotnet/runtime-assets 99168dcff56809205e7ef8530d1256f3a07fab1f - + https://github.com/dotnet/roslyn - 9862861f63e972615f315ddbfa368f9ee84f1189 + 12b11685a551e0a6a203dcecb584f610f4df1157 - + https://github.com/dotnet/roslyn - 9862861f63e972615f315ddbfa368f9ee84f1189 + 12b11685a551e0a6a203dcecb584f610f4df1157 - + https://github.com/dotnet/roslyn - 9862861f63e972615f315ddbfa368f9ee84f1189 + 12b11685a551e0a6a203dcecb584f610f4df1157 https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index 53e7dca23df9e1..c889bc72c835a6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -44,9 +44,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23518.2 - 4.8.0-3.23518.2 - 4.8.0-3.23518.2 + 4.8.0-3.23518.7 + 4.8.0-3.23518.7 + 4.8.0-3.23518.7 + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Bcl.Cryptography is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md new file mode 100644 index 00000000000000..651e3c04c98405 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Caching.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md new file mode 100644 index 00000000000000..efb7ca7c9133cc --- /dev/null +++ b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.FileProviders.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md new file mode 100644 index 00000000000000..bf3378a56e63dd --- /dev/null +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.FileProviders.Physical is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md new file mode 100644 index 00000000000000..9e3801f758a082 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Addtional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.FileSystemGlobbing is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md new file mode 100644 index 00000000000000..7bab863fa95cc9 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Logging.TraceSource is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md new file mode 100644 index 00000000000000..3bf3280ad4cf1b --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +Microsoft.Extensions.Options.DataAnnotations is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md b/src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md new file mode 100644 index 00000000000000..61bbd897786b2c --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +System.DirectoryServices.Protocols is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Formats.Cbor/src/PACKAGE.md b/src/libraries/System.Formats.Cbor/src/PACKAGE.md new file mode 100644 index 00000000000000..96474955ed1b16 --- /dev/null +++ b/src/libraries/System.Formats.Cbor/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Addtional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +System.Formats.Cbor is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.IO.Hashing/src/PACKAGE.md b/src/libraries/System.IO.Hashing/src/PACKAGE.md new file mode 100644 index 00000000000000..5bb2b571759074 --- /dev/null +++ b/src/libraries/System.IO.Hashing/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +System.IO.Hashing is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Memory.Data/src/PACKAGE.md b/src/libraries/System.Memory.Data/src/PACKAGE.md new file mode 100644 index 00000000000000..9c4f30806907e1 --- /dev/null +++ b/src/libraries/System.Memory.Data/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +System.Memory.Data is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md b/src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md new file mode 100644 index 00000000000000..09e76336690163 --- /dev/null +++ b/src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md @@ -0,0 +1,44 @@ +## About + + + + + +## Key Features + + + +* +* +* + +## How to Use + + + +## Main Types + + + +The main types provided by this library are: + +* `` +* `` +* `` + +## Additional Documentation + + + +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) + +## Related Packages + + + +## Feedback & Contributing + + + +System.Security.Cryptography.ProtectedData is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file From 863d3813bb08c29c49229561c54c6529ad82a05a Mon Sep 17 00:00:00 2001 From: Illia Larka Date: Tue, 3 Oct 2023 23:01:12 +0200 Subject: [PATCH 395/783] Microsoft.Extensions.Logging.TraceSource package readme update (#92962) Fix #92228 --- .../src/PACKAGE.md | 49 +++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md index 7bab863fa95cc9..90c9a560856a52 100644 --- a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md @@ -2,41 +2,72 @@ - +Implements a trace logger provider for the .NET logging infrastructre facilitating enhanced logging capabilities and trace-level diagnostics in application by writing messages to a trace listener using System.Diagnostic.TraceSource. ## Key Features -* -* -* +* Seamless integration with .NET logging infrastructure. +* Fine-grained control over trace messages using SourceSwitch. +* A set of builder methods to configure logging infrastructure. ## How to Use +The Microsoft.Extensions.Logging.TraceSource library provides extension methods to the logger factory and the logger builder to add a trace source with trace listeners. + +```csharp +using System.Diagnostics; +using Microsoft.Extensions.Logging; + +using var consoleTraceListener = new ConsoleTraceListener(); +using var textWriterTraceListener = new TextWriterTraceListener("/traces.txt"); +using var loggerFactory = LoggerFactory.Create(builder => +{ + builder + .AddTraceSource(new SourceSwitch("Something") { Level = SourceLevels.All }, consoleTraceListener) + .AddTraceSource(new SourceSwitch("HouseKeeping") { Level = SourceLevels.All }, textWriterTraceListener); +}); + +var logger = loggerFactory.CreateLogger(); + +logger.LogInformation("Information message."); +// Program Information: 0 : Information message. +logger.LogWarning("Warning message."); +// Program Warning: 0 : Warning message. + +var traceSource = new TraceSource("HouseKeeping", SourceLevels.All); +traceSource.Listeners.Add(consoleTraceListener); +traceSource.Listeners.Add(textWriterTraceListener); + +traceSource.TraceEvent(TraceEventType.Error, 0, "Error message."); +//HouseKeeping Error: 0 : Error message. +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `Microsoft.Extensions.Logging.TraceSource.TraceSourceLoggerProvider` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.tracesource) ## Related Packages +* Abstractions for dependency injection: [Microsoft.Extensions.DependencyInjection.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection.Abstractions/) +* Defult implementation of logging infrastructure: [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging/) +* Abstractions for logging: [Microsoft.Extensions.Logging.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Abstractions/) + ## Feedback & Contributing From 88d5911642f4c428fe25642971f70f588601de2c Mon Sep 17 00:00:00 2001 From: Illia Larka Date: Wed, 4 Oct 2023 11:46:03 +0200 Subject: [PATCH 396/783] Fix PACKAGE.md typo (#92989) Typo in word 'Defult' fixed to 'Default'. Fix #92228 --- .../Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md index 90c9a560856a52..25abc578ba6d36 100644 --- a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md @@ -65,7 +65,7 @@ The main types provided by this library are: * Abstractions for dependency injection: [Microsoft.Extensions.DependencyInjection.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection.Abstractions/) -* Defult implementation of logging infrastructure: [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging/) +* Default implementation of logging infrastructure: [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging/) * Abstractions for logging: [Microsoft.Extensions.Logging.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Abstractions/) ## Feedback & Contributing From 93f0952843501aaf9e347b51a96eb3d7252f8697 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 4 Oct 2023 12:26:19 -0400 Subject: [PATCH 397/783] Update Microsoft.Bcl.Cryptography/src/PACKAGE.md --- .../Microsoft.Bcl.Cryptography/src/PACKAGE.md | 45 +++++++++---------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md index 5a3a8c037bca45..4346252b24386b 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md @@ -1,44 +1,39 @@ ## About - - - +This library provides some cryptographic types and functionality for .NET Standard and .NET Framework. This library is not necessary nor recommended when targeting versions of .NET that include the relevant support. ## Key Features - - -* -* -* +* Enables the use of some cryptographic functionality on older .NET platforms. ## How to Use - +This package should only be used by platforms where the desired functionality is not built-in. -## Main Types +```C# +using System.Security.Cryptography; + +internal static class Program +{ + private static void Main() + { + byte[] key = LoadKey(); + SP800108HmacCounterKdf kbkdf = new(key, HashAlgorithmName.SHA256); + byte[] derivedKey = kbkdf.DeriveKey("label"u8, "context"u8, derivedKeyLengthInBytes: 32); + } +} +``` - +## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `System.Security.Cryptography.SP800108HmacCounterKdf` ## Additional Documentation - - -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/System.Security.Cryptography) ## Feedback & Contributing - - -Microsoft.Bcl.Cryptography is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Bcl.Cryptography is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 998e11854ea9477fc91abc22a65b8fe0c84c4867 Mon Sep 17 00:00:00 2001 From: Illia Larka Date: Mon, 9 Oct 2023 10:56:12 +0200 Subject: [PATCH 398/783] System.Formats.Cbor package's readme (#93021) * Remove conceptual docummentation item Removed since is not applicable * List types library provides Add list of types which library provides. Listed public types, means exposed types. * Add description and usage examples Add library description. Add few code examples showing basic functionality for CBOR wirter and reader types. * Add related packages section Since different targets have different dependencies so I have divided for each section. * Improve short description Add 'format' word after abbreviation to have an object in sentence. * Remove related packages section Since there are no related packages. * Improve array reading/writing example --- .../System.Formats.Cbor/src/PACKAGE.md | 77 +++++++++++++++---- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Formats.Cbor/src/PACKAGE.md b/src/libraries/System.Formats.Cbor/src/PACKAGE.md index 96474955ed1b16..ff26f0debbdc0a 100644 --- a/src/libraries/System.Formats.Cbor/src/PACKAGE.md +++ b/src/libraries/System.Formats.Cbor/src/PACKAGE.md @@ -2,40 +2,91 @@ +Provides support for reading and writing values in Concise Binary Object Representation (CBOR) format, as originally defined in [IETF RFC 7049](https://www.ietf.org/rfc/rfc7049.html). ## Key Features -* -* -* +* Reader and writer types for the CBOR format. +* Built-in support for different CBOR conformance modes. ## How to Use +Write and read primitives: + +```csharp +using System.Formats.Cbor; + +var cborWriter = new CborWriter(CborConformanceMode.Lax); +cborWriter.WriteTextString("Hello World"); + +var cborReader = new CborReader(cborWriter.Encode(), CborConformanceMode.Lax); +Console.WriteLine(cborReader.ReadTextString()); +// Hello World +``` + +Write and read an array: + +```csharp +var cborWriter = new CborWriter(CborConformanceMode.Lax); +cborWriter.WriteStartArray(5); +for (var index = 0; index < 5; index++) +{ + cborWriter.WriteInt32(index); +} +cborWriter.WriteEndArray(); + +var cborReader = new CborReader(cborWriter.Encode(), CborConformanceMode.Lax); +var arrayLength = cborReader.ReadStartArray(); +for (var index = 0; index < arrayLength; index++) +{ + Console.Write(cborReader.ReadInt32()); +} +// 01234 +cborReader.ReadEndArray(); +``` + +Inspect writer and reader state: + +```csharp +var cborWriter = new CborWriter(CborConformanceMode.Lax); +cborWriter.WriteTextString("SomeArray"); +Console.WriteLine(cborWriter.BytesWritten); +// 10 +Console.WriteLine(cborWriter.IsWriteCompleted); +// True + +var cborReader = new CborReader(cborWriter.Encode(), CborConformanceMode.Lax); +Console.WriteLine(cborReader.BytesRemaining); +// 10 +Console.WriteLine(cborReader.ReadTextString()); +// SomeArray +Console.WriteLine(cborReader.BytesRemaining); +// 0 +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `System.Formats.Cbor.CborReader` +* `System.Formats.Cbor.CborWriter` +* `System.Formats.Cbor.CborReaderState` +* `System.Formats.Cbor.CborConformanceMode` +* `System.Formats.Cbor.CborContentException` +* `System.Formats.Cbor.CborTag` -## Addtional Documentation +## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.formats.cbor) ## Feedback & Contributing From b77fd65b3ae1f20595d2ab1677ab2e16ed185301 Mon Sep 17 00:00:00 2001 From: Logan Payton <18620874+EnsignPayton@users.noreply.github.com> Date: Mon, 9 Oct 2023 03:59:47 -0500 Subject: [PATCH 399/783] Microsoft.Extensions.FileSystemGlobbing PACKAGE.md (#93123) * Microsoft.Extensions.FileSystemGlobbing PACKAGE.md Fill out details for `Microsoft.Extensions.FileSystemGlobbing` NuGet package readme See https://github.com/dotnet/runtime/pull/92228 * Update src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md * Update src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md --------- Co-authored-by: Viktor Hofer --- .../src/PACKAGE.md | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md index 9e3801f758a082..433fa943e1172a 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md @@ -2,40 +2,48 @@ - +Provides support for matching file system names/paths using [glob patterns](https://en.wikipedia.org/wiki/Glob_(programming)). ## Key Features -* -* -* +* Contains the `Matcher` type, which can be used to match files in the file system based on user-defined patterns. ## How to Use +Get all matching files: + +```c# +using Microsoft.Extensions.FileSystemGlobbing; + +Matcher matcher = new(); +matcher.AddIncludePatterns(new[] { "*.txt", "*.asciidoc", "*.md" }); + +string searchDirectory = "../starting-folder/"; + +IEnumerable matchingFiles = matcher.GetResultsInFullPath(searchDirectory); + +// Use matchingFiles if there are any found. +// The files in this collection are fully qualified file system paths. +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `Microsoft.Extensions.FileSystemGlobbing.Matcher` -## Addtional Documentation +## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - +* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/core/extensions/file-globbing) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.filesystemglobbing) ## Feedback & Contributing From cae670e287f32d8b38ef6092bddc9b5319e35d78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= Date: Wed, 18 Oct 2023 00:34:17 +0200 Subject: [PATCH 400/783] Provide Microsoft.Extentions.FileProviders.Abstractions package readme (#93489) * Provide FileProviders.Abstractions package readme * Improve how to use section --- .../src/PACKAGE.md | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md index efb7ca7c9133cc..bbb9b68a06e4a6 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/PACKAGE.md @@ -2,43 +2,50 @@ - +Serves as the foundation for creating file providers in .NET, offering core abstractions to develop custom file providers capable of fetching files from various sources. ## Key Features -* -* -* +* Core abstractions for creating and managing file providers. +* Flexibility to develop custom file providers for fetching files from distinct sources. ## How to Use +This package is typically used with an implementation of the file provider abstractions, such as `Microsoft.Extensions.FileProviders.Composite` or `Microsoft.Extensions.FileProviders.Physical`. + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `Microsoft.Extensions.FileProviders.IFileProvider` +* `Microsoft.Extensions.FileProviders.IDirectoryContents` +* `Microsoft.Extensions.FileProviders.IFileInfo` +* `Microsoft.Extensions.FileProviders.NullFileProvider` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/aspnet/core/fundamentals/file-providers) +* [Detect changes with change tokens](https://learn.microsoft.com/aspnet/core/fundamentals/change-tokens) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.fileproviders) ## Related Packages +* File provider for physical files: [Microsoft.Extensions.FileProviders.Physical](https://www.nuget.org/packages/Microsoft.Extensions.FileProviders.Physical/) +* File provider for files in embedded resources: [Microsoft.Extensions.FileProviders.Embedded](https://www.nuget.org/packages/Microsoft.Extensions.FileProviders.Embedded/) +* Composite file and directory providers: [Microsoft.Extensions.FileProviders.Composite](https://www.nuget.org/packages/Microsoft.Extensions.FileProviders.Composite/) + ## Feedback & Contributing -Microsoft.Extensions.FileProviders.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.FileProviders.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From b34dc7e761c9eb191e0cf2ec1fedd5ea2a04817f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= Date: Wed, 18 Oct 2023 00:34:36 +0200 Subject: [PATCH 401/783] Provide Microsoft.Extentions.FileProviders.Physical package readme (#93485) * Provide FileProviders.Physical package readme * Remove whitespace --- .../src/PACKAGE.md | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md index bf3378a56e63dd..6ffcd733120209 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PACKAGE.md @@ -2,43 +2,69 @@ +Provides an implementation of a physical file provider, facilitating file access and monitoring on the disk. The primary type, [`PhysicalFileProvider`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.fileproviders.physicalfileprovider), enables the lookup of files on disk and can watch for changes either via `FileSystemWatcher` or polling mechanisms. ## Key Features -* -* -* +* Easy access and monitoring of files on the disk. +* Ability to watch for file changes either by using `FileSystemWatcher` or through polling. ## How to Use +This library can be used to look up files on disk and monitor file changes effectively. +Below is an example of how to use the `PhysicalFileProvider` to access files on disk and monitor changes: + +```c# +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.FileProviders.Physical; + +using var provider = new PhysicalFileProvider(AppContext.BaseDirectory); + +Environment.SetEnvironmentVariable("DOTNET_USE_POLLING_FILE_WATCHER", "1"); + +var contents = provider.GetDirectoryContents(string.Empty); +foreach (PhysicalFileInfo fileInfo in contents) +{ + Console.WriteLine(fileInfo.PhysicalPath); +} + +var changeToken = provider.Watch("*.txt"); +changeToken.RegisterChangeCallback(_ => Console.WriteLine("Text file changed"), null); + +Console.ReadLine(); +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `Microsoft.Extensions.FileProviders.PhysicalFileProvider` +* `Microsoft.Extensions.FileProviders.PhysicalDirectoryInfo` +* `Microsoft.Extensions.FileProviders.PhysicalFileInfo` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/aspnet/core/fundamentals/file-providers#physical-file-provider) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.fileproviders.physical) ## Related Packages +* Abstractions of files and directories: [Microsoft.Extensions.FileProviders.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.FileProviders.Abstractions/) +* File system globbing to find files matching a specified pattern: [Microsoft.Extensions.FileSystemGlobbing](https://www.nuget.org/packages/Microsoft.Extensions.FileSystemGlobbing/) + ## Feedback & Contributing -Microsoft.Extensions.FileProviders.Physical is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.FileProviders.Physical is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 7ad2ed9acd0196e349b9fa5a745a71c52827fb04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= Date: Wed, 18 Oct 2023 01:45:52 +0200 Subject: [PATCH 402/783] Provide DirectoryServices.Protocols package readme (#93518) --- .../src/PACKAGE.md | 43 +++++++++++++++---- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md b/src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md index 61bbd897786b2c..2938eee70fa8b0 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md +++ b/src/libraries/System.DirectoryServices.Protocols/src/PACKAGE.md @@ -2,43 +2,68 @@ +System.DirectoryServices.Protocols provides a managed implementation of Lightweight Directory Access Protocol (LDAP) version 3 and Directory Services Markup Language (DSML) version 2.0 (V2) standards. +It primarily uses the `LdapConnection` type for interacting with LDAP servers, using system native libraries to establish TCP/IP or UDP LDAP connections. +Supports both Windows and Unix, but certain features, such as setting client or server certificate options, are not available on Unix. ## Key Features -* -* -* +* Managed implementation of LDAP v3 and DSML V2 standards. ## How to Use +Using the `LdapConnection` type, you can establish connections to LDAP servers and issue requests. + +Here is a simple example: + +```csharp +using System.DirectoryServices.Protocols; + +// Create a new LdapConnection instance using the server URL. +using (LdapConnection connection = new LdapConnection("ldap.example.com")) { + + // Some credentials + connection.Credential = new NetworkCredential(dn, password); + + // Connect to the server + connection.Bind(); + + // Perform LDAP operations +} +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `System.DirectoryServices.Protocols.LdapConnection` +* `System.DirectoryServices.Protocols.DirectoryAttribute` +* `System.DirectoryServices.Protocols.DirectoryOperation` +* `System.DirectoryServices.Protocols.DirectoryRequest` +* `System.DirectoryServices.Protocols.DirectoryResponse` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [API documentation](https://learn.microsoft.com/dotnet/api/system.directoryservices.protocols) +* [Active Directory Domain Services](https://learn.microsoft.com/windows/win32/ad/active-directory-domain-services) ## Related Packages +* [System.DirectoryServices](https://www.nuget.org/packages/System.DirectoryServices/) + ## Feedback & Contributing -System.DirectoryServices.Protocols is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +System.DirectoryServices.Protocols is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From b6289e2038043809b5c531a7d1c47963800901a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= Date: Wed, 18 Oct 2023 08:14:30 +0200 Subject: [PATCH 403/783] Provide System.IO.Hashing package readme (#93567) --- .../System.IO.Hashing/src/PACKAGE.md | 65 ++++++++++++++++--- 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.IO.Hashing/src/PACKAGE.md b/src/libraries/System.IO.Hashing/src/PACKAGE.md index 5bb2b571759074..64fa5ff754845b 100644 --- a/src/libraries/System.IO.Hashing/src/PACKAGE.md +++ b/src/libraries/System.IO.Hashing/src/PACKAGE.md @@ -2,43 +2,90 @@ +System.IO.Hashing offers a variety of hash code algorithms. +Hash code algorithms are pivotal for generating unique values for objects based on their content, facilitating object comparisons, and detecting content alterations. +The namespace encompasses algorithms like CRC-32, CRC-64, xxHash3, xxHash32, xxHash64, and xxHash128, all engineered for swift and efficient hash code generation, with xxHash being an "Extremely fast hash algorithm". + +**Warning**: The hash functions provided by System.IO.Hashing are not suitable for security purposes such as handling passwords or verifying untrusted content. +For such security-critical applications, consider using cryptographic hash functions provided by the [System.Security.Cryptography](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography) namespace. ## Key Features -* -* -* +* Variety of hash code algorithms including CRC-32, CRC-64, xxHash3, xxHash32, xxHash64, and xxHash128. +* Implementations of CRC-32 and CRC-64 algorithms, as used in IEEE 802.3, and described in ECMA-182, Annex B respectively. +* Implementations of XxHash32 for generating 32-bit hashes, XxHash3 and XxHash64 for generating 64-bit hashes, and xxHash128 for generating 128-bit hashes. ## How to Use +Creating hash codes is straightforward. +Call the `Hash` method with the content to be hashed. + +Here is a practical example: + +```csharp +using System; +using System.IO.Hashing; + +byte[] data = new byte[] { 1, 2, 3, 4 }; + +byte[] crc32Value = Crc32.Hash(data); +Console.WriteLine($"CRC-32 Hash: {BitConverter.ToString(crc32Value)}"); +// CRC-32 Hash: CD-FB-3C-B6 + +byte[] crc64Value = Crc64.Hash(data); +Console.WriteLine($"CRC-64 Hash: {BitConverter.ToString(crc64Value)}"); +// CRC-64 Hash: 58-8D-5A-D4-2A-70-1D-B2 + +byte[] xxHash3Value = XxHash3.Hash(data); +Console.WriteLine($"XxHash3 Hash: {BitConverter.ToString(xxHash3Value)}"); +// XxHash3 Hash: 98-8B-7B-90-33-AC-46-22 + +byte[] xxHash32Value = XxHash32.Hash(data); +Console.WriteLine($"XxHash32 Hash: {BitConverter.ToString(xxHash32Value)}"); +// XxHash32 Hash: FE-96-D1-9C + +byte[] xxHash64Value = XxHash64.Hash(data); +Console.WriteLine($"XxHash64 Hash: {BitConverter.ToString(xxHash64Value)}"); +// XxHash64 Hash: 54-26-20-E3-A2-A9-2E-D1 + +byte[] xxHash128Value = XxHash128.Hash(data); +Console.WriteLine($"XxHash128 Hash: {BitConverter.ToString(xxHash128Value)}"); +// XxHash128 Hash: 49-A0-48-99-59-7A-35-67-53-76-53-A0-D9-95-5B-86 +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `System.IO.Hashing.Crc32` +* `System.IO.Hashing.Crc64` +* `System.IO.Hashing.XxHash3` +* `System.IO.Hashing.XxHash32` +* `System.IO.Hashing.XxHash64` +* `System.IO.Hashing.XxHash128` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [API documentation](https://learn.microsoft.com/dotnet/api/system.io.hashing) +* [xxHash - Extremely fast hash algorithm](https://github.com/Cyan4973/xxHash/blob/release/doc/xxhash_spec.md) ## Related Packages +Cryptographic services, including secure encryption and decryption of data: [System.Security.Cryptography](https://learn.microsoft.com/dotnet/api/system.security.cryptography) + ## Feedback & Contributing -System.IO.Hashing is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +System.IO.Hashing is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 59080e6ae589da5a82fec3eefd6569201343780a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= Date: Wed, 18 Oct 2023 22:05:14 +0200 Subject: [PATCH 404/783] Provide Microsoft.Extensions.Options.DataAnnotations package readme (#93657) --- .../src/PACKAGE.md | 49 +++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md index 3bf3280ad4cf1b..368518bbedb313 100644 --- a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/PACKAGE.md @@ -2,43 +2,74 @@ +Microsoft.Extensions.Options.DataAnnotations is a library that adds extra validation functionality to configuration options using data annotations. +It allows to apply validation rules to configuration classes to ensure they are correctly configured before the application starts running. + +This way, misconfiguration issues are catched early during the application startup rather than facing them later in production. ## Key Features -* -* -* +* Enables validation of configuration options using data annotations. +* Early detection of misconfiguration issues during application startup. ## How to Use +While configuring services, chain the `ValidateDataAnnotations()` and `ValidateOnStart()` methods to the `AddOptions` method for your configuration class. + +Here is a simple example demonstrating how to validate options on application startup: + +```csharp +services + .AddOptions() + .ValidateDataAnnotations() + .ValidateOnStart(); +``` + +In the configuration class, use data annotations to specify the validation rules. + +For instance, in the following `MyOptions` class, the `Name` property is marked as required: + +```csharp +using System.ComponentModel.DataAnnotations; + +public class MyOptions +{ + [Required(AllowEmptyStrings = false)] + public string Name { get; set; } +} +``` + +With this setup, an error indicating that the `Name` field is required will be thrown upon startup if it hasn't been configured. + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `Microsoft.Extensions.Options.DataAnnotationsValidateOptions` +* `Microsoft.Extensions.DependencyInjection.OptionsBuilderDataAnnotationsExtensions` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/dotnet/core/extensions/options) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.options.dataannotationvalidateoptions-1) ## Related Packages +Core options: [Microsoft.Extensions.Options](https://www.nuget.org/packages/Microsoft.Extensions.Options/) + ## Feedback & Contributing -Microsoft.Extensions.Options.DataAnnotations is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.Options.DataAnnotations is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 72cad7de2d57d73a64e7764a13212461b61d5938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= Date: Thu, 19 Oct 2023 21:37:30 +0200 Subject: [PATCH 405/783] Provide Microsoft.Extensions.Caching.Abstractions package readme (#93653) * Provide Caching.Abstractions package readme * Process feedback --- .../src/PACKAGE.md | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md index 651e3c04c98405..eb8a9beacbc44b 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/PACKAGE.md @@ -2,43 +2,52 @@ +Provides the abstractions to create and use in-memory and distributed caching in your applications. +This library defines how in-memory and distributed caches should be implemented; it doesn’t contain any cache implementation. +With the abstractions provided in this library, various types of caches can be built and used interchangeably, whether the data is kept in memory, in files, or even across a network. ## Key Features -* -* -* +* Interfaces for building and using in-memory and distributed caches. ## How to Use +This package is typically used with an implementation of the caching abstractions, such as `Microsoft.Extensions.Caching.Memory` or `Microsoft.Extensions.Caching.SqlServer`. + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `Microsoft.Extensions.Caching.Abstractions.ICacheEntry` +* `Microsoft.Extensions.Caching.Abstractions.IMemoryCache` +* `Microsoft.Extensions.Caching.Abstractions.IDistributedCache` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/dotnet/core/extensions/caching) +* API documentation + * [Microsoft.Extensions.Caching.Memory](https://learn.microsoft.com/dotnet/api/microsoft.extensions.caching.memory) + * [Microsoft.Extensions.Caching.Distributed](https://learn.microsoft.com/dotnet/api/microsoft.extensions.caching.distributed) ## Related Packages +* In-memory caching: [Microsoft.Extensions.Caching.Memory](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Memory/) +* SQL Server caching: [Microsoft.Extensions.Caching.SqlServer](https://www.nuget.org/packages/Microsoft.Extensions.Caching.SqlServer/) +* Redis caching: [Microsoft.Extensions.Caching.StackExchangeRedis](https://www.nuget.org/packages/Microsoft.Extensions.Caching.StackExchangeRedis/) + ## Feedback & Contributing -Microsoft.Extensions.Caching.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +Microsoft.Extensions.Caching.Abstractions is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 4631159c9604e940e8ac12d168876bd1ab44354f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= Date: Thu, 19 Oct 2023 21:42:26 +0200 Subject: [PATCH 406/783] Provide System.Memory.Data package readme (#93516) * Provide System.Memory.Data package readme * Update src/libraries/System.Memory.Data/src/PACKAGE.md --------- Co-authored-by: Viktor Hofer --- .../System.Memory.Data/src/PACKAGE.md | 84 ++++++++++++++++--- 1 file changed, 71 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Memory.Data/src/PACKAGE.md b/src/libraries/System.Memory.Data/src/PACKAGE.md index 9c4f30806907e1..33996a16b08252 100644 --- a/src/libraries/System.Memory.Data/src/PACKAGE.md +++ b/src/libraries/System.Memory.Data/src/PACKAGE.md @@ -2,43 +2,101 @@ +System.Memory.Data introduces the `BinaryData` type, a lightweight abstraction for a byte payload. +It makes it easy to convert between string, bytes, and stream. + +This abstraction can simplify the API surface by exposing a single type instead of numerous overloads or properties. +The `BinaryData` type handles data ownership efficiently, wrapping passed-in bytes when using `byte[]` or `ReadOnlyMemory` constructors or methods, and managing data as bytes when dealing with streams, strings, or rich model types serialized as JSON. ## Key Features -* -* -* +* Lightweight abstraction for byte payload via `BinaryData` type. +* Convenient helper methods for common conversions among string, bytes, and stream. +* Efficient data ownership handling. ## How to Use +To/From String: + +```csharp +var data = new BinaryData("some data"); + +// ToString will decode the bytes using UTF-8 +Console.WriteLine(data.ToString()); // prints "some data" +``` + +To/From Bytes: + +```csharp +byte[] bytes = Encoding.UTF8.GetBytes("some data"); + +// Create BinaryData using a constructor ... +BinaryData data = new BinaryData(bytes); + +// Or using a static factory method. +data = BinaryData.FromBytes(bytes); + +// There is an implicit cast defined for ReadOnlyMemory +ReadOnlyMemory rom = data; + +// There is also an implicit cast defined for ReadOnlySpan +ReadOnlySpan ros = data; + +// there is also a ToMemory method that gives access to the ReadOnlyMemory. +rom = data.ToMemory(); + +// and a ToArray method that converts into a byte array. +byte[] array = data.ToArray(); +``` + +To/From stream: + +```csharp +var bytes = Encoding.UTF8.GetBytes("some data"); +Stream stream = new MemoryStream(bytes); +var data = BinaryData.FromStream(stream); + +// Calling ToStream will give back a stream that is backed by ReadOnlyMemory, so it is not writable. +stream = data.ToStream(); +Console.WriteLine(stream.CanWrite); // prints false +``` + +`BinaryData` also can be used to integrate with `ObjectSerializer`. +By default, the `JsonObjectSerializer` will be used, but any serializer deriving from `ObjectSerializer` can be used. + +```csharp +var model = new CustomModel +{ + A = "some text", + B = 5, + C = true +}; + +var data = BinaryData.FromObjectAsJson(model); +model = data.ToObjectFromJson(); +``` + ## Main Types The main types provided by this library are: -* `` -* `` -* `` +* `System.BinaryData` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) - -## Related Packages - - +* [API documentation](https://learn.microsoft.com/dotnet/api/system.binarydata) ## Feedback & Contributing -System.Memory.Data is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +System.Memory.Data is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From a9cc342e7ee5079db8a19f154a31ca501bd52a34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= Date: Fri, 20 Oct 2023 00:05:04 +0200 Subject: [PATCH 407/783] Provide System.Security.Cryptography.ProtectedData package readme (#93660) * Provide Cryptography.ProtectedData package readme * Processing review comments * Remove paragraph and improve sentence * Improve code sample --- .../src/PACKAGE.md | 48 +++++++++++++++---- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md b/src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md index 09e76336690163..7a0f751326f550 100644 --- a/src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md +++ b/src/libraries/System.Security.Cryptography.ProtectedData/src/PACKAGE.md @@ -2,43 +2,71 @@ +System.Security.Cryptography.ProtectedData offers a simplified interface for utilizing Microsoft Windows DPAPI's [CryptProtectData](https://learn.microsoft.com/windows/win32/api/dpapi/nf-dpapi-cryptprotectdata) and [CryptUnprotectData](https://learn.microsoft.com/windows/win32/api/dpapi/nf-dpapi-cryptunprotectdata) functions. +**Note**: Since it relies on Windows DPAPI, this package is only supported on Windows platforms. +For more complex cryptographic operations or cross-platform support, consider the [System.Security.Cryptography](https://learn.microsoft.com/dotnet/api/system.security.cryptography) namespace. ## Key Features -* -* -* +* Built upon the robust and secure Windows Data Protection API (DPAPI). +* Data can be protected either for current process or for any process on the machine. +* Scope of protection can be defined either to the current user or the local machine. ## How to Use +Utilizing this package is quite simple, and it mainly revolves around two methods: `Protect` and `Unprotect`. + +Here, `originalData` is the data you want to protect, `optionalEntropy` is an additional byte array used to increase encryption complexity, and `DataProtectionScope` specifies whether the data protection should apply to the current user or the machine. + +```csharp +using System.Security.Cryptography; +using System.Text; + +byte[] originalData = Encoding.UTF8.GetBytes("This is a secret"); +byte[] optionalEntropy = new byte[64]; +Random.Shared.NextBytes(optionalEntropy); + +// To protect: +byte[] encryptedData = ProtectedData.Protect( + originalData, + optionalEntropy, + DataProtectionScope.CurrentUser); + +// To unprotect: +byte[] decryptedData = ProtectedData.Unprotect( + encryptedData, + optionalEntropy, + DataProtectionScope.CurrentUser); +``` + ## Main Types -The main types provided by this library are: +The main type provided by this library is: -* `` -* `` -* `` +* `System.Security.Cryptography.ProtectedData` ## Additional Documentation -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/**LIBRARYNAME**/overview) -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/**LIBRARYNAME**) +* [Conceptual documentation](https://learn.microsoft.com/dotnet/standard/security/how-to-use-data-protection) +* [API documentation](https://learn.microsoft.com/dotnet/api/system.security.cryptography.protecteddata) ## Related Packages +* PKCS and CMS algorithms: [System.Security.Cryptography.Pkcs](https://www.nuget.org/packages/System.Security.Cryptography.Pkcs/) + ## Feedback & Contributing -System.Security.Cryptography.ProtectedData is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). \ No newline at end of file +System.Security.Cryptography.ProtectedData is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 6012d754fe8e44cb9082649850ec9f732f5cca52 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Fri, 20 Oct 2023 09:56:23 +0200 Subject: [PATCH 408/783] Remove en-us culture code from URIs --- src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md | 2 +- .../Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md | 2 +- .../Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md | 2 +- src/libraries/System.Formats.Cbor/src/PACKAGE.md | 2 +- src/libraries/System.IO.Hashing/src/PACKAGE.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md index 4346252b24386b..215d29e162c4b6 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md @@ -32,7 +32,7 @@ The main types provided by this library are: ## Additional Documentation -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/System.Security.Cryptography) +* [API documentation](https://learn.microsoft.com/dotnet/api/System.Security.Cryptography) ## Feedback & Contributing diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md index 433fa943e1172a..25bd9129c3968b 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PACKAGE.md @@ -42,7 +42,7 @@ The main types provided by this library are: -* [Conceptual documentation](https://learn.microsoft.com/en-us/dotnet/core/extensions/file-globbing) +* [Conceptual documentation](https://learn.microsoft.com/dotnet/core/extensions/file-globbing) * [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.filesystemglobbing) ## Feedback & Contributing diff --git a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md index 25abc578ba6d36..a58e190ec552b9 100644 --- a/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md +++ b/src/libraries/Microsoft.Extensions.Logging.TraceSource/src/PACKAGE.md @@ -58,7 +58,7 @@ The main types provided by this library are: -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.tracesource) +* [API documentation](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.tracesource) ## Related Packages diff --git a/src/libraries/System.Formats.Cbor/src/PACKAGE.md b/src/libraries/System.Formats.Cbor/src/PACKAGE.md index ff26f0debbdc0a..b6549d0941e8c2 100644 --- a/src/libraries/System.Formats.Cbor/src/PACKAGE.md +++ b/src/libraries/System.Formats.Cbor/src/PACKAGE.md @@ -86,7 +86,7 @@ The main types provided by this library are: -* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.formats.cbor) +* [API documentation](https://learn.microsoft.com/dotnet/api/system.formats.cbor) ## Feedback & Contributing diff --git a/src/libraries/System.IO.Hashing/src/PACKAGE.md b/src/libraries/System.IO.Hashing/src/PACKAGE.md index 64fa5ff754845b..41b90205eac84e 100644 --- a/src/libraries/System.IO.Hashing/src/PACKAGE.md +++ b/src/libraries/System.IO.Hashing/src/PACKAGE.md @@ -8,7 +8,7 @@ Hash code algorithms are pivotal for generating unique values for objects based The namespace encompasses algorithms like CRC-32, CRC-64, xxHash3, xxHash32, xxHash64, and xxHash128, all engineered for swift and efficient hash code generation, with xxHash being an "Extremely fast hash algorithm". **Warning**: The hash functions provided by System.IO.Hashing are not suitable for security purposes such as handling passwords or verifying untrusted content. -For such security-critical applications, consider using cryptographic hash functions provided by the [System.Security.Cryptography](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography) namespace. +For such security-critical applications, consider using cryptographic hash functions provided by the [System.Security.Cryptography](https://learn.microsoft.com/dotnet/api/system.security.cryptography) namespace. ## Key Features From 07f535a74924b41ea4137ccb67cac73f1fbc1133 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 22:11:41 +0200 Subject: [PATCH 409/783] [release/8.0] Update dependencies from dotnet/arcade (#93727) * Update dependencies from https://github.com/dotnet/arcade build 20231016.4 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23505.1 -> To Version 8.0.0-beta.23516.4 * use latest daily for workload testing * Update dependencies from https://github.com/dotnet/arcade build 20231016.4 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23505.1 -> To Version 8.0.0-beta.23516.4 * Respond to post rc1 template changes --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Larry Ewing --- eng/Version.Details.xml | 72 +++++++++---------- eng/Versions.props | 32 ++++----- eng/common/sdk-task.ps1 | 2 +- eng/common/tools.ps1 | 4 +- global.json | 10 +-- .../Wasm.Build.Tests/Blazor/MiscTests3.cs | 4 +- .../Blazor/WorkloadRequiredTests.cs | 2 +- 7 files changed, 63 insertions(+), 63 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b2a167af26f5d8..fd1357fb1b844a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -107,9 +107,9 @@ - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 @@ -117,69 +117,69 @@ 73f0850939d96131c28cf6ea6ee5aacb4da0083a - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 https://github.com/dotnet/runtime-assets @@ -330,9 +330,9 @@ https://github.com/dotnet/xharness 480b9159eb7e69b182a87581d5a336e97e0b6dae - + https://github.com/dotnet/arcade - e6be64c3e27aeb29f93f6aa751fad972e4ef2d52 + 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index 25b12b58fd53ec..19e6a5891d30b2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -87,21 +87,21 @@ 8.0.100-preview.7.23329.3 - 8.0.0-beta.23505.1 - 8.0.0-beta.23505.1 - 8.0.0-beta.23505.1 - 8.0.0-beta.23505.1 - 8.0.0-beta.23505.1 - 2.5.1-beta.23505.1 - 8.0.0-beta.23505.1 - 8.0.0-beta.23505.1 - 8.0.0-beta.23505.1 - 8.0.0-beta.23505.1 - 8.0.0-beta.23505.1 - 8.0.0-beta.23505.1 - 8.0.0-beta.23505.1 - 8.0.0-beta.23505.1 - 8.0.0-beta.23505.1 + 8.0.0-beta.23516.4 + 8.0.0-beta.23516.4 + 8.0.0-beta.23516.4 + 8.0.0-beta.23516.4 + 8.0.0-beta.23516.4 + 2.5.1-beta.23516.4 + 8.0.0-beta.23516.4 + 8.0.0-beta.23516.4 + 8.0.0-beta.23516.4 + 8.0.0-beta.23516.4 + 8.0.0-beta.23516.4 + 8.0.0-beta.23516.4 + 8.0.0-beta.23516.4 + 8.0.0-beta.23516.4 + 8.0.0-beta.23516.4 6.0.0-preview.1.102 @@ -259,6 +259,6 @@ 1.0.406601 8.0.100-rtm.23478.7 - $(MicrosoftDotnetSdkInternalVersion) + diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1 index 91f8196cc808db..73828dd30d3179 100644 --- a/eng/common/sdk-task.ps1 +++ b/eng/common/sdk-task.ps1 @@ -64,7 +64,7 @@ try { $GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty } if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) { - $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.7.2-1" -MemberType NoteProperty + $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.8.1-2" -MemberType NoteProperty } if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") { $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 84cfe7cd9cb463..fdd0cbb91f8596 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -384,8 +384,8 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = # If the version of msbuild is going to be xcopied, # use this version. Version matches a package here: - # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/RoslynTools.MSBuild/versions/17.7.2-1 - $defaultXCopyMSBuildVersion = '17.7.2-1' + # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/RoslynTools.MSBuild/versions/17.8.1-2 + $defaultXCopyMSBuildVersion = '17.8.1-2' if (!$vsRequirements) { if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') { diff --git a/global.json b/global.json index b3fdf36ccb3d25..38ec23b6193a2f 100644 --- a/global.json +++ b/global.json @@ -1,16 +1,16 @@ { "sdk": { - "version": "8.0.100-rc.1.23455.8", + "version": "8.0.100-rtm.23506.1", "allowPrerelease": true, "rollForward": "major" }, "tools": { - "dotnet": "8.0.100-rc.1.23455.8" + "dotnet": "8.0.100-rtm.23506.1" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23505.1", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23505.1", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23505.1", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23516.4", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23516.4", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23516.4", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/MiscTests3.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/MiscTests3.cs index b006bf7a93e5c3..10717b334174b9 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/MiscTests3.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/MiscTests3.cs @@ -63,7 +63,7 @@ public static class MyDllImports public static extern int cpp_add(int a, int b); }}"; - File.WriteAllText(Path.Combine(_projectDir!, "Components", "Pages", "MyDllImport.cs"), myDllImportCs); + File.WriteAllText(Path.Combine(_projectDir!, "Pages", "MyDllImport.cs"), myDllImportCs); AddItemsPropertiesToProject(projectFile, extraItems: @""); BlazorAddRazorButton("cpp_add", """ @@ -144,7 +144,7 @@ public void BugRegression_60479_WithRazorClassLib() Assert.Contains(razorClassLibraryFileName, lazyVal.EnumerateObject().Select(jp => jp.Name)); } - private void BlazorAddRazorButton(string buttonText, string customCode, string methodName = "test", string razorPage = "Components/Pages/Counter.razor") + private void BlazorAddRazorButton(string buttonText, string customCode, string methodName = "test", string razorPage = "Pages/Counter.razor") { string additionalCode = $$"""

Output: @outputText

diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/WorkloadRequiredTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/WorkloadRequiredTests.cs index 7ca663dce5372f..cbe3e461ec9cde 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/WorkloadRequiredTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/WorkloadRequiredTests.cs @@ -84,7 +84,7 @@ public async Task WorkloadNotRequiredForInvariantGlobalization(string config, bo if (invariant) AddItemsPropertiesToProject(projectFile, extraProperties: "true"); - string counterPath = Path.Combine(Path.GetDirectoryName(projectFile)!, "Components", "Pages", "Counter.razor"); + string counterPath = Path.Combine(Path.GetDirectoryName(projectFile)!, "Pages", "Counter.razor"); string allText = File.ReadAllText(counterPath); string ccText = "currentCount++;"; if (allText.IndexOf(ccText) < 0) From 0b0222b0f2b29fd7e63d2be16700515d1c41cfeb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:22:10 -0700 Subject: [PATCH 410/783] [release/8.0] Support specifying multiple directories through SSL_CERT_DIR. (#93749) * Support specifying multiple directories through SSL_CERT_DIR. * Apply suggestions from code review Co-authored-by: Jeremy Barton Co-authored-by: Kevin Jones * PR feedback. * Only check for duplicates when there's at least 2 directories. --------- Co-authored-by: Tom Deseyn Co-authored-by: Jeremy Barton Co-authored-by: Kevin Jones Co-authored-by: Jeff Handley --- .../OpenSslCachedSystemStoreProvider.cs | 232 +++++++++--------- .../X509Certificates/X509StoreTests.Unix.cs | 42 +++- 2 files changed, 157 insertions(+), 117 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCachedSystemStoreProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCachedSystemStoreProvider.cs index 4c9643c01e2fcb..e66b3d1ad11022 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCachedSystemStoreProvider.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCachedSystemStoreProvider.cs @@ -21,14 +21,14 @@ internal sealed class OpenSslCachedSystemStoreProvider : IStorePal private static readonly TimeSpan s_lastWriteRecheckInterval = TimeSpan.FromSeconds(5); private static readonly TimeSpan s_assumeInvalidInterval = TimeSpan.FromMinutes(5); private static readonly Stopwatch s_recheckStopwatch = new Stopwatch(); - private static DirectoryInfo? s_rootStoreDirectoryInfo = SafeOpenRootDirectoryInfo(); + private static string[]? s_rootStoreDirectories; private static bool s_defaultRootDir; - private static readonly FileInfo? s_rootStoreFileInfo = SafeOpenRootFileInfo(); + private static string? s_rootStoreFile; + private static DateTime[]? s_directoryLastWrite; + private static DateTime s_fileLastWrite; // Use non-Value-Tuple so that it's an atomic update. private static Tuple? s_nativeCollections; - private static DateTime s_directoryCertsLastWrite; - private static DateTime s_fileCertsLastWrite; private readonly bool _isRoot; @@ -93,18 +93,11 @@ private static Tuple GetCollections() { lock (s_recheckStopwatch) { - FileInfo? fileInfo = s_rootStoreFileInfo; - DirectoryInfo? dirInfo = s_rootStoreDirectoryInfo; - - fileInfo?.Refresh(); - dirInfo?.Refresh(); - if (ret == null || elapsed > s_assumeInvalidInterval || - (fileInfo != null && fileInfo.Exists && ContentWriteTime(fileInfo) != s_fileCertsLastWrite) || - (dirInfo != null && dirInfo.Exists && ContentWriteTime(dirInfo) != s_directoryCertsLastWrite)) + LastWriteTimesHaveChanged()) { - ret = LoadMachineStores(dirInfo, fileInfo); + ret = LoadMachineStores(); } } } @@ -113,9 +106,37 @@ private static Tuple GetCollections() return ret; } - private static Tuple LoadMachineStores( - DirectoryInfo? rootStorePath, - FileInfo? rootStoreFile) + private static bool LastWriteTimesHaveChanged() + { + Debug.Assert( + Monitor.IsEntered(s_recheckStopwatch), + "LastWriteTimesHaveChanged assumes a lock(s_recheckStopwatch)"); + + if (s_rootStoreFile != null) + { + _ = TryStatFile(s_rootStoreFile, out DateTime lastModified); + if (lastModified != s_fileLastWrite) + { + return true; + } + } + + if (s_rootStoreDirectories != null && s_directoryLastWrite != null) + { + for (int i = 0; i < s_rootStoreDirectories.Length; i++) + { + _ = TryStatDirectory(s_rootStoreDirectories[i], out DateTime lastModified); + if (lastModified != s_directoryLastWrite[i]) + { + return true; + } + } + } + + return false; + } + + private static Tuple LoadMachineStores() { Debug.Assert( Monitor.IsEntered(s_recheckStopwatch), @@ -126,61 +147,76 @@ private static Tuple LoadMachineStores SafeX509StackHandle intermedStore = Interop.Crypto.NewX509Stack(); Interop.Crypto.CheckValidOpenSslHandle(intermedStore); - DateTime newFileTime = default; - DateTime newDirTime = default; - var uniqueRootCerts = new HashSet(); var uniqueIntermediateCerts = new HashSet(); bool firstLoad = (s_nativeCollections == null); - if (rootStoreFile != null && rootStoreFile.Exists) + if (firstLoad) { - newFileTime = ContentWriteTime(rootStoreFile); - ProcessFile(rootStoreFile); + s_rootStoreDirectories = GetRootStoreDirectories(out s_defaultRootDir); + s_directoryLastWrite = new DateTime[s_rootStoreDirectories.Length]; + s_rootStoreFile = GetRootStoreFile(); + } + else + { + Debug.Assert(s_rootStoreDirectories is not null); + Debug.Assert(s_directoryLastWrite is not null); + } + + if (s_rootStoreFile != null) + { + ProcessFile(s_rootStoreFile, out s_fileLastWrite); } bool hasStoreData = false; - if (rootStorePath != null && rootStorePath.Exists) + for (int i = 0; i < s_rootStoreDirectories.Length; i++) { - newDirTime = ContentWriteTime(rootStorePath); - hasStoreData = ProcessDir(rootStorePath); + hasStoreData = ProcessDir(s_rootStoreDirectories[i], out s_directoryLastWrite[i]); } if (firstLoad && !hasStoreData && s_defaultRootDir) { - DirectoryInfo etcSslCerts = new DirectoryInfo("/etc/ssl/certs"); - - if (etcSslCerts.Exists) + const string DefaultCertDir = "/etc/ssl/certs"; + hasStoreData = ProcessDir(DefaultCertDir, out DateTime lastModified); + if (hasStoreData) { - DateTime tmpTime = ContentWriteTime(etcSslCerts); - hasStoreData = ProcessDir(etcSslCerts); - - if (hasStoreData) - { - newDirTime = tmpTime; - s_rootStoreDirectoryInfo = etcSslCerts; - } + s_rootStoreDirectories = new[] { DefaultCertDir }; + s_directoryLastWrite = new[] { lastModified }; } } - bool ProcessDir(DirectoryInfo dir) + bool ProcessDir(string dir, out DateTime lastModified) { + if (!TryStatDirectory(dir, out lastModified)) + { + return false; + } + bool hasStoreData = false; - foreach (FileInfo file in dir.EnumerateFiles()) + foreach (string file in Directory.EnumerateFiles(dir)) { - hasStoreData |= ProcessFile(file); + hasStoreData |= ProcessFile(file, out _, skipStat: true); } return hasStoreData; } - bool ProcessFile(FileInfo file) + bool ProcessFile(string file, out DateTime lastModified, bool skipStat = false) { bool readData = false; - using (SafeBioHandle fileBio = Interop.Crypto.BioNewFile(file.FullName, "rb")) + if (skipStat) + { + lastModified = default; + } + else if (!TryStatFile(file, out lastModified)) + { + return false; + } + + using (SafeBioHandle fileBio = Interop.Crypto.BioNewFile(file, "rb")) { // The handle may be invalid, for example when we don't have read permission for the file. if (fileBio.IsInvalid) @@ -274,114 +310,78 @@ bool ProcessFile(FileInfo file) // on every call. Volatile.Write(ref s_nativeCollections, newCollections); - s_directoryCertsLastWrite = newDirTime; - s_fileCertsLastWrite = newFileTime; s_recheckStopwatch.Restart(); return newCollections; } - private static FileInfo? SafeOpenRootFileInfo() + private static string? GetRootStoreFile() { string? rootFile = Interop.Crypto.GetX509RootStoreFile(); if (!string.IsNullOrEmpty(rootFile)) { - try - { - return new FileInfo(rootFile); - } - catch (ArgumentException) - { - // If SSL_CERT_FILE is set to the empty string, or anything else which gives - // "The path is not of a legal form", then the GetX509RootStoreFile value is ignored. - } + return Path.GetFullPath(rootFile); } return null; } - private static DirectoryInfo? SafeOpenRootDirectoryInfo() + private static string[] GetRootStoreDirectories(out bool isDefault) { - string? rootDirectory = Interop.Crypto.GetX509RootStorePath(out s_defaultRootDir); + string rootDirectory = Interop.Crypto.GetX509RootStorePath(out isDefault) ?? ""; - if (!string.IsNullOrEmpty(rootDirectory)) - { - try - { - return new DirectoryInfo(rootDirectory); - } - catch (ArgumentException) - { - // If SSL_CERT_DIR is set to the empty string, or anything else which gives - // "The path is not of a legal form", then the GetX509RootStoreFile value is ignored. - } - } - - return null; - } - - private static DateTime ContentWriteTime(FileInfo info) - { - string path = info.FullName; - string? target = Interop.Sys.ReadLink(path); - - if (string.IsNullOrEmpty(target)) - { - return info.LastWriteTimeUtc; - } + string[] directories = rootDirectory.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries); - if (target[0] != '/') + for (int i = 0; i < directories.Length; i++) { - target = Path.Join(info.Directory?.FullName, target); + directories[i] = Path.GetFullPath(directories[i]); } - try + // Remove duplicates. + if (directories.Length > 1) { - var targetInfo = new FileInfo(target); - - if (targetInfo.Exists) + var set = new HashSet(directories, StringComparer.Ordinal); + if (set.Count != directories.Length) { - return targetInfo.LastWriteTimeUtc; + // Preserve the original order. + string[] directoriesTrimmed = new string[set.Count]; + int j = 0; + for (int i = 0; i < directories.Length; i++) + { + string directory = directories[i]; + if (set.Remove(directory)) + { + directoriesTrimmed[j++] = directory; + } + } + Debug.Assert(set.Count == 0); + directories = directoriesTrimmed; } } - catch (ArgumentException) - { - // If we can't load information about the link path, just treat it as not a link. - } - return info.LastWriteTimeUtc; + return directories; } - private static DateTime ContentWriteTime(DirectoryInfo info) - { - string path = info.FullName; - string? target = Interop.Sys.ReadLink(path); - - if (string.IsNullOrEmpty(target)) - { - return info.LastWriteTimeUtc; - } + private static bool TryStatFile(string path, out DateTime lastModified) + => TryStat(path, Interop.Sys.FileTypes.S_IFREG, out lastModified); - if (target[0] != '/') - { - target = Path.Join(info.Parent?.FullName, target); - } + private static bool TryStatDirectory(string path, out DateTime lastModified) + => TryStat(path, Interop.Sys.FileTypes.S_IFDIR, out lastModified); - try - { - var targetInfo = new DirectoryInfo(target); + private static bool TryStat(string path, int fileType, out DateTime lastModified) + { + lastModified = default; - if (targetInfo.Exists) - { - return targetInfo.LastWriteTimeUtc; - } - } - catch (ArgumentException) + Interop.Sys.FileStatus status; + // Use Stat to follow links. + if (Interop.Sys.Stat(path, out status) < 0 || + (status.Mode & Interop.Sys.FileTypes.S_IFMT) != fileType) { - // If we can't load information about the link path, just treat it as not a link. + return false; } - return info.LastWriteTimeUtc; + lastModified = DateTime.UnixEpoch + TimeSpan.FromTicks(status.MTime * TimeSpan.TicksPerSecond + status.MTimeNsec / TimeSpan.NanosecondsPerTick); + return true; } } } diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/X509StoreTests.Unix.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/X509StoreTests.Unix.cs index 0efb6c12028fb9..f460d6b9bd6c69 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/X509StoreTests.Unix.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/X509StoreTests.Unix.cs @@ -10,7 +10,6 @@ namespace System.Security.Cryptography.X509Certificates.Tests { public partial class X509StoreTests { - [ConditionalFact(nameof(NotRunningAsRootAndRemoteExecutorSupported))] // root can read '2.pem' [PlatformSpecific(TestPlatforms.Linux)] // Windows/OSX doesn't use SSL_CERT_{DIR,FILE}. private void X509Store_MachineStoreLoadSkipsInvalidFiles() @@ -50,6 +49,47 @@ private void X509Store_MachineStoreLoadSkipsInvalidFiles() }, new RemoteInvokeOptions { StartInfo = psi }).Dispose(); } + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [PlatformSpecific(TestPlatforms.Linux)] // Windows/OSX doesn't use SSL_CERT_{DIR,FILE}. + private void X509Store_MachineStoreLoadsMutipleSslCertDirectories() + { + // Create 3 certificates and place them in two directories that will be passed + // using SSL_CERT_DIR. + string sslCertDir1 = GetTestFilePath(); + Directory.CreateDirectory(sslCertDir1); + File.WriteAllBytes(Path.Combine(sslCertDir1, "1.pem"), TestData.SelfSigned1PemBytes); + File.WriteAllBytes(Path.Combine(sslCertDir1, "2.pem"), TestData.SelfSigned2PemBytes); + string sslCertDir2 = GetTestFilePath(); + Directory.CreateDirectory(sslCertDir2); + File.WriteAllBytes(Path.Combine(sslCertDir2, "3.pem"), TestData.SelfSigned3PemBytes); + + // Add a non-existing directory after each valid directory to verify they are ignored. + string sslCertDir = string.Join(Path.PathSeparator, + new[] { + sslCertDir1, + sslCertDir2, + "", // empty string + sslCertDir2, // duplicate directory + "/invalid2", // path that does not exist + }); + + var psi = new ProcessStartInfo(); + psi.Environment.Add("SSL_CERT_DIR", sslCertDir); + // Set SSL_CERT_FILE to avoid loading the default bundle file. + psi.Environment.Add("SSL_CERT_FILE", "/nonexisting"); + RemoteExecutor.Invoke(() => + { + Assert.NotNull(Environment.GetEnvironmentVariable("SSL_CERT_DIR")); + using (var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine)) + { + store.Open(OpenFlags.OpenExistingOnly); + + // Check nr of certificates in store. + Assert.Equal(3, store.Certificates.Count); + } + }, new RemoteInvokeOptions { StartInfo = psi }).Dispose(); + } + public static bool NotRunningAsRootAndRemoteExecutorSupported => !Environment.IsPrivilegedProcess && RemoteExecutor.IsSupported; } } From 2e19d10b7a47c41b62ca2d3872aae1bef5d01a1f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:22:29 -0700 Subject: [PATCH 411/783] [release/8.0] Fix analysis of interface methods on generic types (#93748) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix analysis of interface methods on generic types Fixes an issue observed in #92881. The dependency analysis within the compiler was incorrectly considering `Equals(object x, object y)` to be the implementation of `IEqualityComparer.Equals(T, T)`. When we generate the interface dispatch table, we'd use the correct algorithm (that looks at uninstantiated types) and fail the compilation. The fix is to use the same algorithm during dependency analysis. Looks like this has been broken ever since interface support was added to CoreRT: https://github.com/dotnet/corert/pull/626. * Stop building a test --------- Co-authored-by: Michal Strehovský Co-authored-by: Andy Gocke --- .../Compiler/DependencyAnalysis/EETypeNode.cs | 26 +++++++--- .../MethodBodyOnUnrelatedType.ilproj | 3 ++ .../SmokeTests/UnitTests/Interfaces.cs | 49 +++++++++++++++++++ 3 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs index 61520b4bfadaff..eb64be16023150 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs @@ -437,10 +437,14 @@ public sealed override IEnumerable GetConditionalSt // Add conditional dependencies for interface methods the type implements. For example, if the type T implements // interface IFoo which has a method M1, add a dependency on T.M1 dependent on IFoo.M1 being called, since it's // possible for any IFoo object to actually be an instance of T. + DefType defTypeDefinition = (DefType)defType.GetTypeDefinition(); DefType[] defTypeRuntimeInterfaces = defType.RuntimeInterfaces; + DefType[] defTypeDefinitionRuntimeInterfaces = defTypeDefinition.RuntimeInterfaces; + Debug.Assert(defTypeDefinitionRuntimeInterfaces.Length == defTypeRuntimeInterfaces.Length); for (int interfaceIndex = 0; interfaceIndex < defTypeRuntimeInterfaces.Length; interfaceIndex++) { DefType interfaceType = defTypeRuntimeInterfaces[interfaceIndex]; + DefType interfaceDefinitionType = defTypeDefinitionRuntimeInterfaces[interfaceIndex]; Debug.Assert(interfaceType.IsInterface); @@ -457,11 +461,22 @@ public sealed override IEnumerable GetConditionalSt if (!isStaticInterfaceMethod && !needsDependenciesForInstanceInterfaceMethodImpls) continue; + MethodDesc interfaceMethodDefinition = interfaceMethod; + if (interfaceType != interfaceDefinitionType) + interfaceMethodDefinition = factory.TypeSystemContext.GetMethodForInstantiatedType(interfaceMethodDefinition.GetTypicalMethodDefinition(), (InstantiatedType)interfaceDefinitionType); + MethodDesc implMethod = isStaticInterfaceMethod ? - defType.ResolveInterfaceMethodToStaticVirtualMethodOnType(interfaceMethod) : - defType.ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod); + defTypeDefinition.ResolveInterfaceMethodToStaticVirtualMethodOnType(interfaceMethodDefinition) : + defTypeDefinition.ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethodDefinition); if (implMethod != null) { + TypeDesc implType = defType; + while (!implType.HasSameTypeDefinition(implMethod.OwningType)) + implType = implType.BaseType; + + if (!implType.IsTypeDefinition) + implMethod = factory.TypeSystemContext.GetMethodForInstantiatedType(implMethod.GetTypicalMethodDefinition(), (InstantiatedType)implType); + if (isStaticInterfaceMethod) { Debug.Assert(!implMethod.IsVirtual); @@ -500,12 +515,7 @@ public sealed override IEnumerable GetConditionalSt // Is the implementation provided by a default interface method? // If so, add a dependency on the entrypoint directly since nobody else is going to do that // (interface types have an empty vtable, modulo their generic dictionary). - TypeDesc interfaceOnDefinition = defType.GetTypeDefinition().RuntimeInterfaces[interfaceIndex]; - MethodDesc interfaceMethodDefinition = interfaceMethod; - if (!interfaceType.IsTypeDefinition) - interfaceMethodDefinition = factory.TypeSystemContext.GetMethodForInstantiatedType(interfaceMethod.GetTypicalMethodDefinition(), (InstantiatedType)interfaceOnDefinition); - - var resolution = defType.GetTypeDefinition().ResolveInterfaceMethodToDefaultImplementationOnType(interfaceMethodDefinition, out implMethod); + var resolution = defTypeDefinition.ResolveInterfaceMethodToDefaultImplementationOnType(interfaceMethodDefinition, out implMethod); if (resolution == DefaultInterfaceMethodResolution.DefaultImplementation) { DefType providingInterfaceDefinitionType = (DefType)implMethod.OwningType; diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/NegativeTestCases/MethodBodyOnUnrelatedType.ilproj b/src/tests/Loader/classloader/StaticVirtualMethods/NegativeTestCases/MethodBodyOnUnrelatedType.ilproj index 397521a4d40047..294b3c3a66827e 100644 --- a/src/tests/Loader/classloader/StaticVirtualMethods/NegativeTestCases/MethodBodyOnUnrelatedType.ilproj +++ b/src/tests/Loader/classloader/StaticVirtualMethods/NegativeTestCases/MethodBodyOnUnrelatedType.ilproj @@ -4,6 +4,9 @@ false + + + true Full diff --git a/src/tests/nativeaot/SmokeTests/UnitTests/Interfaces.cs b/src/tests/nativeaot/SmokeTests/UnitTests/Interfaces.cs index 7ad4f974bbb09c..e4b7f437382360 100644 --- a/src/tests/nativeaot/SmokeTests/UnitTests/Interfaces.cs +++ b/src/tests/nativeaot/SmokeTests/UnitTests/Interfaces.cs @@ -40,6 +40,7 @@ public static int Run() TestDefaultInterfaceVariance.Run(); TestVariantInterfaceOptimizations.Run(); TestSharedInterfaceMethods.Run(); + TestGenericAnalysis.Run(); TestCovariantReturns.Run(); TestDynamicInterfaceCastable.Run(); TestStaticInterfaceMethodsAnalysis.Run(); @@ -653,6 +654,54 @@ public static void Run() } } + class TestGenericAnalysis + { + interface IInterface + { + string Method(object p); + } + + interface IInterface + { + string Method(T p); + } + + class C1 : IInterface, IInterface + { + public string Method(object p) => "Method(object)"; + public string Method(T p) => "Method(T)"; + } + + class C2 : IInterface, IInterface + { + public string Method(object p) => "Method(object)"; + public string Method(T p) => "Method(T)"; + } + + class C3 : IInterface, IInterface + { + public string Method(object p) => "Method(object)"; + public string Method(T p) => "Method(T)"; + } + + static IInterface s_c1 = new C1(); + static IInterface s_c2 = new C2(); + static IInterface s_c3a = new C3(); + static IInterface s_c3b = new C3(); + + public static void Run() + { + if (s_c1.Method(null) != "Method(object)") + throw new Exception(); + if (s_c2.Method(null) != "Method(T)") + throw new Exception(); + if (s_c3a.Method(null) != "Method(T)") + throw new Exception(); + if (s_c3b.Method(null) != "Method(object)") + throw new Exception(); + } + } + class TestCovariantReturns { interface IFoo From 754d8f8de726232d268f9016f874bd59eef96196 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:24:34 -0700 Subject: [PATCH 412/783] Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231019.5 (#93776) optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23515.2 -> To Version 1.0.0-prerelease.23519.5 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index fd1357fb1b844a..e9087374ba0cf9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -334,21 +334,21 @@ https://github.com/dotnet/arcade 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 0e20c85562e8c4615c2a3a9e28371a34d9d0a398 + a7b602f57c5792b579accd3a70af16a231a62027 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 0e20c85562e8c4615c2a3a9e28371a34d9d0a398 + a7b602f57c5792b579accd3a70af16a231a62027 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 0e20c85562e8c4615c2a3a9e28371a34d9d0a398 + a7b602f57c5792b579accd3a70af16a231a62027 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 0e20c85562e8c4615c2a3a9e28371a34d9d0a398 + a7b602f57c5792b579accd3a70af16a231a62027 https://github.com/dotnet/hotreload-utils @@ -384,13 +384,13 @@ d10b02ae5cc670609d920a672985ed4456bdd6b6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 0e20c85562e8c4615c2a3a9e28371a34d9d0a398 + a7b602f57c5792b579accd3a70af16a231a62027 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 0e20c85562e8c4615c2a3a9e28371a34d9d0a398 + a7b602f57c5792b579accd3a70af16a231a62027 diff --git a/eng/Versions.props b/eng/Versions.props index 19e6a5891d30b2..189fb6671d44b9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23515.2 - 1.0.0-prerelease.23515.2 - 1.0.0-prerelease.23515.2 - 1.0.0-prerelease.23515.2 - 1.0.0-prerelease.23515.2 - 1.0.0-prerelease.23515.2 + 1.0.0-prerelease.23519.5 + 1.0.0-prerelease.23519.5 + 1.0.0-prerelease.23519.5 + 1.0.0-prerelease.23519.5 + 1.0.0-prerelease.23519.5 + 1.0.0-prerelease.23519.5 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From cea93b5c5070a192dd5c40217c45f8669f887a36 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:25:28 -0700 Subject: [PATCH 413/783] Fix options source gen test (#93782) Co-authored-by: Tarek Mahmoud Sayed --- .../tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs index d9bd0808cf77f6..4c701e4b9f498f 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Globalization; using System.Linq; using System.Threading.Tasks; using Xunit; @@ -361,7 +362,7 @@ public void TestCustomGeneratedAttributes() Assert.Equal(new [] { #if NET8_0_OR_GREATER "P0: The field OptionsUsingGeneratedAttributes.P0 must be a string or collection type with a minimum length of '1' and maximum length of '3'.", - "P11: The field OptionsUsingGeneratedAttributes.P11 must be between 1/30/2023 12:00:00 AM and 12/30/2023 12:00:00 AM.", + string.Format(CultureInfo.CurrentCulture, "P11: The field OptionsUsingGeneratedAttributes.P11 must be between {0} and {1}.", new DateTime(2023, 1, 30), new DateTime(2023, 12, 30)), "P12: The field OptionsUsingGeneratedAttributes.P12 must be between 5 exclusive and 10.", "P13: The field OptionsUsingGeneratedAttributes.P13 must be between 5 and 10 exclusive.", "P14: The field OptionsUsingGeneratedAttributes.P14 must be a string or collection type with a minimum length of '2' and maximum length of '10'.", From 4135a754f13af1c1e172c8f7ab11af1329d7ade1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:58:53 -0700 Subject: [PATCH 414/783] [release/8.0] [iOS][non-icu] HybridGlobalization Get available locales (#93751) * Get available locales hybrid mode * Fix the exception when value is empty * Apply changes requested by review,fix currencyCode * Add test case * Add braces and fix order in csproj --------- Co-authored-by: Meri Khamoyan --- .../Common/src/Interop/Interop.Locale.iOS.cs | 3 + .../CultureInfo/CultureInfoGetCultures.cs | 25 ++++ .../System.Globalization.IOS.Tests.csproj | 1 + .../System/Globalization/CultureData.Icu.cs | 25 +++- .../System.Globalization.Native/entrypoints.c | 1 + .../System.Globalization.Native/pal_locale.h | 2 + .../System.Globalization.Native/pal_locale.m | 119 ++++++++++++------ 7 files changed, 138 insertions(+), 38 deletions(-) create mode 100644 src/libraries/System.Globalization/tests/CultureInfo/CultureInfoGetCultures.cs diff --git a/src/libraries/Common/src/Interop/Interop.Locale.iOS.cs b/src/libraries/Common/src/Interop/Interop.Locale.iOS.cs index 0f7b1763d58509..6725436b4f0945 100644 --- a/src/libraries/Common/src/Interop/Interop.Locale.iOS.cs +++ b/src/libraries/Common/src/Interop/Interop.Locale.iOS.cs @@ -24,5 +24,8 @@ internal static partial class Globalization [LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLocaleTimeFormatNative", StringMarshalling = StringMarshalling.Utf8)] internal static partial string GetLocaleTimeFormatNative(string localeName, [MarshalAs(UnmanagedType.Bool)] bool shortFormat); + + [LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLocalesNative", StringMarshalling = StringMarshalling.Utf16)] + internal static partial int GetLocalesNative([Out] char[]? value, int valueLength); } } diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoGetCultures.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoGetCultures.cs new file mode 100644 index 00000000000000..5dcdfb54c1f835 --- /dev/null +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoGetCultures.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Globalization.Tests +{ + public class CultureInfoGetCultures + { + [Fact] + public void GetSpecificCultures() + { + var specificCultures = CultureInfo.GetCultures(CultureTypes.SpecificCultures); + Assert.True(specificCultures.Length > 0); + Assert.All(specificCultures, c => Assert.True(c.IsNeutralCulture == false)); + } + + [Fact] + public void GetAllCultures() + { + var allCultures = CultureInfo.GetCultures(CultureTypes.AllCultures); + Assert.True(allCultures.Length > 0); + } + } +} diff --git a/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.IOS.Tests.csproj b/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.IOS.Tests.csproj index eac50b0d2f3e0f..bb38f00b88f9d8 100644 --- a/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.IOS.Tests.csproj +++ b/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.IOS.Tests.csproj @@ -6,6 +6,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs index 0d4dad112249ca..12af791d392e24 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs @@ -420,7 +420,19 @@ private static CultureInfo[] IcuEnumCultures(CultureTypes types) return Array.Empty(); } - int bufferLength = Interop.Globalization.GetLocales(null, 0); + int bufferLength; +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS + if (GlobalizationMode.Hybrid) + { + bufferLength = Interop.Globalization.GetLocalesNative(null, 0); + } + else + { + bufferLength = Interop.Globalization.GetLocales(null, 0); + } +#else + bufferLength = Interop.Globalization.GetLocales(null, 0); +#endif if (bufferLength <= 0) { return Array.Empty(); @@ -428,7 +440,18 @@ private static CultureInfo[] IcuEnumCultures(CultureTypes types) char [] chars = new char[bufferLength]; +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS + if (GlobalizationMode.Hybrid) + { + bufferLength = Interop.Globalization.GetLocalesNative(chars, bufferLength); + } + else + { + bufferLength = Interop.Globalization.GetLocales(chars, bufferLength); + } +#else bufferLength = Interop.Globalization.GetLocales(chars, bufferLength); +#endif if (bufferLength <= 0) { return Array.Empty(); diff --git a/src/native/libs/System.Globalization.Native/entrypoints.c b/src/native/libs/System.Globalization.Native/entrypoints.c index cffad72a023721..84d2177d558841 100644 --- a/src/native/libs/System.Globalization.Native/entrypoints.c +++ b/src/native/libs/System.Globalization.Native/entrypoints.c @@ -69,6 +69,7 @@ static const Entry s_globalizationNative[] = DllImportEntry(GlobalizationNative_GetLocaleInfoSecondaryGroupingSizeNative) DllImportEntry(GlobalizationNative_GetLocaleInfoStringNative) DllImportEntry(GlobalizationNative_GetLocaleNameNative) + DllImportEntry(GlobalizationNative_GetLocalesNative) DllImportEntry(GlobalizationNative_GetLocaleTimeFormatNative) DllImportEntry(GlobalizationNative_IndexOfNative) DllImportEntry(GlobalizationNative_StartsWithNative) diff --git a/src/native/libs/System.Globalization.Native/pal_locale.h b/src/native/libs/System.Globalization.Native/pal_locale.h index 7fe89f667f2132..4a1fe0768e4fda 100644 --- a/src/native/libs/System.Globalization.Native/pal_locale.h +++ b/src/native/libs/System.Globalization.Native/pal_locale.h @@ -21,4 +21,6 @@ PALEXPORT int32_t GlobalizationNative_GetLocaleTimeFormat(const UChar* localeNam PALEXPORT const char* GlobalizationNative_GetLocaleNameNative(const char* localeName); PALEXPORT const char* GlobalizationNative_GetLocaleTimeFormatNative(const char* localeName, int shortFormat); + +PALEXPORT int32_t GlobalizationNative_GetLocalesNative(UChar* locales, int32_t length); #endif diff --git a/src/native/libs/System.Globalization.Native/pal_locale.m b/src/native/libs/System.Globalization.Native/pal_locale.m index d8ab7da1fbee0c..4789ac89691da2 100644 --- a/src/native/libs/System.Globalization.Native/pal_locale.m +++ b/src/native/libs/System.Globalization.Native/pal_locale.m @@ -97,7 +97,7 @@ static void GetParent(const char* localeID, char* parent, int32_t parentCapacity { @autoreleasepool { - const char* value; + NSString *value; NSString *locName = [NSString stringWithFormat:@"%s", localeName]; NSLocale *currentLocale = [[NSLocale alloc] initWithLocaleIdentifier:locName]; NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; @@ -112,35 +112,35 @@ static void GetParent(const char* localeID, char* parent, int32_t parentCapacity case LocaleString_LocalizedDisplayName: /// Display name (language + country usually) in English, eg "German (Germany)" (corresponds to LOCALE_SENGLISHDISPLAYNAME) case LocaleString_EnglishDisplayName: - value = [[gbLocale displayNameForKey:NSLocaleIdentifier value:currentLocale.localeIdentifier] UTF8String]; - break; + value = [gbLocale displayNameForKey:NSLocaleIdentifier value:currentLocale.localeIdentifier]; + break; /// Display name in native locale language, eg "Deutsch (Deutschland) (corresponds to LOCALE_SNATIVEDISPLAYNAME) case LocaleString_NativeDisplayName: - value = [[currentLocale displayNameForKey:NSLocaleIdentifier value:currentLocale.localeIdentifier] UTF8String]; + value = [currentLocale displayNameForKey:NSLocaleIdentifier value:currentLocale.localeIdentifier]; break; /// Language Display Name for a language, eg "German" in UI language (corresponds to LOCALE_SLOCALIZEDLANGUAGENAME) case LocaleString_LocalizedLanguageName: /// English name of language, eg "German" (corresponds to LOCALE_SENGLISHLANGUAGENAME) case LocaleString_EnglishLanguageName: - value = [[gbLocale localizedStringForLanguageCode:currentLocale.languageCode] UTF8String]; + value = [gbLocale localizedStringForLanguageCode:currentLocale.languageCode]; break; /// native name of language, eg "Deutsch" (corresponds to LOCALE_SNATIVELANGUAGENAME) case LocaleString_NativeLanguageName: - value = [[currentLocale localizedStringForLanguageCode:currentLocale.languageCode] UTF8String]; + value = [currentLocale localizedStringForLanguageCode:currentLocale.languageCode]; break; /// English name of country, eg "Germany" (corresponds to LOCALE_SENGLISHCOUNTRYNAME) case LocaleString_EnglishCountryName: - value = [[gbLocale localizedStringForCountryCode:currentLocale.countryCode] UTF8String]; + value = [gbLocale localizedStringForCountryCode:currentLocale.countryCode]; break; /// native name of country, eg "Deutschland" (corresponds to LOCALE_SNATIVECOUNTRYNAME) case LocaleString_NativeCountryName: - value = [[currentLocale localizedStringForCountryCode:currentLocale.countryCode] UTF8String]; + value = [currentLocale localizedStringForCountryCode:currentLocale.countryCode]; break; case LocaleString_ThousandSeparator: - value = [currentLocale.groupingSeparator UTF8String]; + value = currentLocale.groupingSeparator; break; case LocaleString_DecimalSeparator: - value = [currentLocale.decimalSeparator UTF8String]; + value = currentLocale.decimalSeparator; // or value = [[currentLocale objectForKey:NSLocaleDecimalSeparator] UTF8String]; break; case LocaleString_Digits: @@ -150,87 +150,84 @@ static void GetParent(const char* localeID, char* parent, int32_t parentCapacity [nf1 setLocale:currentLocale]; NSNumber *newNum = [nf1 numberFromString:digitsString]; - value = [[newNum stringValue] UTF8String]; + value = [newNum stringValue]; break; } case LocaleString_MonetarySymbol: - value = [currentLocale.currencySymbol UTF8String]; + value = currentLocale.currencySymbol; break; case LocaleString_Iso4217MonetarySymbol: // check if this is correct, check currencyISOCode - value = [currentLocale.currencySymbol UTF8String]; + value = currentLocale.currencyCode; break; case LocaleString_CurrencyEnglishName: - value = [[gbLocale localizedStringForCurrencyCode:currentLocale.currencyCode] UTF8String]; + value = [gbLocale localizedStringForCurrencyCode:currentLocale.currencyCode]; break; case LocaleString_CurrencyNativeName: - value = [[currentLocale localizedStringForCurrencyCode:currentLocale.currencyCode] UTF8String]; + value = [currentLocale localizedStringForCurrencyCode:currentLocale.currencyCode]; break; case LocaleString_MonetaryDecimalSeparator: - value = [numberFormatter.currencyDecimalSeparator UTF8String]; + value = numberFormatter.currencyDecimalSeparator; break; case LocaleString_MonetaryThousandSeparator: - value = [numberFormatter.currencyGroupingSeparator UTF8String]; + value = numberFormatter.currencyGroupingSeparator; break; case LocaleString_AMDesignator: - value = [dateFormatter.AMSymbol UTF8String]; + value = dateFormatter.AMSymbol; break; case LocaleString_PMDesignator: - value = [dateFormatter.PMSymbol UTF8String]; + value = dateFormatter.PMSymbol; break; case LocaleString_PositiveSign: - value = [numberFormatter.plusSign UTF8String]; + value = numberFormatter.plusSign; break; case LocaleString_NegativeSign: - value = [numberFormatter.minusSign UTF8String]; + value = numberFormatter.minusSign; break; case LocaleString_Iso639LanguageTwoLetterName: - value = [[currentLocale objectForKey:NSLocaleLanguageCode] UTF8String]; + value = [currentLocale objectForKey:NSLocaleLanguageCode]; break; case LocaleString_Iso639LanguageThreeLetterName: { NSString *iso639_2 = [currentLocale objectForKey:NSLocaleLanguageCode]; - value = uloc_getISO3LanguageByLangCode([iso639_2 UTF8String]); - break; + return iso639_2 == nil ? strdup("") : strdup(uloc_getISO3LanguageByLangCode([iso639_2 UTF8String])); } case LocaleString_Iso3166CountryName: - value = [[currentLocale objectForKey:NSLocaleCountryCode] UTF8String]; + value = [currentLocale objectForKey:NSLocaleCountryCode]; break; case LocaleString_Iso3166CountryName2: { - const char *countryCode = strdup([[currentLocale objectForKey:NSLocaleCountryCode] UTF8String]); - value = uloc_getISO3CountryByCountryCode(countryCode); - break; + NSString* countryCode = [currentLocale objectForKey:NSLocaleCountryCode]; + return countryCode == nil ? strdup("") : strdup(uloc_getISO3CountryByCountryCode([countryCode UTF8String])); } case LocaleString_NaNSymbol: - value = [numberFormatter.notANumberSymbol UTF8String]; + value = numberFormatter.notANumberSymbol; break; case LocaleString_PositiveInfinitySymbol: - value = [numberFormatter.positiveInfinitySymbol UTF8String]; + value = numberFormatter.positiveInfinitySymbol; break; case LocaleString_NegativeInfinitySymbol: - value = [numberFormatter.negativeInfinitySymbol UTF8String]; + value = numberFormatter.negativeInfinitySymbol; break; case LocaleString_PercentSymbol: - value = [numberFormatter.percentSymbol UTF8String]; + value = numberFormatter.percentSymbol; break; case LocaleString_PerMilleSymbol: - value = [numberFormatter.perMillSymbol UTF8String]; + value = numberFormatter.perMillSymbol; break; case LocaleString_ParentName: { char localeNameTemp[FULLNAME_CAPACITY]; const char* lName = [currentLocale.localeIdentifier UTF8String]; GetParent(lName, localeNameTemp, FULLNAME_CAPACITY); - value = strdup(localeNameTemp); - break; + return strdup(localeNameTemp); } default: - value = ""; + value = nil; break; } - return value ? strdup(value) : ""; + return value == nil ? strdup("") : strdup([value UTF8String]); } } @@ -667,6 +664,54 @@ Returns time format information (in native format, it needs to be converted to . } } +// GlobalizationNative_GetLocalesNative gets all locale names and store it in the value buffer +// in case of success, it returns the count of the characters stored in value buffer +// in case of failure, it returns negative number. +// if the input value buffer is null, it returns the length needed to store the +// locale names list. +// if the value is not null, it fills the value with locale names separated by the length +// of each name. +int32_t GlobalizationNative_GetLocalesNative(UChar* value, int32_t length) +{ + @autoreleasepool + { + NSArray* availableLocaleIdentifiers = [NSLocale availableLocaleIdentifiers]; + int32_t index = 0; + int32_t totalLength = 0; + int32_t availableLength = (int32_t)[availableLocaleIdentifiers count]; + + if (availableLength <= 0) + return -1; // failed + + for (NSInteger i = 0; i < availableLength; i++) + { + NSString *localeIdentifier = availableLocaleIdentifiers[i]; + int32_t localeNameLength = localeIdentifier.length; + totalLength += localeNameLength + 1; // add 1 for the name length + if (value != NULL) + { + if (totalLength > length) + return -3; + + value[index++] = (UChar) localeNameLength; + + for (int j = 0; j < localeNameLength; j++) + { + if ((UChar)[localeIdentifier characterAtIndex:j] == '_') + { + value[index++] = (UChar) '-'; + } + else + { + value[index++] = (UChar) [localeIdentifier characterAtIndex:j]; + } + } + } + } + return totalLength; + } +} + #endif #if defined(TARGET_MACCATALYST) || defined(TARGET_IOS) || defined(TARGET_TVOS) From 9255cc64dde40a50723ce9210a1f483fbbabf94a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 16:00:17 -0700 Subject: [PATCH 415/783] [release/8.0] Update dependencies from dotnet/sdk (#93783) * Update dependencies from https://github.com/dotnet/sdk build 20231020.8 Microsoft.DotNet.ApiCompat.Task From Version 8.0.100-preview.7.23329.3 -> To Version 8.0.100-rtm.23520.8 * Update CompatibilitySuppressions.xml * Update ApiCompatBaseline.netstandard2.0.xml * Update ApiCompatBaseline.netstandard2.1.xml * Suppress intentional ObsoleteAttribute parameter change --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Viktor Hofer --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- .../src/CompatibilitySuppressions.xml | 8 +++++++ .../src/CompatibilitySuppressions.xml | 21 +++++++++++++++++++ .../ApiCompatBaseline.netstandard2.0.xml | 14 ++++++++++++- .../ApiCompatBaseline.netstandard2.1.xml | 8 ++++++- 6 files changed, 52 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e9087374ba0cf9..930b2a0a404201 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -379,9 +379,9 @@ https://github.com/dotnet/roslyn-analyzers 4ff28092cdb2006c30869fb35b2fd6b7b11382b1 - + https://github.com/dotnet/sdk - d10b02ae5cc670609d920a672985ed4456bdd6b6 + 7e33fd449381b337c290a801057fdcd68c4b7220 diff --git a/eng/Versions.props b/eng/Versions.props index 189fb6671d44b9..c9ccb7ba58fc5a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -85,7 +85,7 @@ 0.2.0 - 8.0.100-preview.7.23329.3 + 8.0.100-rtm.23520.8 8.0.0-beta.23516.4 8.0.0-beta.23516.4 diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml index d5fbde8e348dc3..229085a10afaa0 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml @@ -800,6 +800,10 @@ CP0001 T:System.Diagnostics.DebugAnnotations + + CP0001 + T:System.Diagnostics.DebuggerGuidedStepThroughAttribute + CP0001 T:System.MDArray @@ -864,6 +868,10 @@ CP0001 T:System.Reflection.RuntimeAssemblyName + + CP0001 + T:System.Runtime.CompilerServices.EagerStaticClassConstructionAttribute + CP0001 T:System.Runtime.CompilerServices.ForceDictionaryLookupsAttribute diff --git a/src/libraries/System.Security.Permissions/src/CompatibilitySuppressions.xml b/src/libraries/System.Security.Permissions/src/CompatibilitySuppressions.xml index 10869bf91f9227..5ff9a82feffe7d 100644 --- a/src/libraries/System.Security.Permissions/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Security.Permissions/src/CompatibilitySuppressions.xml @@ -218,6 +218,27 @@ lib/netstandard2.0/System.Security.Permissions.dll true + + CP0014 + P:System.Security.Permissions.FileIOPermissionAttribute.All:[T:System.ObsoleteAttribute] + lib/netstandard2.0/System.Security.Permissions.dll + lib/netstandard2.0/System.Security.Permissions.dll + true + + + CP0014 + P:System.Security.Permissions.ReflectionPermissionAttribute.ReflectionEmit:[T:System.ObsoleteAttribute] + lib/netstandard2.0/System.Security.Permissions.dll + lib/netstandard2.0/System.Security.Permissions.dll + true + + + CP0014 + P:System.Security.Permissions.ReflectionPermissionAttribute.TypeInformation:[T:System.ObsoleteAttribute] + lib/netstandard2.0/System.Security.Permissions.dll + lib/netstandard2.0/System.Security.Permissions.dll + true + CP0014 P:System.Security.Permissions.RegistryPermissionAttribute.All:[T:System.ObsoleteAttribute] diff --git a/src/libraries/apicompat/ApiCompatBaseline.netstandard2.0.xml b/src/libraries/apicompat/ApiCompatBaseline.netstandard2.0.xml index f19da8b94090d0..12fce752d1b3d7 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.netstandard2.0.xml +++ b/src/libraries/apicompat/ApiCompatBaseline.netstandard2.0.xml @@ -2773,10 +2773,22 @@ netstandard2.0/netstandard.dll net8.0/netstandard.dll + + CP0015 + T:System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute:[T:System.AttributeUsageAttribute] + netstandard2.0/netstandard.dll + net8.0/netstandard.dll + CP0015 P:System.Timers.Timer.Interval:[T:System.ComponentModel.DefaultValueAttribute] netstandard2.0/System.dll net8.0/System.dll - \ No newline at end of file + + CP0015 + T:System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute:[T:System.AttributeUsageAttribute] + netstandard2.0/System.dll + net8.0/System.dll + + diff --git a/src/libraries/apicompat/ApiCompatBaseline.netstandard2.1.xml b/src/libraries/apicompat/ApiCompatBaseline.netstandard2.1.xml index de4ff50c7dc0ed..a6009206387156 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.netstandard2.1.xml +++ b/src/libraries/apicompat/ApiCompatBaseline.netstandard2.1.xml @@ -853,6 +853,12 @@ netstandard2.1/netstandard.dll net8.0/netstandard.dll + + CP0015 + T:System.Runtime.CompilerServices.AsyncMethodBuilderAttribute:[T:System.AttributeUsageAttribute] + netstandard2.1/netstandard.dll + net8.0/netstandard.dll + CP0015 T:System.Runtime.InteropServices.ManagedToNativeComInteropStubAttribute:[T:System.AttributeUsageAttribute] @@ -871,4 +877,4 @@ netstandard2.1/netstandard.dll net8.0/netstandard.dll - \ No newline at end of file + From 8262af28e6429f057710a36755e48b937a67df35 Mon Sep 17 00:00:00 2001 From: Michael Sharp <51342856+michaelgsharp@users.noreply.github.com> Date: Fri, 20 Oct 2023 16:01:42 -0700 Subject: [PATCH 416/783] [release/8.0] Vectorize TensorPrimitives APIs (#93746) * Use FMA in TensorPrimitives (#92205) * Simplify TensorPrimitive's AbsoluteOperator (#92577) Vector{128/256/512} all provide Abs; no need to do this manually. * Reduce some boilerplate in TensorPrimitive's IBinaryOperator (#92576) Change a few of the static abstract interface methods to be virtual, as most implementations throw from these methods; we can consolidate that throwing to the base. * Minor code cleanup in TensorPrimitives tests (#92575) * Normalize some test naming * Alphabetize tests * Improve mistmatched length tests with all positions of the shorter tensor * Alphabetize methods in TensorPrimitives.cs * Vectorize TensorPrimitives.Min/Max{Magnitude} (#92618) * Vectorize TensorPrimitives.Min/Max{Magnitude} * Use AdvSimd.Max/Min * Rename some parameters/locals for consistency * Improve HorizontalAggregate * Move a few helpers * Avoid scalar path for returning found NaN * Update TensorPrimitives aggregations to vectorize handling of remaining elements (#92672) * Update TensorPrimitives.CosineSimilarity to vectorize handling of remaining elements * Vectorize remainder handling for Aggregate helpers * Flesh out TensorPrimitives XML docs (#92749) * Flesh out TensorPrimitives XML docs * Address PR feedback - Remove use of FusedMultiplyAdd from all but CosineSimilarity - Remove comments about platform/OS-specific behavior from Add/AddMultiply/Subtract/Multiply/MultiplyAdd/Divide/Negate - Loosen comments about NaN and which exact one is returned * Address PR feedback * Vectorize TensorPrimitives.ConvertToHalf (#92715) * Enable TensorPrimitives to perform in-place operations (#92820) Some operations would produce incorrect results if the same span was passed as both an input and an output. When vectorization was employed but the span's length wasn't a perfect multiple of a vector, we'd do the standard trick of performing one last operation on the last vector's worth of data; however, that relies on the operation being idempotent, and if a previous operation has overwritten input with a new value due to the same memory being used for input and output, some operations won't be idempotent. This fixes that by masking off the already processed elements. It adds tests to validate in-place use works, and it updates the docs to carve out this valid overlapping. * Vectorize TensorPrimitives.ConvertToSingle (#92779) * Vectorize TensorPrimitives.ConvertToSingle * Address PR feedback * Throw exception in TensorPrimitives for unsupported span overlaps (#92838) * This vectorizes TensorPrimitives.Log2 (#92897) * Add a way to support operations that can't be vectorized on netstandard * Updating TensorPrimitives.Log2 to be vectorized on .NET Core * Update src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs Co-authored-by: Stephen Toub * Ensure we do an arithmetic right shift in the Log2 vectorization * Ensure the code can compile on .NET 7 * Ensure that edge cases are properly handled and don't resolve to `x` * Ensure that Log2 special results are explicitly handled. --------- Co-authored-by: Stephen Toub * Adding Log2 tests covering some special values (#92946) * [wasm] Disable `TensorPrimitivesTests.ConvertToHalf_SpecialValues` (#92953) Failing test: `System.Numerics.Tensors.Tests.TensorPrimitivesTests.ConvertToHalf_SpecialValues` Issue: https://github.com/dotnet/runtime/issues/92885 * Adding a vectorized implementation of TensorPrimitives.Log (#92960) * Adding a vectorized implementation of TensorPrimitives.Log * Make sure to hit Ctrl+S * Consolidate some TensorPrimitivesTests logic around special values (#92982) * Vectorize TensorPrimitives.Exp (#93018) * Vectorize TensorPrimitives.Exp * Update src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs * Vectorize TensorPrimitives.Sigmoid and TensorPrimitives.SoftMax (#93029) * Vectorize TensorPrimitives.Sigmoid and TensorPrimitives.SoftMax - Adds a SigmoidOperator that just wraps the ExpOperator - Vectorizes both passes of SoftMax, on top of ExpOperator. Simplest way to do this was to augment the existing InvokeSpanScalarIntoSpan to take a transform operator. - In doing so, found some naming inconsistencies I'd previously introduced, so I did some automatic renaming to make things more consistent. - Added XML comments to all the internal/private surface area. - Fleshes out some tests (and test values). * Disable tests on mono * Address PR feedback * Vectorize TensorPrimitives.Tanh/Cosh/Sinh (#93093) * Vectorize TensorPrimitives.Tanh/Cosh/Sinh Tanh and Cosh are based on AOCL-LibM. AOCL-LibM doesn't appear to have a sinh implementation, so this Sinh is just based on the sinh formula based on exp(x). I also augmented the tests further, including: - Added more tests for sinh/cosh/tanh - Add an equality routine that supports comparing larger values with a tolerance - Tightened the tolerance for most functions - Changed some tests to be theories to be consistent with style elsewhere in the tests - Fixed some use of Math to be MathF * Remove unnecessary special-handling path from cosh * Remove unnecessary special-handling path from tanh * Redo sinh based on cosh * Address PR feedback * Replace confusing new T[] { ... } * Remove a few unnecessary `unsafe` keyword uses in TensorPrimitives (#93219) * Consolidate a few exception throws in TensorPrimitives (#93168) * Fix TensorPrimitives.IndexOfXx corner-case when first element is seed value (#93169) * Fix TensorPrimitives.IndexOfXx corner-case when first element is seed value Found as part of adding more tests for Min/Max{Magnitude} to validate they match their IndexOfXx variants. * Address PR feedback * Improve a vector implementation to support alignment and non-temporal tores (#93296) * Improve a vector implementation to support alignment and non-temporal stores * Fix a build error and mark a couple methods as AggressiveInlining * Fix the remaining block count computation * Ensure overlapping for small data on the V256/512 is handled * Ensure we only go down the vectorized path when supported for netstandard * Mark TensorPrimitives as unsafe (#93412) * Use the improved vectorization algorithm for binary and ternary TensorPrimitives operations (#93409) * Update InvokeSpanSpanIntoSpan for TensorPrimitives to use the better SIMD algorithm * Update InvokeSpanScalarIntoSpan for TensorPrimitives to use the better SIMD algorithm * Update InvokeSpanSpanSpanIntoSpan for TensorPrimitives to use the better SIMD algorithm * Update InvokeSpanSpanScalarIntoSpan for TensorPrimitives to use the better SIMD algorithm * Update InvokeSpanScalarSpanIntoSpan for TensorPrimitives to use the better SIMD algorithm * Improve codegen slightly by using case 0, rather than default * Adjust the canAlign check to be latter, to reduce branch count for data under the threshold * Add a comment explaining the NonTemporalByteThreshold * Make sure xTransformOp.CanVectorize is checked on .NET Standard * Use the improved vectorization algorithm for aggregate TensorPrimitives operations (#93695) * Improve the handling of the IAggregationOperator implementations * Update Aggregate for TensorPrimitives to use the better SIMD algorithm * Update Aggregate for TensorPrimitives to use the better SIMD algorithm * Respond to PR feedback * [wasm] Remove more active issues for #92885 (#93596) * adding patch from pr 93556 * Vectorizes IndexOfMin/Max/Magnitude (#93469) * resolved merge conflicts * net core full done * minor code cleanup * NetStandard and PR fixes. * minor pr changes * Fix IndexOfMaxMagnitudeOperator * Fix IndexOfMaxMagnitudeOperator on netcore * updates from PR comments * netcore fixed * net standard updated * add reference assembly exclusions * made naive approach better * resolved PR comments * minor comment changes * minor formatting fixes * added inlining * fixes from PR comments * comments from pr * fixed spacing --------- Co-authored-by: Eric StJohn --------- Co-authored-by: Stephen Toub Co-authored-by: Tanner Gooding Co-authored-by: Ankit Jain Co-authored-by: Radek Doulik Co-authored-by: Eric StJohn --- .../System.Numerics.Tensors.sln | 81 +- .../src/ReferenceAssemblyExclusions.txt | 2 + .../src/Resources/Strings.resx | 5 +- .../src/System.Numerics.Tensors.csproj | 1 + .../Numerics/Tensors/TensorPrimitives.cs | 1644 ++- .../Tensors/TensorPrimitives.netcore.cs | 12088 ++++++++++++++-- .../Tensors/TensorPrimitives.netstandard.cs | 3664 ++++- .../src/System/ThrowHelper.cs | 4 + .../tests/TensorPrimitivesTests.cs | 2771 +++- .../tests/TensorPrimitivesTests.netcore.cs | 63 +- .../System.Private.CoreLib/src/System/Half.cs | 4 +- 11 files changed, 17580 insertions(+), 2747 deletions(-) create mode 100644 src/libraries/System.Numerics.Tensors/src/ReferenceAssemblyExclusions.txt diff --git a/src/libraries/System.Numerics.Tensors/System.Numerics.Tensors.sln b/src/libraries/System.Numerics.Tensors/System.Numerics.Tensors.sln index cc3000d60ef88f..015b65250931ac 100644 --- a/src/libraries/System.Numerics.Tensors/System.Numerics.Tensors.sln +++ b/src/libraries/System.Numerics.Tensors/System.Numerics.Tensors.sln @@ -1,18 +1,34 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34205.153 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{9F20CEA1-2216-4432-BBBD-F01E05D17F23}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bcl.Numerics", "..\Microsoft.Bcl.Numerics\ref\Microsoft.Bcl.Numerics.csproj", "{D311ABE4-10A9-4BB1-89CE-6358C55501A8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bcl.Numerics", "..\Microsoft.Bcl.Numerics\src\Microsoft.Bcl.Numerics.csproj", "{1578185F-C4FA-4866-936B-E62AAEDD03B7}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Numerics.Tensors", "ref\System.Numerics.Tensors.csproj", "{21CB448A-3882-4337-B416-D1A3E0BCFFC5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Numerics.Tensors", "src\System.Numerics.Tensors.csproj", "{848DD000-3D22-4A25-A9D9-05AFF857A116}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Numerics.Tensors.Tests", "tests\System.Numerics.Tensors.Tests.csproj", "{4AF6A02D-82C8-4898-9EDF-01F107C25061}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComInterfaceGenerator", "..\System.Runtime.InteropServices\gen\ComInterfaceGenerator\ComInterfaceGenerator.csproj", "{8CA7C982-3EE4-4BCE-9493-7A63556736D3}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibraryImportGenerator", "..\System.Runtime.InteropServices\gen\LibraryImportGenerator\LibraryImportGenerator.csproj", "{4588351F-4233-4957-B84C-7F8E22B8888A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Interop.SourceGeneration", "..\System.Runtime.InteropServices\gen\Microsoft.Interop.SourceGeneration\Microsoft.Interop.SourceGeneration.csproj", "{DB954E01-898A-4FE2-A3AA-180D041AB08F}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILLink.CodeFixProvider", "..\..\tools\illink\src\ILLink.CodeFix\ILLink.CodeFixProvider.csproj", "{04FC0651-B9D0-448A-A28B-11B1D4A897F4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILLink.RoslynAnalyzer", "..\..\tools\illink\src\ILLink.RoslynAnalyzer\ILLink.RoslynAnalyzer.csproj", "{683A7D28-CC55-4375-848D-E659075ECEE4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILLink.Tasks", "..\..\tools\illink\src\ILLink.Tasks\ILLink.Tasks.csproj", "{1CBEAEA8-2CA1-4B07-9930-35A785205852}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Linker", "..\..\tools\illink\src\linker\Mono.Linker.csproj", "{BA7828B1-7953-47A0-AE5A-E22B501C4BD0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Linker", "..\..\tools\illink\src\linker\ref\Mono.Linker.csproj", "{57E57290-3A6A-43F8-8764-D4DC8151F89C}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{DE94CA7D-BB10-4865-85A6-6B694631247F}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{6BC42E6D-848C-4533-B715-F116E7DB3610}" @@ -21,6 +37,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AB415F5A-75E EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gen", "gen", "{083161E5-6049-4D84-9739-9D7797D7117D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gen", "gen", "{841A2FA4-A95F-4612-A8B9-AD2EF769BC71}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{DF0561A1-3AB8-4B51-AFB4-392EE1DD6247}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{7AC4B2C7-A55C-4C4F-9B02-77F5CBFFF4AB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{F9C2AAB1-C7B0-4E43-BB18-4FB16F6E272B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -31,6 +55,14 @@ Global {9F20CEA1-2216-4432-BBBD-F01E05D17F23}.Debug|Any CPU.Build.0 = Debug|Any CPU {9F20CEA1-2216-4432-BBBD-F01E05D17F23}.Release|Any CPU.ActiveCfg = Release|Any CPU {9F20CEA1-2216-4432-BBBD-F01E05D17F23}.Release|Any CPU.Build.0 = Release|Any CPU + {D311ABE4-10A9-4BB1-89CE-6358C55501A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D311ABE4-10A9-4BB1-89CE-6358C55501A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D311ABE4-10A9-4BB1-89CE-6358C55501A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D311ABE4-10A9-4BB1-89CE-6358C55501A8}.Release|Any CPU.Build.0 = Release|Any CPU + {1578185F-C4FA-4866-936B-E62AAEDD03B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1578185F-C4FA-4866-936B-E62AAEDD03B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1578185F-C4FA-4866-936B-E62AAEDD03B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1578185F-C4FA-4866-936B-E62AAEDD03B7}.Release|Any CPU.Build.0 = Release|Any CPU {21CB448A-3882-4337-B416-D1A3E0BCFFC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {21CB448A-3882-4337-B416-D1A3E0BCFFC5}.Debug|Any CPU.Build.0 = Debug|Any CPU {21CB448A-3882-4337-B416-D1A3E0BCFFC5}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -43,10 +75,6 @@ Global {4AF6A02D-82C8-4898-9EDF-01F107C25061}.Debug|Any CPU.Build.0 = Debug|Any CPU {4AF6A02D-82C8-4898-9EDF-01F107C25061}.Release|Any CPU.ActiveCfg = Release|Any CPU {4AF6A02D-82C8-4898-9EDF-01F107C25061}.Release|Any CPU.Build.0 = Release|Any CPU - {8CA7C982-3EE4-4BCE-9493-7A63556736D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8CA7C982-3EE4-4BCE-9493-7A63556736D3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8CA7C982-3EE4-4BCE-9493-7A63556736D3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8CA7C982-3EE4-4BCE-9493-7A63556736D3}.Release|Any CPU.Build.0 = Release|Any CPU {4588351F-4233-4957-B84C-7F8E22B8888A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4588351F-4233-4957-B84C-7F8E22B8888A}.Debug|Any CPU.Build.0 = Debug|Any CPU {4588351F-4233-4957-B84C-7F8E22B8888A}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -55,20 +83,53 @@ Global {DB954E01-898A-4FE2-A3AA-180D041AB08F}.Debug|Any CPU.Build.0 = Debug|Any CPU {DB954E01-898A-4FE2-A3AA-180D041AB08F}.Release|Any CPU.ActiveCfg = Release|Any CPU {DB954E01-898A-4FE2-A3AA-180D041AB08F}.Release|Any CPU.Build.0 = Release|Any CPU + {04FC0651-B9D0-448A-A28B-11B1D4A897F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {04FC0651-B9D0-448A-A28B-11B1D4A897F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {04FC0651-B9D0-448A-A28B-11B1D4A897F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {04FC0651-B9D0-448A-A28B-11B1D4A897F4}.Release|Any CPU.Build.0 = Release|Any CPU + {683A7D28-CC55-4375-848D-E659075ECEE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {683A7D28-CC55-4375-848D-E659075ECEE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {683A7D28-CC55-4375-848D-E659075ECEE4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {683A7D28-CC55-4375-848D-E659075ECEE4}.Release|Any CPU.Build.0 = Release|Any CPU + {1CBEAEA8-2CA1-4B07-9930-35A785205852}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1CBEAEA8-2CA1-4B07-9930-35A785205852}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1CBEAEA8-2CA1-4B07-9930-35A785205852}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1CBEAEA8-2CA1-4B07-9930-35A785205852}.Release|Any CPU.Build.0 = Release|Any CPU + {BA7828B1-7953-47A0-AE5A-E22B501C4BD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA7828B1-7953-47A0-AE5A-E22B501C4BD0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA7828B1-7953-47A0-AE5A-E22B501C4BD0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA7828B1-7953-47A0-AE5A-E22B501C4BD0}.Release|Any CPU.Build.0 = Release|Any CPU + {57E57290-3A6A-43F8-8764-D4DC8151F89C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57E57290-3A6A-43F8-8764-D4DC8151F89C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57E57290-3A6A-43F8-8764-D4DC8151F89C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57E57290-3A6A-43F8-8764-D4DC8151F89C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {9F20CEA1-2216-4432-BBBD-F01E05D17F23} = {DE94CA7D-BB10-4865-85A6-6B694631247F} - {4AF6A02D-82C8-4898-9EDF-01F107C25061} = {DE94CA7D-BB10-4865-85A6-6B694631247F} + {D311ABE4-10A9-4BB1-89CE-6358C55501A8} = {6BC42E6D-848C-4533-B715-F116E7DB3610} + {1578185F-C4FA-4866-936B-E62AAEDD03B7} = {AB415F5A-75E5-4E03-8A92-15CEDEC4CD3A} {21CB448A-3882-4337-B416-D1A3E0BCFFC5} = {6BC42E6D-848C-4533-B715-F116E7DB3610} {848DD000-3D22-4A25-A9D9-05AFF857A116} = {AB415F5A-75E5-4E03-8A92-15CEDEC4CD3A} - {8CA7C982-3EE4-4BCE-9493-7A63556736D3} = {083161E5-6049-4D84-9739-9D7797D7117D} + {4AF6A02D-82C8-4898-9EDF-01F107C25061} = {DE94CA7D-BB10-4865-85A6-6B694631247F} {4588351F-4233-4957-B84C-7F8E22B8888A} = {083161E5-6049-4D84-9739-9D7797D7117D} {DB954E01-898A-4FE2-A3AA-180D041AB08F} = {083161E5-6049-4D84-9739-9D7797D7117D} + {04FC0651-B9D0-448A-A28B-11B1D4A897F4} = {841A2FA4-A95F-4612-A8B9-AD2EF769BC71} + {683A7D28-CC55-4375-848D-E659075ECEE4} = {841A2FA4-A95F-4612-A8B9-AD2EF769BC71} + {1CBEAEA8-2CA1-4B07-9930-35A785205852} = {DF0561A1-3AB8-4B51-AFB4-392EE1DD6247} + {BA7828B1-7953-47A0-AE5A-E22B501C4BD0} = {DF0561A1-3AB8-4B51-AFB4-392EE1DD6247} + {57E57290-3A6A-43F8-8764-D4DC8151F89C} = {7AC4B2C7-A55C-4C4F-9B02-77F5CBFFF4AB} + {841A2FA4-A95F-4612-A8B9-AD2EF769BC71} = {F9C2AAB1-C7B0-4E43-BB18-4FB16F6E272B} + {DF0561A1-3AB8-4B51-AFB4-392EE1DD6247} = {F9C2AAB1-C7B0-4E43-BB18-4FB16F6E272B} + {7AC4B2C7-A55C-4C4F-9B02-77F5CBFFF4AB} = {F9C2AAB1-C7B0-4E43-BB18-4FB16F6E272B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {10A5F2C3-5230-4916-9D4D-BBDB94851037} EndGlobalSection -EndGlobal + GlobalSection(SharedMSBuildProjectFiles) = preSolution + ..\..\tools\illink\src\ILLink.Shared\ILLink.Shared.projitems*{683a7d28-cc55-4375-848d-e659075ecee4}*SharedItemsImports = 5 + ..\..\tools\illink\src\ILLink.Shared\ILLink.Shared.projitems*{ba7828b1-7953-47a0-ae5a-e22b501c4bd0}*SharedItemsImports = 5 + EndGlobalSection +EndGlobal \ No newline at end of file diff --git a/src/libraries/System.Numerics.Tensors/src/ReferenceAssemblyExclusions.txt b/src/libraries/System.Numerics.Tensors/src/ReferenceAssemblyExclusions.txt new file mode 100644 index 00000000000000..a8f2d0192cfec9 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/ReferenceAssemblyExclusions.txt @@ -0,0 +1,2 @@ +M:System.Numerics.Tensors.TensorPrimitives.ConvertToHalf(System.ReadOnlySpan{System.Single},System.Span{System.Half}) +M:System.Numerics.Tensors.TensorPrimitives.ConvertToSingle(System.ReadOnlySpan{System.Half},System.Span{System.Single}) \ No newline at end of file diff --git a/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx b/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx index 45f0d8fa17893a..86b9f4d82b1f61 100644 --- a/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx +++ b/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx @@ -126,4 +126,7 @@ Input span arguments must all have the same length. - \ No newline at end of file + + The destination span may only overlap with an input span if the two spans start at the same memory location. + + diff --git a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj index be4a04702af5e1..52c6cb65811e68 100644 --- a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj @@ -9,6 +9,7 @@ Once this package has shipped a stable version, the following line should be removed in order to re-enable validation. --> true + ReferenceAssemblyExclusions.txt diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.cs index d28d4bacafdb8e..03db1abb7f858a 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.cs @@ -1,953 +1,1097 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + namespace System.Numerics.Tensors { /// Performs primitive tensor operations over spans of memory. public static partial class TensorPrimitives { - /// Computes the element-wise result of: + . + /// Computes the element-wise absolute value of each single-precision floating-point number in the specified tensor. + /// The tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = MathF.Abs([i]). + /// + /// + /// The absolute value of a is its numeric value without its sign. For example, the absolute value of both 1.2e-03 and -1.2e03 is 1.2e03. + /// + /// + /// If a value is equal to or , the result stored into the corresponding destination location is set to . + /// If a value is equal to , the result stored into the corresponding destination location is the original NaN value with the sign bit removed. + /// + /// + public static void Abs(ReadOnlySpan x, Span destination) => + InvokeSpanIntoSpan(x, destination); + + /// Computes the element-wise addition of single-precision floating-point numbers in the specified tensors. /// The first tensor, represented as a span. /// The second tensor, represented as a span. /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. + /// Length of must be same as length of . /// Destination is too short. - /// This method effectively does [i] = [i] + [i]. - public static unsafe void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) => + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = [i] + [i]. + /// + /// + /// If either of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// + /// + public static void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) => InvokeSpanSpanIntoSpan(x, y, destination); - /// Computes the element-wise result of: + . + /// Computes the element-wise addition of single-precision floating-point numbers in the specified tensors. /// The first tensor, represented as a span. /// The second tensor, represented as a scalar. /// The destination tensor, represented as a span. /// Destination is too short. - /// This method effectively does [i] = [i] + . + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = [i] + . + /// + /// + /// If either of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// + /// public static void Add(ReadOnlySpan x, float y, Span destination) => InvokeSpanScalarIntoSpan(x, y, destination); - /// Computes the element-wise result of: - . - /// The first tensor, represented as a span. - /// The second tensor, represented as a scalar. - /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. - /// Destination is too short. - /// This method effectively does [i] = [i] - [i]. - public static void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) => - InvokeSpanSpanIntoSpan(x, y, destination); - - /// Computes the element-wise result of: - . - /// The first tensor, represented as a span. - /// The second tensor, represented as a scalar. - /// The destination tensor, represented as a span. - /// Destination is too short. - /// This method effectively does [i] = [i] - . - public static void Subtract(ReadOnlySpan x, float y, Span destination) => - InvokeSpanScalarIntoSpan(x, y, destination); - - /// Computes the element-wise result of: * . + /// Computes the element-wise result of ( + ) * for the specified tensors. /// The first tensor, represented as a span. /// The second tensor, represented as a span. + /// The third tensor, represented as a span. /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. - /// Destination is too short. - /// This method effectively does [i] = [i] * . - public static void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) => - InvokeSpanSpanIntoSpan(x, y, destination); - - /// Computes the element-wise result of: * . - /// The first tensor, represented as a span. - /// The second tensor, represented as a scalar. - /// The destination tensor, represented as a span. + /// Length of must be same as length of and the length of . /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. /// - /// This method effectively does [i] = [i] * . - /// This method corresponds to the scal method defined by BLAS1. + /// + /// This method effectively computes [i] = ([i] + [i]) * [i]. + /// + /// + /// If any of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// /// - public static void Multiply(ReadOnlySpan x, float y, Span destination) => - InvokeSpanScalarIntoSpan(x, y, destination); + public static void AddMultiply(ReadOnlySpan x, ReadOnlySpan y, ReadOnlySpan multiplier, Span destination) => + InvokeSpanSpanSpanIntoSpan(x, y, multiplier, destination); - /// Computes the element-wise result of: / . + /// Computes the element-wise result of ( + ) * for the specified tensors. /// The first tensor, represented as a span. /// The second tensor, represented as a span. + /// The third tensor, represented as a scalar. /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. + /// Length of must be same as length of . /// Destination is too short. - /// This method effectively does [i] = [i] / . - public static void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) => - InvokeSpanSpanIntoSpan(x, y, destination); + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = ([i] + [i]) * . + /// + /// + /// If any of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// + /// + public static void AddMultiply(ReadOnlySpan x, ReadOnlySpan y, float multiplier, Span destination) => + InvokeSpanSpanScalarIntoSpan(x, y, multiplier, destination); - /// Computes the element-wise result of: / . + /// Computes the element-wise result of ( + ) * for the specified tensors. /// The first tensor, represented as a span. /// The second tensor, represented as a scalar. + /// The third tensor, represented as a span. /// The destination tensor, represented as a span. + /// Length of must be same as length of . /// Destination is too short. - /// This method effectively does [i] = [i] / . - public static void Divide(ReadOnlySpan x, float y, Span destination) => - InvokeSpanScalarIntoSpan(x, y, destination); - - /// Computes the element-wise result of: -. - /// The tensor, represented as a span. - /// The destination tensor, represented as a span. - /// Destination is too short. - /// This method effectively does [i] = -[i]. - public static void Negate(ReadOnlySpan x, Span destination) => - InvokeSpanIntoSpan(x, destination); + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = ([i] + ) * [i]. + /// + /// + /// If any of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// + /// + public static void AddMultiply(ReadOnlySpan x, float y, ReadOnlySpan multiplier, Span destination) => + InvokeSpanScalarSpanIntoSpan(x, y, multiplier, destination); - /// Computes the element-wise result of: MathF.Abs(). + /// Computes the element-wise hyperbolic cosine of each single-precision floating-point radian angle in the specified tensor. /// The tensor, represented as a span. /// The destination tensor, represented as a span. /// Destination is too short. - /// This method effectively does [i] = MathF.Abs([i]). - public static void Abs(ReadOnlySpan x, Span destination) => - InvokeSpanIntoSpan(x, destination); + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = .Cosh([i]). + /// + /// + /// If a value is equal to or , the result stored into the corresponding destination location is set to . + /// If a value is equal to , the result stored into the corresponding destination location is also NaN. + /// + /// + /// The angles in x must be in radians. Use or multiply by /180 to convert degrees to radians. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void Cosh(ReadOnlySpan x, Span destination) => + InvokeSpanIntoSpan(x, destination); - /// Computes the element-wise result of: ( + ) * . + /// Computes the cosine similarity between the two specified non-empty, equal-length tensors of single-precision floating-point numbers. /// The first tensor, represented as a span. /// The second tensor, represented as a span. - /// The third tensor, represented as a span. - /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. - /// Length of '' must be same as length of ''. - /// Destination is too short. - /// This method effectively does [i] = ([i] + [i]) * [i]. - public static void AddMultiply(ReadOnlySpan x, ReadOnlySpan y, ReadOnlySpan multiplier, Span destination) => - InvokeSpanSpanSpanIntoSpan(x, y, multiplier, destination); + /// The cosine similarity of the two tensors. + /// Length of must be same as length of . + /// and must not be empty. + /// + /// + /// This method effectively computes TensorPrimitives.Dot(x, y) / (MathF.Sqrt(TensorPrimitives.SumOfSquares(x)) * MathF.Sqrt(TensorPrimitives.SumOfSquares(y)). + /// + /// + /// If any element in either input tensor is equal to , , or , + /// NaN is returned. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static float CosineSimilarity(ReadOnlySpan x, ReadOnlySpan y) + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + return CosineSimilarityCore(x, y); + } - /// Computes the element-wise result of: ( + ) * . + /// Computes the distance between two points, specified as non-empty, equal-length tensors of single-precision floating-point numbers, in Euclidean space. /// The first tensor, represented as a span. /// The second tensor, represented as a span. - /// The third tensor, represented as a scalar. - /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. - /// Destination is too short. - /// This method effectively does [i] = ([i] + [i]) * . - public static void AddMultiply(ReadOnlySpan x, ReadOnlySpan y, float multiplier, Span destination) => - InvokeSpanSpanScalarIntoSpan(x, y, multiplier, destination); + /// The Euclidean distance. + /// Length of must be same as length of . + /// and must not be empty. + /// + /// + /// This method effectively computes the equivalent of: + /// + /// Span<float> difference = ...; + /// TensorPrimitives.Subtract(x, y, difference); + /// float result = MathF.Sqrt(TensorPrimitives.SumOfSquares(difference)); + /// + /// but without requiring additional temporary storage for the intermediate differences. + /// + /// + /// If any element in either input tensor is equal to , NaN is returned. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static float Distance(ReadOnlySpan x, ReadOnlySpan y) + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } - /// Computes the element-wise result of: ( + ) * . - /// The first tensor, represented as a span. - /// The second tensor, represented as a scalar. - /// The third tensor, represented as a span. - /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. - /// Destination is too short. - /// This method effectively does [i] = ([i] + ) * [i]. - public static void AddMultiply(ReadOnlySpan x, float y, ReadOnlySpan multiplier, Span destination) => - InvokeSpanScalarSpanIntoSpan(x, y, multiplier, destination); + return MathF.Sqrt(Aggregate(x, y)); + } - /// Computes the element-wise result of: ( * ) + . + /// Computes the element-wise division of single-precision floating-point numbers in the specified tensors. /// The first tensor, represented as a span. /// The second tensor, represented as a span. - /// The third tensor, represented as a span. /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. - /// Length of '' must be same as length of ''. + /// Length of must be same as length of . /// Destination is too short. - /// This method effectively does [i] = ([i] * [i]) + [i]. - public static void MultiplyAdd(ReadOnlySpan x, ReadOnlySpan y, ReadOnlySpan addend, Span destination) => - InvokeSpanSpanSpanIntoSpan(x, y, addend, destination); + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = [i] / [i]. + /// + /// + /// If either of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// + /// + public static void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) => + InvokeSpanSpanIntoSpan(x, y, destination); - /// Computes the element-wise result of: ( * ) + . + /// Computes the element-wise division of single-precision floating-point numbers in the specified tensors. /// The first tensor, represented as a span. - /// The second tensor, represented as a span. - /// The third tensor, represented as a span. + /// The second tensor, represented as a scalar. /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. /// - /// This method effectively does [i] = ([i] * [i]) + . - /// This method corresponds to the axpy method defined by BLAS1. + /// + /// This method effectively computes [i] = [i] / . + /// + /// + /// If either of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// /// - public static void MultiplyAdd(ReadOnlySpan x, ReadOnlySpan y, float addend, Span destination) => - InvokeSpanSpanScalarIntoSpan(x, y, addend, destination); + public static void Divide(ReadOnlySpan x, float y, Span destination) => + InvokeSpanScalarIntoSpan(x, y, destination); - /// Computes the element-wise result of: ( * ) + . + /// Computes the dot product of two tensors containing single-precision floating-point numbers. /// The first tensor, represented as a span. /// The second tensor, represented as a span. - /// The third tensor, represented as a span. - /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. - /// Destination is too short. - /// This method effectively does [i] = ([i] * ) + [i]. - public static void MultiplyAdd(ReadOnlySpan x, float y, ReadOnlySpan addend, Span destination) => - InvokeSpanScalarSpanIntoSpan(x, y, addend, destination); + /// The dot product. + /// Length of must be same as length of . + /// + /// + /// This method effectively computes the equivalent of: + /// + /// Span<float> products = ...; + /// TensorPrimitives.Multiply(x, y, products); + /// float result = TensorPrimitives.Sum(products); + /// + /// but without requiring additional temporary storage for the intermediate products. It corresponds to the dot method defined by BLAS1. + /// + /// + /// If any of the input elements is equal to , the resulting value is also NaN. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static float Dot(ReadOnlySpan x, ReadOnlySpan y) => + Aggregate(x, y); - /// Computes the element-wise result of: pow(e, ). + /// Computes the element-wise result of raising e to the single-precision floating-point number powers in the specified tensor. /// The tensor, represented as a span. /// The destination tensor, represented as a span. /// Destination is too short. - /// This method effectively does [i] = .Exp([i]). - public static void Exp(ReadOnlySpan x, Span destination) + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = .Exp([i]). + /// + /// + /// If a value equals or , the result stored into the corresponding destination location is set to NaN. + /// If a value equals , the result stored into the corresponding destination location is set to 0. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void Exp(ReadOnlySpan x, Span destination) => + InvokeSpanIntoSpan(x, destination); + + /// Searches for the index of the largest single-precision floating-point number in the specified tensor. + /// The tensor, represented as a span. + /// The index of the maximum element in , or -1 if is empty. + /// + /// + /// The determination of the maximum element matches the IEEE 754:2019 `maximum` function. If any value equal to + /// is present, the index of the first is returned. Positive 0 is considered greater than negative 0. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static int IndexOfMax(ReadOnlySpan x) { - if (x.Length > destination.Length) + if (x.IsEmpty) { - ThrowHelper.ThrowArgument_DestinationTooShort(); + return -1; } - for (int i = 0; i < x.Length; i++) - { - destination[i] = MathF.Exp(x[i]); - } + return IndexOfMinMaxCore(x); } - /// Computes the element-wise result of: ln(). + /// Searches for the index of the single-precision floating-point number with the largest magnitude in the specified tensor. /// The tensor, represented as a span. - /// The destination tensor, represented as a span. - /// Destination is too short. - /// This method effectively does [i] = .Log([i]). - public static void Log(ReadOnlySpan x, Span destination) + /// The index of the element in with the largest magnitude (absolute value), or -1 if is empty. + /// + /// + /// The determination of the maximum magnitude matches the IEEE 754:2019 `maximumMagnitude` function. If any value equal to + /// is present, the index of the first is returned. If two values have the same magnitude and one is positive and the other is negative, + /// the positive value is considered to have the larger magnitude. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static int IndexOfMaxMagnitude(ReadOnlySpan x) { - if (x.Length > destination.Length) + if (x.IsEmpty) { - ThrowHelper.ThrowArgument_DestinationTooShort(); + return -1; } - for (int i = 0; i < x.Length; i++) - { - destination[i] = MathF.Log(x[i]); - } + return IndexOfMinMaxCore(x); } - /// Computes the element-wise result of: log2(). + /// Searches for the index of the smallest single-precision floating-point number in the specified tensor. /// The tensor, represented as a span. - /// The destination tensor, represented as a span. - /// Destination is too short. - /// This method effectively does [i] = .Log2([i]). - public static void Log2(ReadOnlySpan x, Span destination) + /// The index of the minimum element in , or -1 if is empty. + /// + /// + /// The determination of the minimum element matches the IEEE 754:2019 `minimum` function. If any value equal to + /// is present, the index of the first is returned. Negative 0 is considered smaller than positive 0. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static int IndexOfMin(ReadOnlySpan x) { - if (x.Length > destination.Length) + if (x.IsEmpty) { - ThrowHelper.ThrowArgument_DestinationTooShort(); + return -1; } - for (int i = 0; i < x.Length; i++) - { - destination[i] = Log2(x[i]); - } + return IndexOfMinMaxCore(x); } - /// Computes the element-wise result of: cosh(). + /// Searches for the index of the single-precision floating-point number with the smallest magnitude in the specified tensor. /// The tensor, represented as a span. - /// The destination tensor, represented as a span. - /// Destination is too short. - /// This method effectively does [i] = .Cosh([i]). - public static void Cosh(ReadOnlySpan x, Span destination) + /// The index of the element in with the smallest magnitude (absolute value), or -1 if is empty. + /// + /// + /// The determination of the minimum magnitude matches the IEEE 754:2019 `minimumMagnitude` function. If any value equal to + /// is present, the index of the first is returned. If two values have the same magnitude and one is positive and the other is negative, + /// the negative value is considered to have the smaller magnitude. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static int IndexOfMinMagnitude(ReadOnlySpan x) { - if (x.Length > destination.Length) + if (x.IsEmpty) { - ThrowHelper.ThrowArgument_DestinationTooShort(); + return -1; } - for (int i = 0; i < x.Length; i++) - { - destination[i] = MathF.Cosh(x[i]); - } + return IndexOfMinMaxCore(x); } - /// Computes the element-wise result of: sinh(). + /// Computes the element-wise natural (base e) logarithm of single-precision floating-point numbers in the specified tensor. /// The tensor, represented as a span. /// The destination tensor, represented as a span. /// Destination is too short. - /// This method effectively does [i] = .Sinh([i]). - public static void Sinh(ReadOnlySpan x, Span destination) - { - if (x.Length > destination.Length) - { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } - - for (int i = 0; i < x.Length; i++) - { - destination[i] = MathF.Sinh(x[i]); - } - } + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = .Log([i]). + /// + /// + /// If a value equals 0, the result stored into the corresponding destination location is set to . + /// If a value is negative or equal to , the result stored into the corresponding destination location is set to NaN. + /// If a value is positive infinity, the result stored into the corresponding destination location is set to . + /// Otherwise, if a value is positive, its natural logarithm is stored into the corresponding destination location. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void Log(ReadOnlySpan x, Span destination) => + InvokeSpanIntoSpan(x, destination); - /// Computes the element-wise result of: tanh(). + /// Computes the element-wise base 2 logarithm of single-precision floating-point numbers in the specified tensor. /// The tensor, represented as a span. /// The destination tensor, represented as a span. /// Destination is too short. - /// This method effectively does [i] = .Tanh([i]). - public static void Tanh(ReadOnlySpan x, Span destination) - { - if (x.Length > destination.Length) - { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = .Log2([i]). + /// + /// + /// If a value equals 0, the result stored into the corresponding destination location is set to . + /// If a value is negative or equal to , the result stored into the corresponding destination location is set to NaN. + /// If a value is positive infinity, the result stored into the corresponding destination location is set to . + /// Otherwise, if a value is positive, its natural logarithm is stored into the corresponding destination location. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void Log2(ReadOnlySpan x, Span destination) => + InvokeSpanIntoSpan(x, destination); - for (int i = 0; i < x.Length; i++) - { - destination[i] = MathF.Tanh(x[i]); - } - } + /// Searches for the largest single-precision floating-point number in the specified tensor. + /// The tensor, represented as a span. + /// The maximum element in . + /// Length of must be greater than zero. + /// + /// + /// The determination of the maximum element matches the IEEE 754:2019 `maximum` function. If any value equal to + /// is present, the first is returned. Positive 0 is considered greater than negative 0. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static float Max(ReadOnlySpan x) => + MinMaxCore(x); - /// Computes the cosine similarity between two non-zero vectors. + /// Computes the element-wise maximum of the single-precision floating-point numbers in the specified tensors. /// The first tensor, represented as a span. /// The second tensor, represented as a span. - /// The cosine similarity between the two vectors. - /// Length of '' must be same as length of ''. - /// '' and '' must not be empty. - public static float CosineSimilarity(ReadOnlySpan x, ReadOnlySpan y) - { - if (x.IsEmpty) - { - ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); - } - if (x.Length != y.Length) - { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); - } + /// The destination tensor, represented as a span. + /// Length of must be same as length of . + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = MathF.Max([i], [i]). + /// + /// + /// The determination of the maximum element matches the IEEE 754:2019 `maximum` function. If either value is equal to , + /// that value is stored as the result. Positive 0 is considered greater than negative 0. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void Max(ReadOnlySpan x, ReadOnlySpan y, Span destination) => + InvokeSpanSpanIntoSpan(x, y, destination); - return CosineSimilarityCore(x, y); - } + /// Searches for the single-precision floating-point number with the largest magnitude in the specified tensor. + /// The tensor, represented as a span. + /// The element in with the largest magnitude (absolute value). + /// Length of must be greater than zero. + /// + /// + /// The determination of the maximum magnitude matches the IEEE 754:2019 `maximumMagnitude` function. If any value equal to + /// is present, the first is returned. If two values have the same magnitude and one is positive and the other is negative, + /// the positive value is considered to have the larger magnitude. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static float MaxMagnitude(ReadOnlySpan x) => + MinMaxCore(x); - /// - /// Compute the distance between two points in Euclidean space. - /// + /// Computes the element-wise single-precision floating-point number with the largest magnitude in the specified tensors. /// The first tensor, represented as a span. /// The second tensor, represented as a span. - /// The Euclidean distance. - /// Length of '' must be same as length of ''. - /// '' and '' must not be empty. - public static float Distance(ReadOnlySpan x, ReadOnlySpan y) - { - if (x.IsEmpty) - { - ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); - } - if (x.Length != y.Length) - { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); - } + /// The destination tensor, represented as a span. + /// Length of must be same as length of . + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// This method effectively computes [i] = MathF.MaxMagnitude([i], [i]). + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void MaxMagnitude(ReadOnlySpan x, ReadOnlySpan y, Span destination) => + InvokeSpanSpanIntoSpan(x, y, destination); - return MathF.Sqrt(Aggregate(0f, x, y)); - } + /// Searches for the smallest single-precision floating-point number in the specified tensor. + /// The tensor, represented as a span. + /// The minimum element in . + /// Length of must be greater than zero. + /// + /// + /// The determination of the minimum element matches the IEEE 754:2019 `minimum` function. If any value is equal to + /// is present, the first is returned. Negative 0 is considered smaller than positive 0. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static float Min(ReadOnlySpan x) => + MinMaxCore(x); - /// - /// A mathematical operation that takes two vectors and returns a scalar. - /// + /// Computes the element-wise minimum of the single-precision floating-point numbers in the specified tensors. /// The first tensor, represented as a span. /// The second tensor, represented as a span. - /// The dot product. - /// Length of '' must be same as length of ''. - public static float Dot(ReadOnlySpan x, ReadOnlySpan y) // BLAS1: dot - { - if (x.Length != y.Length) - { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); - } + /// The destination tensor, represented as a span. + /// Length of must be same as length of . + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = MathF.Max([i], [i]). + /// + /// + /// The determination of the maximum element matches the IEEE 754:2019 `maximum` function. If either value is equal to , + /// that value is stored as the result. Positive 0 is considered greater than negative 0. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void Min(ReadOnlySpan x, ReadOnlySpan y, Span destination) => + InvokeSpanSpanIntoSpan(x, y, destination); - return Aggregate(0f, x, y); - } + /// Searches for the single-precision floating-point number with the smallest magnitude in the specified tensor. + /// The tensor, represented as a span. + /// The element in with the smallest magnitude (absolute value). + /// Length of must be greater than zero. + /// + /// + /// The determination of the minimum magnitude matches the IEEE 754:2019 `minimumMagnitude` function. If any value equal to + /// is present, the first is returned. If two values have the same magnitude and one is positive and the other is negative, + /// the negative value is considered to have the smaller magnitude. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static float MinMagnitude(ReadOnlySpan x) => + MinMaxCore(x); - /// - /// A mathematical operation that takes a vector and returns the L2 norm. - /// + /// Computes the element-wise single-precision floating-point number with the smallest magnitude in the specified tensors. /// The first tensor, represented as a span. - /// The L2 norm. - public static float Norm(ReadOnlySpan x) // BLAS1: nrm2 - { - return MathF.Sqrt(Aggregate(0f, x)); - } + /// The second tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of must be same as length of . + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// This method effectively computes [i] = MathF.MinMagnitude([i], [i]). + /// + /// + /// The determination of the maximum magnitude matches the IEEE 754:2019 `minimumMagnitude` function. If either value is equal to , + /// that value is stored as the result. If the two values have the same magnitude and one is positive and the other is negative, + /// the negative value is considered to have the smaller magnitude. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void MinMagnitude(ReadOnlySpan x, ReadOnlySpan y, Span destination) => + InvokeSpanSpanIntoSpan(x, y, destination); - /// - /// A function that takes a collection of real numbers and returns a probability distribution. - /// + /// Computes the element-wise product of single-precision floating-point numbers in the specified tensors. /// The first tensor, represented as a span. - /// The destination tensor. + /// The second tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of must be same as length of . /// Destination is too short. - /// '' must not be empty. - public static void SoftMax(ReadOnlySpan x, Span destination) - { - if (x.IsEmpty) - { - ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); - } - if (x.Length > destination.Length) - { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } - - float expSum = 0f; - - for (int i = 0; i < x.Length; i++) - { - expSum += MathF.Exp(x[i]); - } - - for (int i = 0; i < x.Length; i++) - { - destination[i] = MathF.Exp(x[i]) / expSum; - } - } + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = [i] * [i]. + /// + /// + /// If either of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// + /// + public static void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) => + InvokeSpanSpanIntoSpan(x, y, destination); - /// - /// A function that takes a real number and returns a value between 0 and 1. - /// + /// Computes the element-wise product of single-precision floating-point numbers in the specified tensors. /// The first tensor, represented as a span. - /// The destination tensor. + /// The second tensor, represented as a scalar. + /// The destination tensor, represented as a span. /// Destination is too short. - /// '' must not be empty. - public static void Sigmoid(ReadOnlySpan x, Span destination) - { - if (x.IsEmpty) - { - ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); - } - if (x.Length > destination.Length) - { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } - - for (int i = 0; i < x.Length; i++) - { - destination[i] = 1f / (1 + MathF.Exp(-x[i])); - } - } - - /// Computes the maximum element in . - /// The tensor, represented as a span. - /// The maximum element in . - /// Length of '' must be greater than zero. - public static float Max(ReadOnlySpan x) - { - if (x.IsEmpty) - { - ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); - } - - float result = float.NegativeInfinity; - - for (int i = 0; i < x.Length; i++) - { - // This matches the IEEE 754:2019 `maximum` function. - // It propagates NaN inputs back to the caller and - // otherwise returns the greater of the inputs. - // It treats +0 as greater than -0 as per the specification. - - float current = x[i]; - - if (current != result) - { - if (float.IsNaN(current)) - { - return current; - } - - if (result < current) - { - result = current; - } - } - else if (IsNegative(result)) - { - result = current; - } - } + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = [i] * . + /// It corresponds to the scal method defined by BLAS1. + /// + /// + /// If either of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// + /// + public static void Multiply(ReadOnlySpan x, float y, Span destination) => + InvokeSpanScalarIntoSpan(x, y, destination); - return result; - } + /// Computes the element-wise result of ( * ) * for the specified tensors of single-precision floating-point numbers. + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The third tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of must be same as length of and length of . + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = ([i] * [i]) + [i]. + /// + /// + /// If either of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// + /// + public static void MultiplyAdd(ReadOnlySpan x, ReadOnlySpan y, ReadOnlySpan addend, Span destination) => + InvokeSpanSpanSpanIntoSpan(x, y, addend, destination); - /// Computes the element-wise result of: MathF.Max(, ). + /// Computes the element-wise result of ( * ) * for the specified tensors of single-precision floating-point numbers. /// The first tensor, represented as a span. /// The second tensor, represented as a span. + /// The third tensor, represented as a scalar. /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. + /// Length of must be same as length of . /// Destination is too short. - /// This method effectively does [i] = MathF.Max([i], [i]). - public static void Max(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - if (x.Length != y.Length) - { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); - } + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = ([i] * [i]) + . + /// It corresponds to the axpy method defined by BLAS1. + /// + /// + /// If either of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// + /// + public static void MultiplyAdd(ReadOnlySpan x, ReadOnlySpan y, float addend, Span destination) => + InvokeSpanSpanScalarIntoSpan(x, y, addend, destination); - if (x.Length > destination.Length) - { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } + /// Computes the element-wise result of ( * ) * for the specified tensors of single-precision floating-point numbers. + /// The first tensor, represented as a span. + /// The second tensor, represented as a scalar. + /// The third tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of must be same as length of . + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = ([i] * ) + [i]. + /// + /// + /// If either of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// + /// + public static void MultiplyAdd(ReadOnlySpan x, float y, ReadOnlySpan addend, Span destination) => + InvokeSpanScalarSpanIntoSpan(x, y, addend, destination); - for (int i = 0; i < x.Length; i++) - { - destination[i] = MathF.Max(x[i], y[i]); - } - } + /// Computes the element-wise negation of each single-precision floating-point number in the specified tensor. + /// The tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = -[i]. + /// + /// + /// If any of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// + /// + public static void Negate(ReadOnlySpan x, Span destination) => + InvokeSpanIntoSpan(x, destination); + + /// Computes the Euclidean norm of the specified tensor of single-precision floating-point numbers. + /// The first tensor, represented as a span. + /// The norm. + /// + /// + /// This method effectively computes MathF.Sqrt(TensorPrimitives.SumOfSquares(x)). + /// This is often referred to as the Euclidean norm or L2 norm. + /// It corresponds to the nrm2 method defined by BLAS1. + /// + /// + /// If any of the input values is equal to , the result value is also NaN. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static float Norm(ReadOnlySpan x) => + MathF.Sqrt(SumOfSquares(x)); - /// Computes the minimum element in . + /// Computes the product of all elements in the specified non-empty tensor of single-precision floating-point numbers. /// The tensor, represented as a span. - /// The minimum element in . - /// Length of '' must be greater than zero. - public static float Min(ReadOnlySpan x) + /// The result of multiplying all elements in . + /// Length of must be greater than zero. + /// + /// + /// If any of the input values is equal to , the result value is also NaN. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static float Product(ReadOnlySpan x) { if (x.IsEmpty) { ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); } - float result = float.PositiveInfinity; - - for (int i = 0; i < x.Length; i++) - { - // This matches the IEEE 754:2019 `minimum` function - // It propagates NaN inputs back to the caller and - // otherwise returns the lesser of the inputs. - // It treats +0 as greater than -0 as per the specification. - - float current = x[i]; - - if (current != result) - { - if (float.IsNaN(current)) - { - return current; - } - - if (current < result) - { - result = current; - } - } - else if (IsNegative(current)) - { - result = current; - } - } - - return result; + return Aggregate(x); } - /// Computes the element-wise result of: MathF.Min(, ). + /// Computes the product of the element-wise differences of the single-precision floating-point numbers in the specified non-empty tensors. /// The first tensor, represented as a span. /// The second tensor, represented as a span. - /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. - /// Destination is too short. - /// This method effectively does [i] = MathF.Min([i], [i]). - public static void Min(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - if (x.Length != y.Length) - { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); - } - - if (x.Length > destination.Length) - { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } - - for (int i = 0; i < x.Length; i++) - { - destination[i] = MathF.Min(x[i], y[i]); - } - } - - /// Computes the maximum magnitude of any element in . - /// The tensor, represented as a span. - /// The maximum magnitude of any element in . - /// Length of '' must be greater than zero. - public static float MaxMagnitude(ReadOnlySpan x) + /// The result of multiplying the element-wise subtraction of the elements in the second tensor from the first tensor. + /// Length of both input spans must be greater than zero. + /// and must have the same length. + /// + /// + /// This method effectively computes: + /// + /// Span<float> differences = ...; + /// TensorPrimitives.Subtract(x, y, differences); + /// float result = TensorPrimitives.Product(differences); + /// + /// but without requiring additional temporary storage for the intermediate differences. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static float ProductOfDifferences(ReadOnlySpan x, ReadOnlySpan y) { if (x.IsEmpty) { ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); } - float result = float.NegativeInfinity; - float resultMag = float.NegativeInfinity; - - for (int i = 0; i < x.Length; i++) - { - // This matches the IEEE 754:2019 `maximumMagnitude` function. - // It propagates NaN inputs back to the caller and - // otherwise returns the input with a greater magnitude. - // It treats +0 as greater than -0 as per the specification. - - float current = x[i]; - float currentMag = Math.Abs(current); - - if (currentMag != resultMag) - { - if (float.IsNaN(currentMag)) - { - return currentMag; - } - - if (resultMag < currentMag) - { - result = current; - resultMag = currentMag; - } - } - else if (IsNegative(result)) - { - result = current; - resultMag = currentMag; - } - } - - return result; + return Aggregate(x, y); } - /// Computes the element-wise result of: MathF.MaxMagnitude(, ). + /// Computes the product of the element-wise sums of the single-precision floating-point numbers in the specified non-empty tensors. /// The first tensor, represented as a span. /// The second tensor, represented as a span. - /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. - /// Destination is too short. - /// This method effectively does [i] = MathF.MaxMagnitude([i], [i]). - public static void MaxMagnitude(ReadOnlySpan x, ReadOnlySpan y, Span destination) + /// The result of multiplying the element-wise additions of the elements in each tensor. + /// Length of both input spans must be greater than zero. + /// and must have the same length. + /// + /// + /// This method effectively computes: + /// + /// Span<float> sums = ...; + /// TensorPrimitives.Add(x, y, sums); + /// float result = TensorPrimitives.Product(sums); + /// + /// but without requiring additional temporary storage for the intermediate sums. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static float ProductOfSums(ReadOnlySpan x, ReadOnlySpan y) { - if (x.Length != y.Length) - { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); - } - - if (x.Length > destination.Length) + if (x.IsEmpty) { - ThrowHelper.ThrowArgument_DestinationTooShort(); + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); } - for (int i = 0; i < x.Length; i++) - { - destination[i] = MaxMagnitude(x[i], y[i]); - } + return Aggregate(x, y); } - /// Computes the minimum magnitude of any element in . + /// Computes the element-wise sigmoid function on the specified non-empty tensor of single-precision floating-point numbers. /// The tensor, represented as a span. - /// The minimum magnitude of any element in . - /// Length of '' must be greater than zero. - public static float MinMagnitude(ReadOnlySpan x) + /// The destination tensor. + /// Destination is too short. + /// must not be empty. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = 1f / (1f + .Exp(-[i])). + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void Sigmoid(ReadOnlySpan x, Span destination) { if (x.IsEmpty) { ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); } - float result = float.PositiveInfinity; - float resultMag = float.PositiveInfinity; - - for (int i = 0; i < x.Length; i++) - { - // This matches the IEEE 754:2019 `minimumMagnitude` function. - // It propagates NaN inputs back to the caller and - // otherwise returns the input with a lesser magnitude. - // It treats +0 as greater than -0 as per the specification. - - float current = x[i]; - float currentMag = Math.Abs(current); - - if (currentMag != resultMag) - { - if (float.IsNaN(currentMag)) - { - return currentMag; - } - - if (currentMag < resultMag) - { - result = current; - resultMag = currentMag; - } - } - else if (IsNegative(current)) - { - result = current; - resultMag = currentMag; - } - } - - return result; + InvokeSpanIntoSpan(x, destination); } - /// Computes the element-wise result of: MathF.MinMagnitude(, ). - /// The first tensor, represented as a span. - /// The second tensor, represented as a span. + /// Computes the element-wise hyperbolic sine of each single-precision floating-point radian angle in the specified tensor. + /// The tensor, represented as a span. /// The destination tensor, represented as a span. - /// Length of '' must be same as length of ''. /// Destination is too short. - /// This method effectively does [i] = MathF.MinMagnitude([i], [i]). - public static void MinMagnitude(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - if (x.Length != y.Length) - { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); - } - - if (x.Length > destination.Length) - { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } - - for (int i = 0; i < x.Length; i++) - { - destination[i] = MinMagnitude(x[i], y[i]); - } - } + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = .Sinh([i]). + /// + /// + /// If a value is equal to , , or , + /// the corresponding destination location is set to that value. + /// + /// + /// The angles in x must be in radians. Use or multiply by /180 to convert degrees to radians. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void Sinh(ReadOnlySpan x, Span destination) => + InvokeSpanIntoSpan(x, destination); - /// Computes the index of the maximum element in . + /// Computes the softmax function over the specified non-empty tensor of single-precision floating-point numbers. /// The tensor, represented as a span. - /// The index of the maximum element in , or -1 if is empty. - public static unsafe int IndexOfMax(ReadOnlySpan x) + /// The destination tensor. + /// Destination is too short. + /// must not be empty. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes a sum of MathF.Exp(x[i]) for all elements in . + /// It then effectively computes [i] = MathF.Exp([i]) / sum. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void SoftMax(ReadOnlySpan x, Span destination) { - int result = -1; - - if (!x.IsEmpty) + if (x.IsEmpty) { - float max = float.NegativeInfinity; - - for (int i = 0; i < x.Length; i++) - { - // This matches the IEEE 754:2019 `maximum` function. - // It propagates NaN inputs back to the caller and - // otherwise returns the greater of the inputs. - // It treats +0 as greater than -0 as per the specification. - - float current = x[i]; - - if (current != max) - { - if (float.IsNaN(current)) - { - return i; - } - - if (max < current) - { - result = i; - max = current; - } - } - else if (IsNegative(max) && !IsNegative(current)) - { - result = i; - max = current; - } - } + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); } - return result; - } - - /// Computes the index of the minimum element in . - /// The tensor, represented as a span. - /// The index of the minimum element in , or -1 if is empty. - public static unsafe int IndexOfMin(ReadOnlySpan x) - { - int result = -1; - - if (!x.IsEmpty) + if (x.Length > destination.Length) { - float min = float.PositiveInfinity; - - for (int i = 0; i < x.Length; i++) - { - // This matches the IEEE 754:2019 `minimum` function. - // It propagates NaN inputs back to the caller and - // otherwise returns the lesser of the inputs. - // It treats +0 as greater than -0 as per the specification. - - float current = x[i]; - - if (current != min) - { - if (float.IsNaN(current)) - { - return i; - } - - if (current < min) - { - result = i; - min = current; - } - } - else if (IsNegative(current) && !IsNegative(min)) - { - result = i; - min = current; - } - } + ThrowHelper.ThrowArgument_DestinationTooShort(); } - return result; - } + ValidateInputOutputSpanNonOverlapping(x, destination); - /// Computes the index of the element in with the maximum magnitude. - /// The tensor, represented as a span. - /// The index of the element with the maximum magnitude, or -1 if is empty. - /// This method corresponds to the iamax method defined by BLAS1. - public static unsafe int IndexOfMaxMagnitude(ReadOnlySpan x) - { - int result = -1; - - if (!x.IsEmpty) - { - float max = float.NegativeInfinity; - float maxMag = float.NegativeInfinity; - - for (int i = 0; i < x.Length; i++) - { - // This matches the IEEE 754:2019 `maximumMagnitude` function. - // It propagates NaN inputs back to the caller and - // otherwise returns the input with a greater magnitude. - // It treats +0 as greater than -0 as per the specification. - - float current = x[i]; - float currentMag = Math.Abs(current); - - if (currentMag != maxMag) - { - if (float.IsNaN(currentMag)) - { - return i; - } - - if (maxMag < currentMag) - { - result = i; - max = current; - maxMag = currentMag; - } - } - else if (IsNegative(max) && !IsNegative(current)) - { - result = i; - max = current; - maxMag = currentMag; - } - } - } + float expSum = Aggregate(x); - return result; + InvokeSpanScalarIntoSpan(x, expSum, destination); } - /// Computes the index of the element in with the minimum magnitude. - /// The tensor, represented as a span. - /// The index of the element with the minimum magnitude, or -1 if is empty. - public static unsafe int IndexOfMinMagnitude(ReadOnlySpan x) - { - int result = -1; - - if (!x.IsEmpty) - { - float min = float.PositiveInfinity; - float minMag = float.PositiveInfinity; - - for (int i = 0; i < x.Length; i++) - { - // This matches the IEEE 754:2019 `minimumMagnitude` function - // It propagates NaN inputs back to the caller and - // otherwise returns the input with a lesser magnitude. - // It treats +0 as greater than -0 as per the specification. - - float current = x[i]; - float currentMag = Math.Abs(current); - - if (currentMag != minMag) - { - if (float.IsNaN(currentMag)) - { - return i; - } - - if (currentMag < minMag) - { - result = i; - min = current; - minMag = currentMag; - } - } - else if (IsNegative(current) && !IsNegative(min)) - { - result = i; - min = current; - minMag = currentMag; - } - } - } + /// Computes the element-wise difference between single-precision floating-point numbers in the specified tensors. + /// The first tensor, represented as a span. + /// The second tensor, represented as a scalar. + /// The destination tensor, represented as a span. + /// Length of must be same as length of . + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = [i] - [i]. + /// + /// + /// If either of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// + /// + public static void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) => + InvokeSpanSpanIntoSpan(x, y, destination); - return result; - } + /// Computes the element-wise difference between single-precision floating-point numbers in the specified tensors. + /// The first tensor, represented as a span. + /// The second tensor, represented as a scalar. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = [i] - . + /// + /// + /// If either of the element-wise input values is equal to , the resulting element-wise value is also NaN. + /// + /// + public static void Subtract(ReadOnlySpan x, float y, Span destination) => + InvokeSpanScalarIntoSpan(x, y, destination); - /// Computes the sum of all elements in . + /// Computes the sum of all elements in the specified tensor of single-precision floating-point numbers. /// The tensor, represented as a span. /// The result of adding all elements in , or zero if is empty. + /// + /// + /// If any of the values in the input is equal to , the result is also NaN. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// public static float Sum(ReadOnlySpan x) => - Aggregate(0f, x); - - /// Computes the sum of the squares of every element in . - /// The tensor, represented as a span. - /// The result of adding every element in multiplied by itself, or zero if is empty. - /// This method effectively does .Sum(.Multiply(, )). - public static float SumOfSquares(ReadOnlySpan x) => - Aggregate(0f, x); + Aggregate(x); - /// Computes the sum of the absolute values of every element in . + /// Computes the sum of the absolute values of every element in the specified tensor of single-precision floating-point numbers. /// The tensor, represented as a span. /// The result of adding the absolute value of every element in , or zero if is empty. /// - /// This method effectively does .Sum(.Abs()). - /// This method corresponds to the asum method defined by BLAS1. + /// + /// This method effectively computes: + /// + /// Span<float> absoluteValues = ...; + /// TensorPrimitives.Abs(x, absoluteValues); + /// float result = TensorPrimitives.Sum(absoluteValues); + /// + /// but without requiring intermediate storage for the absolute values. It corresponds to the asum method defined by BLAS1. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// /// public static float SumOfMagnitudes(ReadOnlySpan x) => - Aggregate(0f, x); + Aggregate(x); - /// Computes the product of all elements in . + /// Computes the sum of the square of every element in the specified tensor of single-precision floating-point numbers. /// The tensor, represented as a span. - /// The result of multiplying all elements in . - /// Length of '' must be greater than zero. - public static float Product(ReadOnlySpan x) - { - if (x.IsEmpty) - { - ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); - } + /// The result of adding the square of every element in , or zero if is empty. + /// + /// + /// This method effectively computes: + /// + /// Span<float> squaredValues = ...; + /// TensorPrimitives.Multiply(x, x, squaredValues); + /// float result = TensorPrimitives.Sum(squaredValues); + /// + /// but without requiring intermediate storage for the squared values. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static float SumOfSquares(ReadOnlySpan x) => + Aggregate(x); - return Aggregate(1.0f, x); - } + /// Computes the element-wise hyperbolic tangent of each single-precision floating-point radian angle in the specified tensor. + /// The tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = .Tanh([i]). + /// + /// + /// If a value is equal to , the corresponding destination location is set to -1. + /// If a value is equal to , the corresponding destination location is set to 1. + /// If a value is equal to , the corresponding destination location is set to NaN. + /// + /// + /// The angles in x must be in radians. Use or multiply by /180 to convert degrees to radians. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void Tanh(ReadOnlySpan x, Span destination) => + InvokeSpanIntoSpan(x, destination); - /// Computes the product of the element-wise result of: + . - /// The first tensor, represented as a span. - /// The second tensor, represented as a span. - /// The result of multiplying the element-wise additions of the elements in each tensor. - /// Length of both input spans must be greater than zero. - /// and must have the same length. - /// This method effectively does .Product(.Add(, )). - public static float ProductOfSums(ReadOnlySpan x, ReadOnlySpan y) + /// Throws an exception if the and spans overlap and don't begin at the same memory location. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void ValidateInputOutputSpanNonOverlapping(ReadOnlySpan input, Span output) { - if (x.IsEmpty) - { - ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); - } - - if (x.Length != y.Length) + if (!Unsafe.AreSame(ref MemoryMarshal.GetReference(input), ref MemoryMarshal.GetReference(output)) && + input.Overlaps(output)) { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + ThrowHelper.ThrowArgument_InputAndDestinationSpanMustNotOverlap(); } - - return Aggregate(1.0f, x, y); } - /// Computes the product of the element-wise result of: - . - /// The first tensor, represented as a span. - /// The second tensor, represented as a span. - /// The result of multiplying the element-wise subtraction of the elements in the second tensor from the first tensor. - /// Length of both input spans must be greater than zero. - /// and must have the same length. - /// This method effectively does .Product(.Subtract(, )). - public static float ProductOfDifferences(ReadOnlySpan x, ReadOnlySpan y) - { - if (x.IsEmpty) - { - ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); - } - - if (x.Length != y.Length) - { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); - } - - return Aggregate(1.0f, x, y); - } + /// Mask used to handle alignment elements before vectorized handling of the input. + /// + /// Logically 16 rows of 16 uints. The Nth row should be used to handle N alignment elements at the + /// beginning of the input, where elements in the vector after that will be zero'd. + /// + /// There actually exists 17 rows in the table with the last row being a repeat of the first. This is + /// done because it allows the main algorithms to use a simplified algorithm when computing the amount + /// of misalignment where we always skip the first 16 elements, even if already aligned, so we don't + /// double process them. This allows us to avoid an additional branch. + /// + private static ReadOnlySpan AlignmentUInt32Mask_16x16 => + [ + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + ]; + + /// Mask used to handle remaining elements after vectorized handling of the input. + /// + /// Logically 16 rows of 16 uints. The Nth row should be used to handle N remaining elements at the + /// end of the input, where elements in the vector prior to that will be zero'd. + /// + /// Much as with the AlignmentMask table, we actually have 17 rows where the last row is a repeat of + /// the first. Doing this allows us to avoid an additional branch and instead to always process the + /// last 16 elements via a conditional select instead. + /// + private static ReadOnlySpan RemainderUInt32Mask_16x16 => + [ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + ]; } } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs index 8eb1769d5eaee8..498e4b58da77ca 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netcore.cs @@ -1,14 +1,33 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using System.Runtime.Intrinsics.X86; namespace System.Numerics.Tensors { - public static partial class TensorPrimitives + public static unsafe partial class TensorPrimitives { + /// Defines the threshold, in bytes, at which non-temporal stores will be used. + /// + /// A non-temporal store is one that allows the CPU to bypass the cache when writing to memory. + /// + /// This can be beneficial when working with large amounts of memory where the writes would otherwise + /// cause large amounts of repeated updates and evictions. The hardware optimization manuals recommend + /// the threshold to be roughly half the size of the last level of on-die cache -- that is, if you have approximately + /// 4MB of L3 cache per core, you'd want this to be approx. 1-2MB, depending on if hyperthreading was enabled. + /// + /// However, actually computing the amount of L3 cache per core can be tricky or error prone. Native memcpy + /// algorithms use a constant threshold that is typically around 256KB and we match that here for simplicity. This + /// threshold accounts for most processors in the last 10-15 years that had approx. 1MB L3 per core and support + /// hyperthreading, giving a per core last level cache of approx. 512KB. + /// + private const nuint NonTemporalByteThreshold = 256 * 1024; + /// /// Copies to , converting each /// value to its nearest representable half-precision floating-point value. @@ -16,6 +35,14 @@ public static partial class TensorPrimitives /// The source span from which to copy values. /// The destination span into which the converted values should be written. /// Destination is too short. + /// + /// + /// This method effectively computes [i] = (Half)[i]. + /// + /// + /// and must not overlap. If they do, behavior is undefined. + /// + /// public static void ConvertToHalf(ReadOnlySpan source, Span destination) { if (source.Length > destination.Length) @@ -23,361 +50,354 @@ public static void ConvertToHalf(ReadOnlySpan source, Span destinat ThrowHelper.ThrowArgument_DestinationTooShort(); } - for (int i = 0; i < source.Length; i++) + ref float sourceRef = ref MemoryMarshal.GetReference(source); + ref ushort destinationRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destination)); + int i = 0, twoVectorsFromEnd; + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) { - destination[i] = (Half)source[i]; + twoVectorsFromEnd = source.Length - (Vector512.Count * 2); + if (i <= twoVectorsFromEnd) + { + // Loop handling two input vectors / one output vector at a time. + do + { + Vector512 lower = SingleToHalfAsWidenedUInt32_Vector512(Vector512.LoadUnsafe(ref sourceRef, (uint)i)); + Vector512 upper = SingleToHalfAsWidenedUInt32_Vector512(Vector512.LoadUnsafe(ref sourceRef, (uint)(i + Vector512.Count))); + Vector512.Narrow(lower, upper).StoreUnsafe(ref destinationRef, (uint)i); + + i += Vector512.Count * 2; + } + while (i <= twoVectorsFromEnd); + + // Handle any remaining elements with final vectors. + if (i != source.Length) + { + i = source.Length - (Vector512.Count * 2); + + Vector512 lower = SingleToHalfAsWidenedUInt32_Vector512(Vector512.LoadUnsafe(ref sourceRef, (uint)i)); + Vector512 upper = SingleToHalfAsWidenedUInt32_Vector512(Vector512.LoadUnsafe(ref sourceRef, (uint)(i + Vector512.Count))); + Vector512.Narrow(lower, upper).StoreUnsafe(ref destinationRef, (uint)i); + } + + return; + } } - } +#endif - /// - /// Copies to , converting each half-precision - /// floating-point value to its nearest representable value. - /// - /// The source span from which to copy values. - /// The destination span into which the converted values should be written. - /// Destination is too short. - public static void ConvertToSingle(ReadOnlySpan source, Span destination) - { - if (source.Length > destination.Length) + if (Vector256.IsHardwareAccelerated) { - ThrowHelper.ThrowArgument_DestinationTooShort(); + twoVectorsFromEnd = source.Length - (Vector256.Count * 2); + if (i <= twoVectorsFromEnd) + { + // Loop handling two input vectors / one output vector at a time. + do + { + Vector256 lower = SingleToHalfAsWidenedUInt32_Vector256(Vector256.LoadUnsafe(ref sourceRef, (uint)i)); + Vector256 upper = SingleToHalfAsWidenedUInt32_Vector256(Vector256.LoadUnsafe(ref sourceRef, (uint)(i + Vector256.Count))); + Vector256 halfs = Vector256.Narrow(lower, upper); + halfs.StoreUnsafe(ref destinationRef, (uint)i); + + i += Vector256.Count * 2; + } + while (i <= twoVectorsFromEnd); + + // Handle any remaining elements with final vectors. + if (i != source.Length) + { + i = source.Length - (Vector256.Count * 2); + + Vector256 lower = SingleToHalfAsWidenedUInt32_Vector256(Vector256.LoadUnsafe(ref sourceRef, (uint)i)); + Vector256 upper = SingleToHalfAsWidenedUInt32_Vector256(Vector256.LoadUnsafe(ref sourceRef, (uint)(i + Vector256.Count))); + Vector256.Narrow(lower, upper).StoreUnsafe(ref destinationRef, (uint)i); + } + + return; + } } - for (int i = 0; i < source.Length; i++) + if (Vector128.IsHardwareAccelerated) { - destination[i] = (float)source[i]; + twoVectorsFromEnd = source.Length - (Vector128.Count * 2); + if (i <= twoVectorsFromEnd) + { + // Loop handling two input vectors / one output vector at a time. + do + { + Vector128 lower = SingleToHalfAsWidenedUInt32_Vector128(Vector128.LoadUnsafe(ref sourceRef, (uint)i)); + Vector128 upper = SingleToHalfAsWidenedUInt32_Vector128(Vector128.LoadUnsafe(ref sourceRef, (uint)(i + Vector128.Count))); + Vector128.Narrow(lower, upper).StoreUnsafe(ref destinationRef, (uint)i); + + i += Vector128.Count * 2; + } + while (i <= twoVectorsFromEnd); + + // Handle any remaining elements with final vectors. + if (i != source.Length) + { + i = source.Length - (Vector128.Count * 2); + + Vector128 lower = SingleToHalfAsWidenedUInt32_Vector128(Vector128.LoadUnsafe(ref sourceRef, (uint)i)); + Vector128 upper = SingleToHalfAsWidenedUInt32_Vector128(Vector128.LoadUnsafe(ref sourceRef, (uint)(i + Vector128.Count))); + Vector128.Narrow(lower, upper).StoreUnsafe(ref destinationRef, (uint)i); + } + + return; + } } - } - private static bool IsNegative(float f) => float.IsNegative(f); + while (i < source.Length) + { + Unsafe.Add(ref destinationRef, i) = BitConverter.HalfToUInt16Bits((Half)Unsafe.Add(ref sourceRef, i)); + i++; + } - private static float MaxMagnitude(float x, float y) => MathF.MaxMagnitude(x, y); + // This implements a vectorized version of the `explicit operator Half(float value) operator`. + // See detailed description of the algorithm used here: + // https://github.com/dotnet/runtime/blob/ca8d6f0420096831766ec11c7d400e4f7ccc7a34/src/libraries/System.Private.CoreLib/src/System/Half.cs#L606-L714 + // The cast operator converts a float to a Half represented as a UInt32, then narrows to a UInt16, and reinterpret casts to Half. + // This does the same, with an input VectorXx and an output VectorXx. + // Loop handling two input vectors at a time; each input float is double the size of each output Half, + // so we need two vectors of floats to produce one vector of Halfs. Half isn't supported in VectorXx, + // so we convert the VectorXx to a VectorXx, and the caller then uses this twice, narrows the combination + // into a VectorXx, and then saves that out to the destination `ref Half` reinterpreted as `ref ushort`. + +#pragma warning disable IDE0059 // https://github.com/dotnet/roslyn/issues/44948 + const uint MinExp = 0x3880_0000u; // Minimum exponent for rounding + const uint Exponent126 = 0x3f00_0000u; // Exponent displacement #1 + const uint SingleBiasedExponentMask = 0x7F80_0000; // float.BiasedExponentMask; // Exponent mask + const uint Exponent13 = 0x0680_0000u; // Exponent displacement #2 + const float MaxHalfValueBelowInfinity = 65520.0f; // Maximum value that is not Infinity in Half + const uint ExponentMask = 0x7C00; // Mask for exponent bits in Half + const uint SingleSignMask = 0x8000_0000u; // float.SignMask; // Mask for sign bit in float +#pragma warning restore IDE0059 + + static Vector128 SingleToHalfAsWidenedUInt32_Vector128(Vector128 value) + { + Vector128 bitValue = value.AsUInt32(); - private static float MinMagnitude(float x, float y) => MathF.MinMagnitude(x, y); + // Extract sign bit + Vector128 sign = Vector128.ShiftRightLogical(bitValue & Vector128.Create(SingleSignMask), 16); - private static float Log2(float x) => MathF.Log2(x); + // Detecting NaN (0u if value is NaN; otherwise, ~0u) + Vector128 realMask = Vector128.Equals(value, value).AsUInt32(); - private static float CosineSimilarityCore(ReadOnlySpan x, ReadOnlySpan y) - { - // Compute the same as: - // TensorPrimitives.Dot(x, y) / (Math.Sqrt(TensorPrimitives.SumOfSquares(x)) * Math.Sqrt(TensorPrimitives.SumOfSquares(y))) - // but only looping over each span once. + // Clear sign bit + value = Vector128.Abs(value); - float dotProduct = 0f; - float xSumOfSquares = 0f; - float ySumOfSquares = 0f; + // Rectify values that are Infinity in Half. + value = Vector128.Min(Vector128.Create(MaxHalfValueBelowInfinity), value); - int i = 0; + // Rectify lower exponent + Vector128 exponentOffset0 = Vector128.Max(value, Vector128.Create(MinExp).AsSingle()).AsUInt32(); -#if NET8_0_OR_GREATER - if (Vector512.IsHardwareAccelerated && x.Length >= Vector512.Count) - { - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); + // Extract exponent + exponentOffset0 &= Vector128.Create(SingleBiasedExponentMask); - Vector512 dotProductVector = Vector512.Zero; - Vector512 xSumOfSquaresVector = Vector512.Zero; - Vector512 ySumOfSquaresVector = Vector512.Zero; + // Add exponent by 13 + exponentOffset0 += Vector128.Create(Exponent13); - // Process vectors, summing their dot products and squares, as long as there's a vector's worth remaining. - int oneVectorFromEnd = x.Length - Vector512.Count; - do - { - Vector512 xVec = Vector512.LoadUnsafe(ref xRef, (uint)i); - Vector512 yVec = Vector512.LoadUnsafe(ref yRef, (uint)i); + // Round Single into Half's precision (NaN also gets modified here, just setting the MSB of fraction) + value += exponentOffset0.AsSingle(); + bitValue = value.AsUInt32(); - dotProductVector += xVec * yVec; - xSumOfSquaresVector += xVec * xVec; - ySumOfSquaresVector += yVec * yVec; + // Only exponent bits will be modified if NaN + Vector128 maskedHalfExponentForNaN = ~realMask & Vector128.Create(ExponentMask); - i += Vector512.Count; - } - while (i <= oneVectorFromEnd); + // Subtract exponent by 126 + bitValue -= Vector128.Create(Exponent126); - // Sum the vector lanes into the scalar result. - dotProduct += Vector512.Sum(dotProductVector); - xSumOfSquares += Vector512.Sum(xSumOfSquaresVector); - ySumOfSquares += Vector512.Sum(ySumOfSquaresVector); - } - else -#endif - if (Vector256.IsHardwareAccelerated && x.Length >= Vector256.Count) - { - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); + // Shift bitValue right by 13 bits to match the boundary of exponent part and fraction part. + Vector128 newExponent = Vector128.ShiftRightLogical(bitValue, 13); - Vector256 dotProductVector = Vector256.Zero; - Vector256 xSumOfSquaresVector = Vector256.Zero; - Vector256 ySumOfSquaresVector = Vector256.Zero; + // Clear the fraction parts if the value was NaN. + bitValue &= realMask; - // Process vectors, summing their dot products and squares, as long as there's a vector's worth remaining. - int oneVectorFromEnd = x.Length - Vector256.Count; - do - { - Vector256 xVec = Vector256.LoadUnsafe(ref xRef, (uint)i); - Vector256 yVec = Vector256.LoadUnsafe(ref yRef, (uint)i); + // Merge the exponent part with fraction part, and add the exponent part and fraction part's overflow. + bitValue += newExponent; - dotProductVector += xVec * yVec; - xSumOfSquaresVector += xVec * xVec; - ySumOfSquaresVector += yVec * yVec; + // Clear exponents if value is NaN + bitValue &= ~maskedHalfExponentForNaN; - i += Vector256.Count; - } - while (i <= oneVectorFromEnd); + // Merge sign bit with possible NaN exponent + Vector128 signAndMaskedExponent = maskedHalfExponentForNaN | sign; - // Sum the vector lanes into the scalar result. - dotProduct += Vector256.Sum(dotProductVector); - xSumOfSquares += Vector256.Sum(xSumOfSquaresVector); - ySumOfSquares += Vector256.Sum(ySumOfSquaresVector); + // Merge sign bit and possible NaN exponent + bitValue |= signAndMaskedExponent; + + // The final result + return bitValue; } - else if (Vector128.IsHardwareAccelerated && x.Length >= Vector128.Count) + + static Vector256 SingleToHalfAsWidenedUInt32_Vector256(Vector256 value) { - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); + Vector256 bitValue = value.AsUInt32(); - Vector128 dotProductVector = Vector128.Zero; - Vector128 xSumOfSquaresVector = Vector128.Zero; - Vector128 ySumOfSquaresVector = Vector128.Zero; + // Extract sign bit + Vector256 sign = Vector256.ShiftRightLogical(bitValue & Vector256.Create(SingleSignMask), 16); - // Process vectors, summing their dot products and squares, as long as there's a vector's worth remaining. - int oneVectorFromEnd = x.Length - Vector128.Count; - do - { - Vector128 xVec = Vector128.LoadUnsafe(ref xRef, (uint)i); - Vector128 yVec = Vector128.LoadUnsafe(ref yRef, (uint)i); + // Detecting NaN (0u if value is NaN; otherwise, ~0u) + Vector256 realMask = Vector256.Equals(value, value).AsUInt32(); - dotProductVector += xVec * yVec; - xSumOfSquaresVector += xVec * xVec; - ySumOfSquaresVector += yVec * yVec; + // Clear sign bit + value = Vector256.Abs(value); - i += Vector128.Count; - } - while (i <= oneVectorFromEnd); + // Rectify values that are Infinity in Half. + value = Vector256.Min(Vector256.Create(MaxHalfValueBelowInfinity), value); - // Sum the vector lanes into the scalar result. - dotProduct += Vector128.Sum(dotProductVector); - xSumOfSquares += Vector128.Sum(xSumOfSquaresVector); - ySumOfSquares += Vector128.Sum(ySumOfSquaresVector); - } + // Rectify lower exponent + Vector256 exponentOffset0 = Vector256.Max(value, Vector256.Create(MinExp).AsSingle()).AsUInt32(); - // Process any remaining elements past the last vector. - for (; (uint)i < (uint)x.Length; i++) - { - dotProduct += x[i] * y[i]; - xSumOfSquares += x[i] * x[i]; - ySumOfSquares += y[i] * y[i]; - } + // Extract exponent + exponentOffset0 &= Vector256.Create(SingleBiasedExponentMask); - // Sum(X * Y) / (|X| * |Y|) - return dotProduct / (MathF.Sqrt(xSumOfSquares) * MathF.Sqrt(ySumOfSquares)); - } + // Add exponent by 13 + exponentOffset0 += Vector256.Create(Exponent13); - private static float Aggregate( - float identityValue, ReadOnlySpan x) - where TLoad : IUnaryOperator - where TAggregate : IBinaryOperator - { - // Initialize the result to the identity value - float result = identityValue; - int i = 0; + // Round Single into Half's precision (NaN also gets modified here, just setting the MSB of fraction) + value += exponentOffset0.AsSingle(); + bitValue = value.AsUInt32(); -#if NET8_0_OR_GREATER - if (Vector512.IsHardwareAccelerated && x.Length >= Vector512.Count * 2) - { - ref float xRef = ref MemoryMarshal.GetReference(x); + // Only exponent bits will be modified if NaN + Vector256 maskedHalfExponentForNaN = ~realMask & Vector256.Create(ExponentMask); - // Load the first vector as the initial set of results - Vector512 resultVector = TLoad.Invoke(Vector512.LoadUnsafe(ref xRef, 0)); - int oneVectorFromEnd = x.Length - Vector512.Count; + // Subtract exponent by 126 + bitValue -= Vector256.Create(Exponent126); - // Aggregate additional vectors into the result as long as there's at - // least one full vector left to process. - i = Vector512.Count; - do - { - resultVector = TAggregate.Invoke(resultVector, TLoad.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i))); - i += Vector512.Count; - } - while (i <= oneVectorFromEnd); + // Shift bitValue right by 13 bits to match the boundary of exponent part and fraction part. + Vector256 newExponent = Vector256.ShiftRightLogical(bitValue, 13); - // Aggregate the lanes in the vector back into the scalar result - result = TAggregate.Invoke(result, TAggregate.Invoke(resultVector)); - } - else -#endif - if (Vector256.IsHardwareAccelerated && x.Length >= Vector256.Count * 2) - { - ref float xRef = ref MemoryMarshal.GetReference(x); + // Clear the fraction parts if the value was NaN. + bitValue &= realMask; - // Load the first vector as the initial set of results - Vector256 resultVector = TLoad.Invoke(Vector256.LoadUnsafe(ref xRef, 0)); - int oneVectorFromEnd = x.Length - Vector256.Count; + // Merge the exponent part with fraction part, and add the exponent part and fraction part's overflow. + bitValue += newExponent; - // Aggregate additional vectors into the result as long as there's at - // least one full vector left to process. - i = Vector256.Count; - do - { - resultVector = TAggregate.Invoke(resultVector, TLoad.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i))); - i += Vector256.Count; - } - while (i <= oneVectorFromEnd); + // Clear exponents if value is NaN + bitValue &= ~maskedHalfExponentForNaN; + + // Merge sign bit with possible NaN exponent + Vector256 signAndMaskedExponent = maskedHalfExponentForNaN | sign; - // Aggregate the lanes in the vector back into the scalar result - result = TAggregate.Invoke(result, TAggregate.Invoke(resultVector)); + // Merge sign bit and possible NaN exponent + bitValue |= signAndMaskedExponent; + + // The final result + return bitValue; } - else if (Vector128.IsHardwareAccelerated && x.Length >= Vector128.Count * 2) + +#if NET8_0_OR_GREATER + static Vector512 SingleToHalfAsWidenedUInt32_Vector512(Vector512 value) { - ref float xRef = ref MemoryMarshal.GetReference(x); + Vector512 bitValue = value.AsUInt32(); - // Load the first vector as the initial set of results - Vector128 resultVector = TLoad.Invoke(Vector128.LoadUnsafe(ref xRef, 0)); - int oneVectorFromEnd = x.Length - Vector128.Count; + // Extract sign bit + Vector512 sign = Vector512.ShiftRightLogical(bitValue & Vector512.Create(SingleSignMask), 16); - // Aggregate additional vectors into the result as long as there's at - // least one full vector left to process. - i = Vector128.Count; - do - { - resultVector = TAggregate.Invoke(resultVector, TLoad.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i))); - i += Vector128.Count; - } - while (i <= oneVectorFromEnd); + // Detecting NaN (0u if value is NaN; otherwise, ~0u) + Vector512 realMask = Vector512.Equals(value, value).AsUInt32(); - // Aggregate the lanes in the vector back into the scalar result - result = TAggregate.Invoke(result, TAggregate.Invoke(resultVector)); - } + // Clear sign bit + value = Vector512.Abs(value); - // Aggregate the remaining items in the input span. - for (; (uint)i < (uint)x.Length; i++) - { - result = TAggregate.Invoke(result, TLoad.Invoke(x[i])); - } + // Rectify values that are Infinity in Half. + value = Vector512.Min(Vector512.Create(MaxHalfValueBelowInfinity), value); - return result; - } + // Rectify lower exponent + Vector512 exponentOffset0 = Vector512.Max(value, Vector512.Create(MinExp).AsSingle()).AsUInt32(); - private static float Aggregate( - float identityValue, ReadOnlySpan x, ReadOnlySpan y) - where TBinary : IBinaryOperator - where TAggregate : IBinaryOperator - { - // Initialize the result to the identity value - float result = identityValue; - int i = 0; + // Extract exponent + exponentOffset0 &= Vector512.Create(SingleBiasedExponentMask); -#if NET8_0_OR_GREATER - if (Vector512.IsHardwareAccelerated && x.Length >= Vector512.Count * 2) - { - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); + // Add exponent by 13 + exponentOffset0 += Vector512.Create(Exponent13); - // Load the first vector as the initial set of results - Vector512 resultVector = TBinary.Invoke(Vector512.LoadUnsafe(ref xRef, 0), Vector512.LoadUnsafe(ref yRef, 0)); - int oneVectorFromEnd = x.Length - Vector512.Count; + // Round Single into Half's precision (NaN also gets modified here, just setting the MSB of fraction) + value += exponentOffset0.AsSingle(); + bitValue = value.AsUInt32(); - // Aggregate additional vectors into the result as long as there's at - // least one full vector left to process. - i = Vector512.Count; - do - { - resultVector = TAggregate.Invoke(resultVector, TBinary.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i), Vector512.LoadUnsafe(ref yRef, (uint)i))); - i += Vector512.Count; - } - while (i <= oneVectorFromEnd); + // Only exponent bits will be modified if NaN + Vector512 maskedHalfExponentForNaN = ~realMask & Vector512.Create(ExponentMask); - // Aggregate the lanes in the vector back into the scalar result - result = TAggregate.Invoke(result, TAggregate.Invoke(resultVector)); - } - else -#endif - if (Vector256.IsHardwareAccelerated && x.Length >= Vector256.Count * 2) - { - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); + // Subtract exponent by 126 + bitValue -= Vector512.Create(Exponent126); - // Load the first vector as the initial set of results - Vector256 resultVector = TBinary.Invoke(Vector256.LoadUnsafe(ref xRef, 0), Vector256.LoadUnsafe(ref yRef, 0)); - int oneVectorFromEnd = x.Length - Vector256.Count; + // Shift bitValue right by 13 bits to match the boundary of exponent part and fraction part. + Vector512 newExponent = Vector512.ShiftRightLogical(bitValue, 13); - // Aggregate additional vectors into the result as long as there's at - // least one full vector left to process. - i = Vector256.Count; - do - { - resultVector = TAggregate.Invoke(resultVector, TBinary.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i), Vector256.LoadUnsafe(ref yRef, (uint)i))); - i += Vector256.Count; - } - while (i <= oneVectorFromEnd); + // Clear the fraction parts if the value was NaN. + bitValue &= realMask; - // Aggregate the lanes in the vector back into the scalar result - result = TAggregate.Invoke(result, TAggregate.Invoke(resultVector)); - } - else if (Vector128.IsHardwareAccelerated && x.Length >= Vector128.Count * 2) - { - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); + // Merge the exponent part with fraction part, and add the exponent part and fraction part's overflow. + bitValue += newExponent; - // Load the first vector as the initial set of results - Vector128 resultVector = TBinary.Invoke(Vector128.LoadUnsafe(ref xRef, 0), Vector128.LoadUnsafe(ref yRef, 0)); - int oneVectorFromEnd = x.Length - Vector128.Count; + // Clear exponents if value is NaN + bitValue &= ~maskedHalfExponentForNaN; - // Aggregate additional vectors into the result as long as there's at - // least one full vector left to process. - i = Vector128.Count; - do - { - resultVector = TAggregate.Invoke(resultVector, TBinary.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i), Vector128.LoadUnsafe(ref yRef, (uint)i))); - i += Vector128.Count; - } - while (i <= oneVectorFromEnd); + // Merge sign bit with possible NaN exponent + Vector512 signAndMaskedExponent = maskedHalfExponentForNaN | sign; - // Aggregate the lanes in the vector back into the scalar result - result = TAggregate.Invoke(result, TAggregate.Invoke(resultVector)); - } + // Merge sign bit and possible NaN exponent + bitValue |= signAndMaskedExponent; - // Aggregate the remaining items in the input span. - for (; (uint)i < (uint)x.Length; i++) - { - result = TAggregate.Invoke(result, TBinary.Invoke(x[i], y[i])); + // The final result + return bitValue; } - - return result; +#endif } - private static unsafe void InvokeSpanIntoSpan( - ReadOnlySpan x, Span destination) - where TUnaryOperator : IUnaryOperator + /// + /// Copies to , converting each half-precision + /// floating-point value to its nearest representable value. + /// + /// The source span from which to copy values. + /// The destination span into which the converted values should be written. + /// Destination is too short. + /// + /// + /// This method effectively computes [i] = (float)[i]. + /// + /// + /// and must not overlap. If they do, behavior is undefined. + /// + /// + public static void ConvertToSingle(ReadOnlySpan source, Span destination) { - if (x.Length > destination.Length) + if (source.Length > destination.Length) { ThrowHelper.ThrowArgument_DestinationTooShort(); } - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float dRef = ref MemoryMarshal.GetReference(destination); + ref short sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); + ref float destinationRef = ref MemoryMarshal.GetReference(destination); int i = 0, oneVectorFromEnd; #if NET8_0_OR_GREATER if (Vector512.IsHardwareAccelerated) { - oneVectorFromEnd = x.Length - Vector512.Count; + oneVectorFromEnd = source.Length - Vector512.Count; if (i <= oneVectorFromEnd) { - // Loop handling one vector at a time. + // Loop handling one input vector / two output vectors at a time. do { - TUnaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + (Vector512 lower, Vector512 upper) = Vector512.Widen(Vector512.LoadUnsafe(ref sourceRef, (uint)i)); + HalfAsWidenedUInt32ToSingle_Vector512(lower.AsUInt32()).StoreUnsafe(ref destinationRef, (uint)i); + HalfAsWidenedUInt32ToSingle_Vector512(upper.AsUInt32()).StoreUnsafe(ref destinationRef, (uint)(i + Vector512.Count)); - i += Vector512.Count; + i += Vector512.Count; } while (i <= oneVectorFromEnd); - // Handle any remaining elements with a final vector. - if (i != x.Length) + // Handle any remaining elements with a final input vector. + if (i != source.Length) { - uint lastVectorIndex = (uint)(x.Length - Vector512.Count); - TUnaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + i = source.Length - Vector512.Count; + + (Vector512 lower, Vector512 upper) = Vector512.Widen(Vector512.LoadUnsafe(ref sourceRef, (uint)i)); + HalfAsWidenedUInt32ToSingle_Vector512(lower.AsUInt32()).StoreUnsafe(ref destinationRef, (uint)i); + HalfAsWidenedUInt32ToSingle_Vector512(upper.AsUInt32()).StoreUnsafe(ref destinationRef, (uint)(i + Vector512.Count)); } return; @@ -387,23 +407,28 @@ private static unsafe void InvokeSpanIntoSpan( if (Vector256.IsHardwareAccelerated) { - oneVectorFromEnd = x.Length - Vector256.Count; + oneVectorFromEnd = source.Length - Vector256.Count; if (i <= oneVectorFromEnd) { - // Loop handling one vector at a time. + // Loop handling one input vector / two output vectors at a time. do { - TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + (Vector256 lower, Vector256 upper) = Vector256.Widen(Vector256.LoadUnsafe(ref sourceRef, (uint)i)); + HalfAsWidenedUInt32ToSingle_Vector256(lower.AsUInt32()).StoreUnsafe(ref destinationRef, (uint)i); + HalfAsWidenedUInt32ToSingle_Vector256(upper.AsUInt32()).StoreUnsafe(ref destinationRef, (uint)(i + Vector256.Count)); - i += Vector256.Count; + i += Vector256.Count; } while (i <= oneVectorFromEnd); - // Handle any remaining elements with a final vector. - if (i != x.Length) + // Handle any remaining elements with a final input vector. + if (i != source.Length) { - uint lastVectorIndex = (uint)(x.Length - Vector256.Count); - TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + i = source.Length - Vector256.Count; + + (Vector256 lower, Vector256 upper) = Vector256.Widen(Vector256.LoadUnsafe(ref sourceRef, (uint)i)); + HalfAsWidenedUInt32ToSingle_Vector256(lower.AsUInt32()).StoreUnsafe(ref destinationRef, (uint)i); + HalfAsWidenedUInt32ToSingle_Vector256(upper.AsUInt32()).StoreUnsafe(ref destinationRef, (uint)(i + Vector256.Count)); } return; @@ -412,832 +437,11129 @@ private static unsafe void InvokeSpanIntoSpan( if (Vector128.IsHardwareAccelerated) { - oneVectorFromEnd = x.Length - Vector128.Count; + oneVectorFromEnd = source.Length - Vector128.Count; if (i <= oneVectorFromEnd) { - // Loop handling one vector at a time. + // Loop handling one input vector / two output vectors at a time. do { - TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + (Vector128 lower, Vector128 upper) = Vector128.Widen(Vector128.LoadUnsafe(ref sourceRef, (uint)i)); + HalfAsWidenedUInt32ToSingle_Vector128(lower.AsUInt32()).StoreUnsafe(ref destinationRef, (uint)i); + HalfAsWidenedUInt32ToSingle_Vector128(upper.AsUInt32()).StoreUnsafe(ref destinationRef, (uint)(i + Vector128.Count)); - i += Vector128.Count; + i += Vector128.Count; } while (i <= oneVectorFromEnd); - // Handle any remaining elements with a final vector. - if (i != x.Length) + // Handle any remaining elements with a final input vector. + if (i != source.Length) { - uint lastVectorIndex = (uint)(x.Length - Vector128.Count); - TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); + i = source.Length - Vector128.Count; + + (Vector128 lower, Vector128 upper) = Vector128.Widen(Vector128.LoadUnsafe(ref sourceRef, (uint)i)); + HalfAsWidenedUInt32ToSingle_Vector128(lower.AsUInt32()).StoreUnsafe(ref destinationRef, (uint)i); + HalfAsWidenedUInt32ToSingle_Vector128(upper.AsUInt32()).StoreUnsafe(ref destinationRef, (uint)(i + Vector128.Count)); } return; } } - while (i < x.Length) + while (i < source.Length) { - Unsafe.Add(ref dRef, i) = TUnaryOperator.Invoke(Unsafe.Add(ref xRef, i)); - + Unsafe.Add(ref destinationRef, i) = (float)Unsafe.As(ref Unsafe.Add(ref sourceRef, i)); i++; } - } - private static unsafe void InvokeSpanSpanIntoSpan( - ReadOnlySpan x, ReadOnlySpan y, Span destination) - where TBinaryOperator : IBinaryOperator - { - if (x.Length != y.Length) + // This implements a vectorized version of the `explicit operator float(Half value) operator`. + // See detailed description of the algorithm used here: + // https://github.com/dotnet/runtime/blob/3bf40a378f00cb5bf18ff62796bc7097719b974c/src/libraries/System.Private.CoreLib/src/System/Half.cs#L1010-L1040 + // The cast operator converts a Half represented as uint to a float. This does the same, with an input VectorXx and an output VectorXx. + // The VectorXx is created by reading a vector of Halfs as a VectorXx then widened to two VectorXxs and cast to VectorXxs. + // We loop handling one input vector at a time, producing two output float vectors. + +#pragma warning disable IDE0059 // https://github.com/dotnet/roslyn/issues/44948 + const uint ExponentLowerBound = 0x3880_0000u; // The smallest positive normal number in Half, converted to Single + const uint ExponentOffset = 0x3800_0000u; // BitConverter.SingleToUInt32Bits(1.0f) - ((uint)BitConverter.HalfToUInt16Bits((Half)1.0f) << 13) + const uint SingleSignMask = 0x8000_0000; // float.SignMask; // Mask for sign bit in Single + const uint HalfExponentMask = 0x7C00; // Mask for exponent bits in Half + const uint HalfToSingleBitsMask = 0x0FFF_E000; // Mask for bits in Single converted from Half +#pragma warning restore IDE0059 + + static Vector128 HalfAsWidenedUInt32ToSingle_Vector128(Vector128 value) { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); - } + // Extract sign bit of value + Vector128 sign = value & Vector128.Create(SingleSignMask); - if (x.Length > destination.Length) - { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } + // Copy sign bit to upper bits + Vector128 bitValueInProcess = value; - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); - ref float dRef = ref MemoryMarshal.GetReference(destination); - int i = 0, oneVectorFromEnd; + // Extract exponent bits of value (BiasedExponent is not for here as it performs unnecessary shift) + Vector128 offsetExponent = bitValueInProcess & Vector128.Create(HalfExponentMask); -#if NET8_0_OR_GREATER - if (Vector512.IsHardwareAccelerated) - { - oneVectorFromEnd = x.Length - Vector512.Count; - if (i <= oneVectorFromEnd) - { - // Loop handling one vector at a time. - do - { - TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i), - Vector512.LoadUnsafe(ref yRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + // ~0u when value is subnormal, 0 otherwise + Vector128 subnormalMask = Vector128.Equals(offsetExponent, Vector128.Zero); - i += Vector512.Count; - } - while (i <= oneVectorFromEnd); + // ~0u when value is either Infinity or NaN, 0 otherwise + Vector128 infinityOrNaNMask = Vector128.Equals(offsetExponent, Vector128.Create(HalfExponentMask)); - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector512.Count); - TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, lastVectorIndex), - Vector512.LoadUnsafe(ref yRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); - } + // 0x3880_0000u if value is subnormal, 0 otherwise + Vector128 maskedExponentLowerBound = subnormalMask & Vector128.Create(ExponentLowerBound); - return; - } - } -#endif + // 0x3880_0000u if value is subnormal, 0x3800_0000u otherwise + Vector128 offsetMaskedExponentLowerBound = Vector128.Create(ExponentOffset) | maskedExponentLowerBound; - if (Vector256.IsHardwareAccelerated) - { - oneVectorFromEnd = x.Length - Vector256.Count; - if (i <= oneVectorFromEnd) - { - // Loop handling one vector at a time. - do - { - TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i), - Vector256.LoadUnsafe(ref yRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + // Match the position of the boundary of exponent bits and fraction bits with IEEE 754 Binary32(Single) + bitValueInProcess = Vector128.ShiftLeft(bitValueInProcess, 13); - i += Vector256.Count; - } - while (i <= oneVectorFromEnd); + // Double the offsetMaskedExponentLowerBound if value is either Infinity or NaN + offsetMaskedExponentLowerBound = Vector128.ConditionalSelect(Vector128.Equals(infinityOrNaNMask, Vector128.Zero), + offsetMaskedExponentLowerBound, + Vector128.ShiftLeft(offsetMaskedExponentLowerBound, 1)); - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector256.Count); - TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, lastVectorIndex), - Vector256.LoadUnsafe(ref yRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); - } + // Extract exponent bits and fraction bits of value + bitValueInProcess &= Vector128.Create(HalfToSingleBitsMask); - return; - } + // Adjust exponent to match the range of exponent + bitValueInProcess += offsetMaskedExponentLowerBound; + + // If value is subnormal, remove unnecessary 1 on top of fraction bits. + Vector128 absoluteValue = (bitValueInProcess.AsSingle() - maskedExponentLowerBound.AsSingle()).AsUInt32(); + + // Merge sign bit with rest + return (absoluteValue | sign).AsSingle(); } - if (Vector128.IsHardwareAccelerated) + static Vector256 HalfAsWidenedUInt32ToSingle_Vector256(Vector256 value) { - oneVectorFromEnd = x.Length - Vector128.Count; - if (i <= oneVectorFromEnd) - { - // Loop handling one vector at a time. - do - { - TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i), - Vector128.LoadUnsafe(ref yRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + // Extract sign bit of value + Vector256 sign = value & Vector256.Create(SingleSignMask); - i += Vector128.Count; - } - while (i <= oneVectorFromEnd); + // Copy sign bit to upper bits + Vector256 bitValueInProcess = value; - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector128.Count); - TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, lastVectorIndex), - Vector128.LoadUnsafe(ref yRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); - } + // Extract exponent bits of value (BiasedExponent is not for here as it performs unnecessary shift) + Vector256 offsetExponent = bitValueInProcess & Vector256.Create(HalfExponentMask); - return; - } + // ~0u when value is subnormal, 0 otherwise + Vector256 subnormalMask = Vector256.Equals(offsetExponent, Vector256.Zero); + + // ~0u when value is either Infinity or NaN, 0 otherwise + Vector256 infinityOrNaNMask = Vector256.Equals(offsetExponent, Vector256.Create(HalfExponentMask)); + + // 0x3880_0000u if value is subnormal, 0 otherwise + Vector256 maskedExponentLowerBound = subnormalMask & Vector256.Create(ExponentLowerBound); + + // 0x3880_0000u if value is subnormal, 0x3800_0000u otherwise + Vector256 offsetMaskedExponentLowerBound = Vector256.Create(ExponentOffset) | maskedExponentLowerBound; + + // Match the position of the boundary of exponent bits and fraction bits with IEEE 754 Binary32(Single) + bitValueInProcess = Vector256.ShiftLeft(bitValueInProcess, 13); + + // Double the offsetMaskedExponentLowerBound if value is either Infinity or NaN + offsetMaskedExponentLowerBound = Vector256.ConditionalSelect(Vector256.Equals(infinityOrNaNMask, Vector256.Zero), + offsetMaskedExponentLowerBound, + Vector256.ShiftLeft(offsetMaskedExponentLowerBound, 1)); + + // Extract exponent bits and fraction bits of value + bitValueInProcess &= Vector256.Create(HalfToSingleBitsMask); + + // Adjust exponent to match the range of exponent + bitValueInProcess += offsetMaskedExponentLowerBound; + + // If value is subnormal, remove unnecessary 1 on top of fraction bits. + Vector256 absoluteValue = (bitValueInProcess.AsSingle() - maskedExponentLowerBound.AsSingle()).AsUInt32(); + + // Merge sign bit with rest + return (absoluteValue | sign).AsSingle(); } - while (i < x.Length) +#if NET8_0_OR_GREATER + static Vector512 HalfAsWidenedUInt32ToSingle_Vector512(Vector512 value) { - Unsafe.Add(ref dRef, i) = TBinaryOperator.Invoke(Unsafe.Add(ref xRef, i), - Unsafe.Add(ref yRef, i)); + // Extract sign bit of value + Vector512 sign = value & Vector512.Create(SingleSignMask); - i++; + // Copy sign bit to upper bits + Vector512 bitValueInProcess = value; + + // Extract exponent bits of value (BiasedExponent is not for here as it performs unnecessary shift) + Vector512 offsetExponent = bitValueInProcess & Vector512.Create(HalfExponentMask); + + // ~0u when value is subnormal, 0 otherwise + Vector512 subnormalMask = Vector512.Equals(offsetExponent, Vector512.Zero); + + // ~0u when value is either Infinity or NaN, 0 otherwise + Vector512 infinityOrNaNMask = Vector512.Equals(offsetExponent, Vector512.Create(HalfExponentMask)); + + // 0x3880_0000u if value is subnormal, 0 otherwise + Vector512 maskedExponentLowerBound = subnormalMask & Vector512.Create(ExponentLowerBound); + + // 0x3880_0000u if value is subnormal, 0x3800_0000u otherwise + Vector512 offsetMaskedExponentLowerBound = Vector512.Create(ExponentOffset) | maskedExponentLowerBound; + + // Match the position of the boundary of exponent bits and fraction bits with IEEE 754 Binary32(Single) + bitValueInProcess = Vector512.ShiftLeft(bitValueInProcess, 13); + + // Double the offsetMaskedExponentLowerBound if value is either Infinity or NaN + offsetMaskedExponentLowerBound = Vector512.ConditionalSelect(Vector512.Equals(infinityOrNaNMask, Vector512.Zero), + offsetMaskedExponentLowerBound, + Vector512.ShiftLeft(offsetMaskedExponentLowerBound, 1)); + + // Extract exponent bits and fraction bits of value + bitValueInProcess &= Vector512.Create(HalfToSingleBitsMask); + + // Adjust exponent to match the range of exponent + bitValueInProcess += offsetMaskedExponentLowerBound; + + // If value is subnormal, remove unnecessary 1 on top of fraction bits. + Vector512 absoluteValue = (bitValueInProcess.AsSingle() - maskedExponentLowerBound.AsSingle()).AsUInt32(); + + // Merge sign bit with rest + return (absoluteValue | sign).AsSingle(); } +#endif } - private static unsafe void InvokeSpanScalarIntoSpan( - ReadOnlySpan x, float y, Span destination) - where TBinaryOperator : IBinaryOperator + /// Computes the cosine similarity between the two specified non-empty, equal-length tensors of single-precision floating-point numbers. + /// Assumes arguments have already been validated to be non-empty and equal length. + private static float CosineSimilarityCore(ReadOnlySpan x, ReadOnlySpan y) { - if (x.Length > destination.Length) - { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } - - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float dRef = ref MemoryMarshal.GetReference(destination); - int i = 0, oneVectorFromEnd; + // Compute the same as: + // TensorPrimitives.Dot(x, y) / (Math.Sqrt(TensorPrimitives.SumOfSquares(x)) * Math.Sqrt(TensorPrimitives.SumOfSquares(y))) + // but only looping over each span once. #if NET8_0_OR_GREATER - if (Vector512.IsHardwareAccelerated) + if (Vector512.IsHardwareAccelerated && x.Length >= Vector512.Count) { - oneVectorFromEnd = x.Length - Vector512.Count; - if (i <= oneVectorFromEnd) + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + + Vector512 dotProductVector = Vector512.Zero; + Vector512 xSumOfSquaresVector = Vector512.Zero; + Vector512 ySumOfSquaresVector = Vector512.Zero; + + // Process vectors, summing their dot products and squares, as long as there's a vector's worth remaining. + int oneVectorFromEnd = x.Length - Vector512.Count; + int i = 0; + do { - Vector512 yVec = Vector512.Create(y); + Vector512 xVec = Vector512.LoadUnsafe(ref xRef, (uint)i); + Vector512 yVec = Vector512.LoadUnsafe(ref yRef, (uint)i); - // Loop handling one vector at a time. - do - { - TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i), - yVec).StoreUnsafe(ref dRef, (uint)i); + dotProductVector = FusedMultiplyAdd(xVec, yVec, dotProductVector); + xSumOfSquaresVector = FusedMultiplyAdd(xVec, xVec, xSumOfSquaresVector); + ySumOfSquaresVector = FusedMultiplyAdd(yVec, yVec, ySumOfSquaresVector); - i += Vector512.Count; - } - while (i <= oneVectorFromEnd); + i += Vector512.Count; + } + while (i <= oneVectorFromEnd); - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector512.Count); - TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, lastVectorIndex), - yVec).StoreUnsafe(ref dRef, lastVectorIndex); - } + // Process the last vector in the span, masking off elements already processed. + if (i != x.Length) + { + Vector512 xVec = Vector512.LoadUnsafe(ref xRef, (uint)(x.Length - Vector512.Count)); + Vector512 yVec = Vector512.LoadUnsafe(ref yRef, (uint)(x.Length - Vector512.Count)); - return; + Vector512 remainderMask = CreateRemainderMaskSingleVector512(x.Length - i); + xVec &= remainderMask; + yVec &= remainderMask; + + dotProductVector = FusedMultiplyAdd(xVec, yVec, dotProductVector); + xSumOfSquaresVector = FusedMultiplyAdd(xVec, xVec, xSumOfSquaresVector); + ySumOfSquaresVector = FusedMultiplyAdd(yVec, yVec, ySumOfSquaresVector); } + + // Sum(X * Y) / (|X| * |Y|) + return + Vector512.Sum(dotProductVector) / + (MathF.Sqrt(Vector512.Sum(xSumOfSquaresVector)) * MathF.Sqrt(Vector512.Sum(ySumOfSquaresVector))); } #endif - if (Vector256.IsHardwareAccelerated) + if (Vector256.IsHardwareAccelerated && x.Length >= Vector256.Count) { - oneVectorFromEnd = x.Length - Vector256.Count; - if (i <= oneVectorFromEnd) + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + + Vector256 dotProductVector = Vector256.Zero; + Vector256 xSumOfSquaresVector = Vector256.Zero; + Vector256 ySumOfSquaresVector = Vector256.Zero; + + // Process vectors, summing their dot products and squares, as long as there's a vector's worth remaining. + int oneVectorFromEnd = x.Length - Vector256.Count; + int i = 0; + do { - Vector256 yVec = Vector256.Create(y); + Vector256 xVec = Vector256.LoadUnsafe(ref xRef, (uint)i); + Vector256 yVec = Vector256.LoadUnsafe(ref yRef, (uint)i); - // Loop handling one vector at a time. - do - { - TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i), - yVec).StoreUnsafe(ref dRef, (uint)i); + dotProductVector = FusedMultiplyAdd(xVec, yVec, dotProductVector); + xSumOfSquaresVector = FusedMultiplyAdd(xVec, xVec, xSumOfSquaresVector); + ySumOfSquaresVector = FusedMultiplyAdd(yVec, yVec, ySumOfSquaresVector); - i += Vector256.Count; - } - while (i <= oneVectorFromEnd); + i += Vector256.Count; + } + while (i <= oneVectorFromEnd); - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector256.Count); - TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, lastVectorIndex), - yVec).StoreUnsafe(ref dRef, lastVectorIndex); - } + // Process the last vector in the span, masking off elements already processed. + if (i != x.Length) + { + Vector256 xVec = Vector256.LoadUnsafe(ref xRef, (uint)(x.Length - Vector256.Count)); + Vector256 yVec = Vector256.LoadUnsafe(ref yRef, (uint)(x.Length - Vector256.Count)); - return; + Vector256 remainderMask = CreateRemainderMaskSingleVector256(x.Length - i); + xVec &= remainderMask; + yVec &= remainderMask; + + dotProductVector = FusedMultiplyAdd(xVec, yVec, dotProductVector); + xSumOfSquaresVector = FusedMultiplyAdd(xVec, xVec, xSumOfSquaresVector); + ySumOfSquaresVector = FusedMultiplyAdd(yVec, yVec, ySumOfSquaresVector); } + + // Sum(X * Y) / (|X| * |Y|) + return + Vector256.Sum(dotProductVector) / + (MathF.Sqrt(Vector256.Sum(xSumOfSquaresVector)) * MathF.Sqrt(Vector256.Sum(ySumOfSquaresVector))); } - if (Vector128.IsHardwareAccelerated) + if (Vector128.IsHardwareAccelerated && x.Length >= Vector128.Count) { - oneVectorFromEnd = x.Length - Vector128.Count; - if (i <= oneVectorFromEnd) + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + + Vector128 dotProductVector = Vector128.Zero; + Vector128 xSumOfSquaresVector = Vector128.Zero; + Vector128 ySumOfSquaresVector = Vector128.Zero; + + // Process vectors, summing their dot products and squares, as long as there's a vector's worth remaining. + int oneVectorFromEnd = x.Length - Vector128.Count; + int i = 0; + do { - Vector128 yVec = Vector128.Create(y); + Vector128 xVec = Vector128.LoadUnsafe(ref xRef, (uint)i); + Vector128 yVec = Vector128.LoadUnsafe(ref yRef, (uint)i); - // Loop handling one vector at a time. - do - { - TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i), - yVec).StoreUnsafe(ref dRef, (uint)i); + dotProductVector = FusedMultiplyAdd(xVec, yVec, dotProductVector); + xSumOfSquaresVector = FusedMultiplyAdd(xVec, xVec, xSumOfSquaresVector); + ySumOfSquaresVector = FusedMultiplyAdd(yVec, yVec, ySumOfSquaresVector); - i += Vector128.Count; - } - while (i <= oneVectorFromEnd); + i += Vector128.Count; + } + while (i <= oneVectorFromEnd); - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector128.Count); - TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, lastVectorIndex), - yVec).StoreUnsafe(ref dRef, lastVectorIndex); - } + // Process the last vector in the span, masking off elements already processed. + if (i != x.Length) + { + Vector128 xVec = Vector128.LoadUnsafe(ref xRef, (uint)(x.Length - Vector128.Count)); + Vector128 yVec = Vector128.LoadUnsafe(ref yRef, (uint)(x.Length - Vector128.Count)); - return; + Vector128 remainderMask = CreateRemainderMaskSingleVector128(x.Length - i); + xVec &= remainderMask; + yVec &= remainderMask; + + dotProductVector = FusedMultiplyAdd(xVec, yVec, dotProductVector); + xSumOfSquaresVector = FusedMultiplyAdd(xVec, xVec, xSumOfSquaresVector); + ySumOfSquaresVector = FusedMultiplyAdd(yVec, yVec, ySumOfSquaresVector); } + + // Sum(X * Y) / (|X| * |Y|) + return + Vector128.Sum(dotProductVector) / + (MathF.Sqrt(Vector128.Sum(xSumOfSquaresVector)) * MathF.Sqrt(Vector128.Sum(ySumOfSquaresVector))); } - while (i < x.Length) + // Vectorization isn't supported or there are too few elements to vectorize. + // Use a scalar implementation. + float dotProduct = 0f, xSumOfSquares = 0f, ySumOfSquares = 0f; + for (int i = 0; i < x.Length; i++) { - Unsafe.Add(ref dRef, i) = TBinaryOperator.Invoke(Unsafe.Add(ref xRef, i), - y); - - i++; + dotProduct = MathF.FusedMultiplyAdd(x[i], y[i], dotProduct); + xSumOfSquares = MathF.FusedMultiplyAdd(x[i], x[i], xSumOfSquares); + ySumOfSquares = MathF.FusedMultiplyAdd(y[i], y[i], ySumOfSquares); } + + // Sum(X * Y) / (|X| * |Y|) + return + dotProduct / + (MathF.Sqrt(xSumOfSquares) * MathF.Sqrt(ySumOfSquares)); } - private static unsafe void InvokeSpanSpanSpanIntoSpan( - ReadOnlySpan x, ReadOnlySpan y, ReadOnlySpan z, Span destination) - where TTernaryOperator : ITernaryOperator + /// Performs an aggregation over all elements in to produce a single-precision floating-point value. + /// Specifies the transform operation that should be applied to each element loaded from . + /// + /// Specifies the aggregation binary operation that should be applied to multiple values to aggregate them into a single value. + /// The aggregation is applied after the transform is applied to each element. + /// + private static float Aggregate( + ReadOnlySpan x) + where TTransformOperator : struct, IUnaryOperator + where TAggregationOperator : struct, IAggregationOperator { - if (x.Length != y.Length || x.Length != z.Length) - { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); - } - - if (x.Length > destination.Length) - { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } + // Since every branch has a cost and since that cost is + // essentially lost for larger inputs, we do branches + // in a way that allows us to have the minimum possible + // for small sizes ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); - ref float zRef = ref MemoryMarshal.GetReference(z); - ref float dRef = ref MemoryMarshal.GetReference(destination); - int i = 0, oneVectorFromEnd; + + nuint remainder = (uint)(x.Length); #if NET8_0_OR_GREATER if (Vector512.IsHardwareAccelerated) { - oneVectorFromEnd = x.Length - Vector512.Count; - if (i <= oneVectorFromEnd) - { - // Loop handling one vector at a time. - do - { - TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i), - Vector512.LoadUnsafe(ref yRef, (uint)i), - Vector512.LoadUnsafe(ref zRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); - - i += Vector512.Count; - } - while (i <= oneVectorFromEnd); + float result; - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector512.Count); - TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, lastVectorIndex), - Vector512.LoadUnsafe(ref yRef, lastVectorIndex), - Vector512.LoadUnsafe(ref zRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); - } + if (remainder >= (uint)(Vector512.Count)) + { + result = Vectorized512(ref xRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. - return; + result = Vectorized512Small(ref xRef, remainder); } + + return result; } #endif if (Vector256.IsHardwareAccelerated) { - oneVectorFromEnd = x.Length - Vector256.Count; - if (i <= oneVectorFromEnd) - { - // Loop handling one vector at a time. - do - { - TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i), - Vector256.LoadUnsafe(ref yRef, (uint)i), - Vector256.LoadUnsafe(ref zRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); - - i += Vector256.Count; - } - while (i <= oneVectorFromEnd); + float result; - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector256.Count); - TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, lastVectorIndex), - Vector256.LoadUnsafe(ref yRef, lastVectorIndex), - Vector256.LoadUnsafe(ref zRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); - } + if (remainder >= (uint)(Vector256.Count)) + { + result = Vectorized256(ref xRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. - return; + result = Vectorized256Small(ref xRef, remainder); } + + return result; } if (Vector128.IsHardwareAccelerated) { - oneVectorFromEnd = x.Length - Vector128.Count; - if (i <= oneVectorFromEnd) - { - // Loop handling one vector at a time. - do - { - TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i), - Vector128.LoadUnsafe(ref yRef, (uint)i), - Vector128.LoadUnsafe(ref zRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); - - i += Vector128.Count; - } - while (i <= oneVectorFromEnd); + float result; - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector128.Count); - TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, lastVectorIndex), - Vector128.LoadUnsafe(ref yRef, lastVectorIndex), - Vector128.LoadUnsafe(ref zRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); - } + if (remainder >= (uint)(Vector128.Count)) + { + result = Vectorized128(ref xRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. - return; + result = Vectorized128Small(ref xRef, remainder); } + + return result; } - while (i < x.Length) - { - Unsafe.Add(ref dRef, i) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, i), - Unsafe.Add(ref yRef, i), - Unsafe.Add(ref zRef, i)); + // This is the software fallback when no acceleration is available. + // It requires no branches to hit. - i++; - } - } + return SoftwareFallback(ref xRef, remainder); - private static unsafe void InvokeSpanSpanScalarIntoSpan( - ReadOnlySpan x, ReadOnlySpan y, float z, Span destination) - where TTernaryOperator : ITernaryOperator - { - if (x.Length != y.Length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static float SoftwareFallback(ref float xRef, nuint length) { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + float result = TAggregationOperator.IdentityValue; + + for (nuint i = 0; i < length; i++) + { + result = TAggregationOperator.Invoke(result, TTransformOperator.Invoke(Unsafe.Add(ref xRef, i))); + } + + return result; } - if (x.Length > destination.Length) + static float Vectorized128(ref float xRef, nuint remainder) { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } + Vector128 vresult = Vector128.Create(TAggregationOperator.IdentityValue); - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); - ref float dRef = ref MemoryMarshal.GetReference(destination); - int i = 0, oneVectorFromEnd; + // Preload the beginning and end so that overlapping accesses don't negatively impact the data -#if NET8_0_OR_GREATER - if (Vector512.IsHardwareAccelerated) - { - oneVectorFromEnd = x.Length - Vector512.Count; - if (i <= oneVectorFromEnd) + Vector128 beg = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef)); + Vector128 end = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count))); + + nuint misalignment = 0; + + if (remainder > (uint)(Vector128.Count * 8)) { - Vector512 zVec = Vector512.Create(z); + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. - // Loop handling one vector at a time. - do + fixed (float* px = &xRef) { - TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i), - Vector512.LoadUnsafe(ref yRef, (uint)i), - zVec).StoreUnsafe(ref dRef, (uint)i); + float* xPtr = px; - i += Vector512.Count; - } - while (i <= oneVectorFromEnd); + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector512.Count); - TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, lastVectorIndex), - Vector512.LoadUnsafe(ref yRef, lastVectorIndex), - zVec).StoreUnsafe(ref dRef, lastVectorIndex); - } + bool canAlign = ((nuint)(xPtr) % sizeof(float)) == 0; - return; + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + misalignment = ((uint)(sizeof(Vector128)) - ((nuint)(xPtr) % (uint)(sizeof(Vector128)))) / sizeof(float); + + xPtr += misalignment; + + Debug.Assert(((nuint)(xPtr) % (uint)(sizeof(Vector128))) == 0); + + remainder -= misalignment; + } + + Vector128 vector1; + Vector128 vector2; + Vector128 vector3; + Vector128 vector4; + + // We only need to load, so there isn't a lot of benefit to doing non-temporal operations + + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0))); + vector2 = TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1))); + vector3 = TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2))); + vector4 = TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3))); + + vresult = TAggregationOperator.Invoke(vresult, vector1); + vresult = TAggregationOperator.Invoke(vresult, vector2); + vresult = TAggregationOperator.Invoke(vresult, vector3); + vresult = TAggregationOperator.Invoke(vresult, vector4); + + // We load, process, and store the next four vectors + + vector1 = TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4))); + vector2 = TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5))); + vector3 = TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6))); + vector4 = TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7))); + + vresult = TAggregationOperator.Invoke(vresult, vector1); + vresult = TAggregationOperator.Invoke(vresult, vector2); + vresult = TAggregationOperator.Invoke(vresult, vector3); + vresult = TAggregationOperator.Invoke(vresult, vector4); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + } } - } -#endif - if (Vector256.IsHardwareAccelerated) - { - oneVectorFromEnd = x.Length - Vector256.Count; - if (i <= oneVectorFromEnd) + // Store the first block. Handling this separately simplifies the latter code as we know + // they come after and so we can relegate it to full blocks or the trailing elements + + beg = Vector128.ConditionalSelect(CreateAlignmentMaskSingleVector128((int)(misalignment)), beg, Vector128.Create(TAggregationOperator.IdentityValue)); + vresult = TAggregationOperator.Invoke(vresult, beg); + + // Process the remaining [0, Count * 7] elements via a jump table + // + // We end up handling any trailing elements in case 0 and in the + // worst case end up just doing the identity operation here if there + // were no trailing elements. + + (nuint blocks, nuint trailing) = Math.DivRem(remainder, (nuint)(Vector128.Count)); + blocks -= (misalignment == 0) ? 1u : 0u; + remainder -= trailing; + + switch (blocks) { - Vector256 zVec = Vector256.Create(z); + case 7: + { + Vector128 vector = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 7))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 6; + } - // Loop handling one vector at a time. - do + case 6: { - TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i), - Vector256.LoadUnsafe(ref yRef, (uint)i), - zVec).StoreUnsafe(ref dRef, (uint)i); + Vector128 vector = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 6))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 5; + } - i += Vector256.Count; + case 5: + { + Vector128 vector = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 5))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 4; } - while (i <= oneVectorFromEnd); - // Handle any remaining elements with a final vector. - if (i != x.Length) + case 4: { - uint lastVectorIndex = (uint)(x.Length - Vector256.Count); - TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, lastVectorIndex), - Vector256.LoadUnsafe(ref yRef, lastVectorIndex), - zVec).StoreUnsafe(ref dRef, lastVectorIndex); + Vector128 vector = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 4))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 3; } - return; - } + case 3: + { + Vector128 vector = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 3))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 2; + } + + case 2: + { + Vector128 vector = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 2))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 1; + } + + case 1: + { + Vector128 vector = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 1))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 0; + } + + case 0: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end = Vector128.ConditionalSelect(CreateRemainderMaskSingleVector128((int)(trailing)), end, Vector128.Create(TAggregationOperator.IdentityValue)); + vresult = TAggregationOperator.Invoke(vresult, end); + break; + } + } + + return TAggregationOperator.Invoke(vresult); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static float Vectorized128Small(ref float xRef, nuint remainder) + { + float result = TAggregationOperator.IdentityValue; + + switch (remainder) + { + case 3: + { + result = TAggregationOperator.Invoke(result, TTransformOperator.Invoke(Unsafe.Add(ref xRef, 2))); + goto case 2; + } + + case 2: + { + result = TAggregationOperator.Invoke(result, TTransformOperator.Invoke(Unsafe.Add(ref xRef, 1))); + goto case 1; + } + + case 1: + { + result = TAggregationOperator.Invoke(result, TTransformOperator.Invoke(xRef)); + goto case 0; + } + + case 0: + { + break; + } + } + + return result; + } + + static float Vectorized256(ref float xRef, nuint remainder) + { + Vector256 vresult = Vector256.Create(TAggregationOperator.IdentityValue); + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector256 beg = TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef)); + Vector256 end = TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count))); + + nuint misalignment = 0; + + if (remainder > (uint)(Vector256.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + { + float* xPtr = px; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(xPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + misalignment = ((uint)(sizeof(Vector256)) - ((nuint)(xPtr) % (uint)(sizeof(Vector256)))) / sizeof(float); + + xPtr += misalignment; + + Debug.Assert(((nuint)(xPtr) % (uint)(sizeof(Vector256))) == 0); + + remainder -= misalignment; + } + + Vector256 vector1; + Vector256 vector2; + Vector256 vector3; + Vector256 vector4; + + // We only need to load, so there isn't a lot of benefit to doing non-temporal operations + + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0))); + vector2 = TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1))); + vector3 = TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2))); + vector4 = TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3))); + + vresult = TAggregationOperator.Invoke(vresult, vector1); + vresult = TAggregationOperator.Invoke(vresult, vector2); + vresult = TAggregationOperator.Invoke(vresult, vector3); + vresult = TAggregationOperator.Invoke(vresult, vector4); + + // We load, process, and store the next four vectors + + vector1 = TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4))); + vector2 = TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5))); + vector3 = TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6))); + vector4 = TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7))); + + vresult = TAggregationOperator.Invoke(vresult, vector1); + vresult = TAggregationOperator.Invoke(vresult, vector2); + vresult = TAggregationOperator.Invoke(vresult, vector3); + vresult = TAggregationOperator.Invoke(vresult, vector4); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + } + } + + // Store the first block. Handling this separately simplifies the latter code as we know + // they come after and so we can relegate it to full blocks or the trailing elements + + beg = Vector256.ConditionalSelect(CreateAlignmentMaskSingleVector256((int)(misalignment)), beg, Vector256.Create(TAggregationOperator.IdentityValue)); + vresult = TAggregationOperator.Invoke(vresult, beg); + + // Process the remaining [0, Count * 7] elements via a jump table + // + // We end up handling any trailing elements in case 0 and in the + // worst case end up just doing the identity operation here if there + // were no trailing elements. + + (nuint blocks, nuint trailing) = Math.DivRem(remainder, (nuint)(Vector256.Count)); + blocks -= (misalignment == 0) ? 1u : 0u; + remainder -= trailing; + + switch (blocks) + { + case 7: + { + Vector256 vector = TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 7))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 6; + } + + case 6: + { + Vector256 vector = TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 6))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 5; + } + + case 5: + { + Vector256 vector = TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 5))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 4; + } + + case 4: + { + Vector256 vector = TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 4))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 3; + } + + case 3: + { + Vector256 vector = TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 3))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 2; + } + + case 2: + { + Vector256 vector = TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 2))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 1; + } + + case 1: + { + Vector256 vector = TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 1))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 0; + } + + case 0: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end = Vector256.ConditionalSelect(CreateRemainderMaskSingleVector256((int)(trailing)), end, Vector256.Create(TAggregationOperator.IdentityValue)); + vresult = TAggregationOperator.Invoke(vresult, end); + break; + } + } + + return TAggregationOperator.Invoke(vresult); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static float Vectorized256Small(ref float xRef, nuint remainder) + { + float result = TAggregationOperator.IdentityValue; + + switch (remainder) + { + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + Vector128 vresult = Vector128.Create(TAggregationOperator.IdentityValue); + + Vector128 beg = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef)); + Vector128 end = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count))); + + end = Vector128.ConditionalSelect(CreateRemainderMaskSingleVector128((int)(remainder % (uint)(Vector128.Count))), end, Vector128.Create(TAggregationOperator.IdentityValue)); + + vresult = TAggregationOperator.Invoke(vresult, beg); + vresult = TAggregationOperator.Invoke(vresult, end); + + result = TAggregationOperator.Invoke(vresult); + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + Vector128 vresult = Vector128.Create(TAggregationOperator.IdentityValue); + + Vector128 beg = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef)); + vresult = TAggregationOperator.Invoke(vresult, beg); + + result = TAggregationOperator.Invoke(vresult); + break; + } + + case 3: + { + result = TAggregationOperator.Invoke(result, TTransformOperator.Invoke(Unsafe.Add(ref xRef, 2))); + goto case 2; + } + + case 2: + { + result = TAggregationOperator.Invoke(result, TTransformOperator.Invoke(Unsafe.Add(ref xRef, 1))); + goto case 1; + } + + case 1: + { + result = TAggregationOperator.Invoke(result, TTransformOperator.Invoke(xRef)); + goto case 0; + } + + case 0: + { + break; + } + } + + return result; + } + +#if NET8_0_OR_GREATER + static float Vectorized512(ref float xRef, nuint remainder) + { + Vector512 vresult = Vector512.Create(TAggregationOperator.IdentityValue); + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector512 beg = TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef)); + Vector512 end = TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count))); + + nuint misalignment = 0; + + if (remainder > (uint)(Vector512.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + { + float* xPtr = px; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(xPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + misalignment = ((uint)(sizeof(Vector512)) - ((nuint)(xPtr) % (uint)(sizeof(Vector512)))) / sizeof(float); + + xPtr += misalignment; + + Debug.Assert(((nuint)(xPtr) % (uint)(sizeof(Vector512))) == 0); + + remainder -= misalignment; + } + + Vector512 vector1; + Vector512 vector2; + Vector512 vector3; + Vector512 vector4; + + // We only need to load, so there isn't a lot of benefit to doing non-temporal operations + + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0))); + vector2 = TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1))); + vector3 = TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2))); + vector4 = TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3))); + + vresult = TAggregationOperator.Invoke(vresult, vector1); + vresult = TAggregationOperator.Invoke(vresult, vector2); + vresult = TAggregationOperator.Invoke(vresult, vector3); + vresult = TAggregationOperator.Invoke(vresult, vector4); + + // We load, process, and store the next four vectors + + vector1 = TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4))); + vector2 = TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5))); + vector3 = TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6))); + vector4 = TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7))); + + vresult = TAggregationOperator.Invoke(vresult, vector1); + vresult = TAggregationOperator.Invoke(vresult, vector2); + vresult = TAggregationOperator.Invoke(vresult, vector3); + vresult = TAggregationOperator.Invoke(vresult, vector4); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + } + } + + // Store the first block. Handling this separately simplifies the latter code as we know + // they come after and so we can relegate it to full blocks or the trailing elements + + beg = Vector512.ConditionalSelect(CreateAlignmentMaskSingleVector512((int)(misalignment)), beg, Vector512.Create(TAggregationOperator.IdentityValue)); + vresult = TAggregationOperator.Invoke(vresult, beg); + + // Process the remaining [0, Count * 7] elements via a jump table + // + // We end up handling any trailing elements in case 0 and in the + // worst case end up just doing the identity operation here if there + // were no trailing elements. + + (nuint blocks, nuint trailing) = Math.DivRem(remainder, (nuint)(Vector512.Count)); + blocks -= (misalignment == 0) ? 1u : 0u; + remainder -= trailing; + + switch (blocks) + { + case 7: + { + Vector512 vector = TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 7))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 6; + } + + case 6: + { + Vector512 vector = TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 6))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 5; + } + + case 5: + { + Vector512 vector = TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 5))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 4; + } + + case 4: + { + Vector512 vector = TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 4))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 3; + } + + case 3: + { + Vector512 vector = TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 3))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 2; + } + + case 2: + { + Vector512 vector = TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 2))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 1; + } + + case 1: + { + Vector512 vector = TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 1))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 0; + } + + case 0: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end = Vector512.ConditionalSelect(CreateRemainderMaskSingleVector512((int)(trailing)), end, Vector512.Create(TAggregationOperator.IdentityValue)); + vresult = TAggregationOperator.Invoke(vresult, end); + break; + } + } + + return TAggregationOperator.Invoke(vresult); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static float Vectorized512Small(ref float xRef, nuint remainder) + { + float result = TAggregationOperator.IdentityValue; + + switch (remainder) + { + case 15: + case 14: + case 13: + case 12: + case 11: + case 10: + case 9: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + Vector256 vresult = Vector256.Create(TAggregationOperator.IdentityValue); + + Vector256 beg = TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef)); + Vector256 end = TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count))); + + end = Vector256.ConditionalSelect(CreateRemainderMaskSingleVector256((int)(remainder % (uint)(Vector256.Count))), end, Vector256.Create(TAggregationOperator.IdentityValue)); + + vresult = TAggregationOperator.Invoke(vresult, beg); + vresult = TAggregationOperator.Invoke(vresult, end); + + result = TAggregationOperator.Invoke(vresult); + break; + } + + case 8: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + Vector256 vresult = Vector256.Create(TAggregationOperator.IdentityValue); + + Vector256 beg = TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef)); + vresult = TAggregationOperator.Invoke(vresult, beg); + + result = TAggregationOperator.Invoke(vresult); + break; + } + + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + Vector128 vresult = Vector128.Create(TAggregationOperator.IdentityValue); + + Vector128 beg = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef)); + Vector128 end = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count))); + + end = Vector128.ConditionalSelect(CreateRemainderMaskSingleVector128((int)(remainder % (uint)(Vector128.Count))), end, Vector128.Create(TAggregationOperator.IdentityValue)); + + vresult = TAggregationOperator.Invoke(vresult, beg); + vresult = TAggregationOperator.Invoke(vresult, end); + + result = TAggregationOperator.Invoke(vresult); + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + Vector128 vresult = Vector128.Create(TAggregationOperator.IdentityValue); + + Vector128 beg = TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef)); + vresult = TAggregationOperator.Invoke(vresult, beg); + + result = TAggregationOperator.Invoke(vresult); + break; + } + + case 3: + { + result = TAggregationOperator.Invoke(result, TTransformOperator.Invoke(Unsafe.Add(ref xRef, 2))); + goto case 2; + } + + case 2: + { + result = TAggregationOperator.Invoke(result, TTransformOperator.Invoke(Unsafe.Add(ref xRef, 1))); + goto case 1; + } + + case 1: + { + result = TAggregationOperator.Invoke(result, TTransformOperator.Invoke(xRef)); + goto case 0; + } + + case 0: + { + break; + } + } + + return result; + } +#endif + } + + /// Performs an aggregation over all pair-wise elements in and to produce a single-precision floating-point value. + /// Specifies the binary operation that should be applied to the pair-wise elements loaded from and . + /// + /// Specifies the aggregation binary operation that should be applied to multiple values to aggregate them into a single value. + /// The aggregation is applied to the results of the binary operations on the pair-wise values. + /// + private static float Aggregate( + ReadOnlySpan x, ReadOnlySpan y) + where TBinaryOperator : struct, IBinaryOperator + where TAggregationOperator : struct, IAggregationOperator + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + // Since every branch has a cost and since that cost is + // essentially lost for larger inputs, we do branches + // in a way that allows us to have the minimum possible + // for small sizes + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + + nuint remainder = (uint)(x.Length); + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) + { + float result; + + if (remainder >= (uint)(Vector512.Count)) + { + result = Vectorized512(ref xRef, ref yRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + result = Vectorized512Small(ref xRef, ref yRef, remainder); + } + + return result; + } +#endif + + if (Vector256.IsHardwareAccelerated) + { + float result; + + if (remainder >= (uint)(Vector256.Count)) + { + result = Vectorized256(ref xRef, ref yRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + result = Vectorized256Small(ref xRef, ref yRef, remainder); + } + + return result; + } + + if (Vector128.IsHardwareAccelerated) + { + float result; + + if (remainder >= (uint)(Vector128.Count)) + { + result = Vectorized128(ref xRef, ref yRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + result = Vectorized128Small(ref xRef, ref yRef, remainder); + } + + return result; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + return SoftwareFallback(ref xRef, ref yRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static float SoftwareFallback(ref float xRef, ref float yRef, nuint length) + { + float result = TAggregationOperator.IdentityValue; + + for (nuint i = 0; i < length; i++) + { + result = TAggregationOperator.Invoke(result, TBinaryOperator.Invoke(Unsafe.Add(ref xRef, i), + Unsafe.Add(ref yRef, i))); + } + + return result; + } + + static float Vectorized128(ref float xRef, ref float yRef, nuint remainder) + { + Vector128 vresult = Vector128.Create(TAggregationOperator.IdentityValue); + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector128 beg = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef)); + Vector128 end = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count))); + + nuint misalignment = 0; + + if (remainder > (uint)(Vector128.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + { + float* xPtr = px; + float* yPtr = py; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(xPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + misalignment = ((uint)(sizeof(Vector128)) - ((nuint)(xPtr) % (uint)(sizeof(Vector128)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + + Debug.Assert(((nuint)(xPtr) % (uint)(sizeof(Vector128))) == 0); + + remainder -= misalignment; + } + + Vector128 vector1; + Vector128 vector2; + Vector128 vector3; + Vector128 vector4; + + // We only need to load, so there isn't a lot of benefit to doing non-temporal operations + + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 0))); + vector2 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 1))); + vector3 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 2))); + vector4 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 3))); + + vresult = TAggregationOperator.Invoke(vresult, vector1); + vresult = TAggregationOperator.Invoke(vresult, vector2); + vresult = TAggregationOperator.Invoke(vresult, vector3); + vresult = TAggregationOperator.Invoke(vresult, vector4); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 4))); + vector2 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 5))); + vector3 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 6))); + vector4 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 7))); + + vresult = TAggregationOperator.Invoke(vresult, vector1); + vresult = TAggregationOperator.Invoke(vresult, vector2); + vresult = TAggregationOperator.Invoke(vresult, vector3); + vresult = TAggregationOperator.Invoke(vresult, vector4); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + yPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + } + } + + // Store the first block. Handling this separately simplifies the latter code as we know + // they come after and so we can relegate it to full blocks or the trailing elements + + beg = Vector128.ConditionalSelect(CreateAlignmentMaskSingleVector128((int)(misalignment)), beg, Vector128.Create(TAggregationOperator.IdentityValue)); + vresult = TAggregationOperator.Invoke(vresult, beg); + + // Process the remaining [0, Count * 7] elements via a jump table + // + // We end up handling any trailing elements in case 0 and in the + // worst case end up just doing the identity operation here if there + // were no trailing elements. + + (nuint blocks, nuint trailing) = Math.DivRem(remainder, (nuint)(Vector128.Count)); + blocks -= (misalignment == 0) ? 1u : 0u; + remainder -= trailing; + + switch (blocks) + { + case 7: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 7)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 7))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 6; + } + + case 6: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 6)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 6))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 5; + } + + case 5: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 5)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 5))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 4; + } + + case 4: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 4)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 4))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 3; + } + + case 3: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 3)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 3))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 2; + } + + case 2: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 2)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 2))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 1; + } + + case 1: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 1)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 1))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 0; + } + + case 0: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end = Vector128.ConditionalSelect(CreateRemainderMaskSingleVector128((int)(trailing)), end, Vector128.Create(TAggregationOperator.IdentityValue)); + vresult = TAggregationOperator.Invoke(vresult, end); + break; + } + } + + return TAggregationOperator.Invoke(vresult); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static float Vectorized128Small(ref float xRef, ref float yRef, nuint remainder) + { + float result = TAggregationOperator.IdentityValue; + + switch (remainder) + { + case 3: + { + result = TAggregationOperator.Invoke(result, TBinaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2))); + goto case 2; + } + + case 2: + { + result = TAggregationOperator.Invoke(result, TBinaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1))); + goto case 1; + } + + case 1: + { + result = TAggregationOperator.Invoke(result, TBinaryOperator.Invoke(xRef, yRef)); + goto case 0; + } + + case 0: + { + break; + } + } + + return result; + } + + static float Vectorized256(ref float xRef, ref float yRef, nuint remainder) + { + Vector256 vresult = Vector256.Create(TAggregationOperator.IdentityValue); + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector256 beg = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + Vector256.LoadUnsafe(ref yRef)); + Vector256 end = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count))); + + nuint misalignment = 0; + + if (remainder > (uint)(Vector256.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + { + float* xPtr = px; + float* yPtr = py; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(xPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + misalignment = ((uint)(sizeof(Vector256)) - ((nuint)(xPtr) % (uint)(sizeof(Vector256)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + + Debug.Assert(((nuint)(xPtr) % (uint)(sizeof(Vector256))) == 0); + + remainder -= misalignment; + } + + Vector256 vector1; + Vector256 vector2; + Vector256 vector3; + Vector256 vector4; + + // We only need to load, so there isn't a lot of benefit to doing non-temporal operations + + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 0))); + vector2 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 1))); + vector3 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 2))); + vector4 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 3))); + + vresult = TAggregationOperator.Invoke(vresult, vector1); + vresult = TAggregationOperator.Invoke(vresult, vector2); + vresult = TAggregationOperator.Invoke(vresult, vector3); + vresult = TAggregationOperator.Invoke(vresult, vector4); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 4))); + vector2 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 5))); + vector3 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 6))); + vector4 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 7))); + + vresult = TAggregationOperator.Invoke(vresult, vector1); + vresult = TAggregationOperator.Invoke(vresult, vector2); + vresult = TAggregationOperator.Invoke(vresult, vector3); + vresult = TAggregationOperator.Invoke(vresult, vector4); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + yPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + } + } + + // Store the first block. Handling this separately simplifies the latter code as we know + // they come after and so we can relegate it to full blocks or the trailing elements + + beg = Vector256.ConditionalSelect(CreateAlignmentMaskSingleVector256((int)(misalignment)), beg, Vector256.Create(TAggregationOperator.IdentityValue)); + vresult = TAggregationOperator.Invoke(vresult, beg); + + // Process the remaining [0, Count * 7] elements via a jump table + // + // We end up handling any trailing elements in case 0 and in the + // worst case end up just doing the identity operation here if there + // were no trailing elements. + + (nuint blocks, nuint trailing) = Math.DivRem(remainder, (nuint)(Vector256.Count)); + blocks -= (misalignment == 0) ? 1u : 0u; + remainder -= trailing; + + switch (blocks) + { + case 7: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 7)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 7))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 6; + } + + case 6: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 6)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 6))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 5; + } + + case 5: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 5)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 5))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 4; + } + + case 4: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 4)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 4))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 3; + } + + case 3: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 3)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 3))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 2; + } + + case 2: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 2)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 2))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 1; + } + + case 1: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 1)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 1))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 0; + } + + case 0: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end = Vector256.ConditionalSelect(CreateRemainderMaskSingleVector256((int)(trailing)), end, Vector256.Create(TAggregationOperator.IdentityValue)); + vresult = TAggregationOperator.Invoke(vresult, end); + break; + } + } + + return TAggregationOperator.Invoke(vresult); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static float Vectorized256Small(ref float xRef, ref float yRef, nuint remainder) + { + float result = TAggregationOperator.IdentityValue; + + switch (remainder) + { + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + Vector128 vresult = Vector128.Create(TAggregationOperator.IdentityValue); + + Vector128 beg = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef)); + Vector128 end = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count))); + + end = Vector128.ConditionalSelect(CreateRemainderMaskSingleVector128((int)(remainder % (uint)(Vector128.Count))), end, Vector128.Create(TAggregationOperator.IdentityValue)); + + vresult = TAggregationOperator.Invoke(vresult, beg); + vresult = TAggregationOperator.Invoke(vresult, end); + + result = TAggregationOperator.Invoke(vresult); + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + Vector128 vresult = Vector128.Create(TAggregationOperator.IdentityValue); + + Vector128 beg = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef)); + vresult = TAggregationOperator.Invoke(vresult, beg); + + result = TAggregationOperator.Invoke(vresult); + break; + } + + case 3: + { + result = TAggregationOperator.Invoke(result, TBinaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2))); + goto case 2; + } + + case 2: + { + result = TAggregationOperator.Invoke(result, TBinaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1))); + goto case 1; + } + + case 1: + { + result = TAggregationOperator.Invoke(result, TBinaryOperator.Invoke(xRef, yRef)); + goto case 0; + } + + case 0: + { + break; + } + } + + return result; + } + +#if NET8_0_OR_GREATER + static float Vectorized512(ref float xRef, ref float yRef, nuint remainder) + { + Vector512 vresult = Vector512.Create(TAggregationOperator.IdentityValue); + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector512 beg = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef), + Vector512.LoadUnsafe(ref yRef)); + Vector512 end = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count))); + + nuint misalignment = 0; + + if (remainder > (uint)(Vector512.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + { + float* xPtr = px; + float* yPtr = py; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(xPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + misalignment = ((uint)(sizeof(Vector512)) - ((nuint)(xPtr) % (uint)(sizeof(Vector512)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + + Debug.Assert(((nuint)(xPtr) % (uint)(sizeof(Vector512))) == 0); + + remainder -= misalignment; + } + + Vector512 vector1; + Vector512 vector2; + Vector512 vector3; + Vector512 vector4; + + // We only need to load, so there isn't a lot of benefit to doing non-temporal operations + + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 0))); + vector2 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 1))); + vector3 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 2))); + vector4 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 3))); + + vresult = TAggregationOperator.Invoke(vresult, vector1); + vresult = TAggregationOperator.Invoke(vresult, vector2); + vresult = TAggregationOperator.Invoke(vresult, vector3); + vresult = TAggregationOperator.Invoke(vresult, vector4); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 4))); + vector2 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 5))); + vector3 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 6))); + vector4 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 7))); + + vresult = TAggregationOperator.Invoke(vresult, vector1); + vresult = TAggregationOperator.Invoke(vresult, vector2); + vresult = TAggregationOperator.Invoke(vresult, vector3); + vresult = TAggregationOperator.Invoke(vresult, vector4); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + yPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + } + } + + // Store the first block. Handling this separately simplifies the latter code as we know + // they come after and so we can relegate it to full blocks or the trailing elements + + beg = Vector512.ConditionalSelect(CreateAlignmentMaskSingleVector512((int)(misalignment)), beg, Vector512.Create(TAggregationOperator.IdentityValue)); + vresult = TAggregationOperator.Invoke(vresult, beg); + + // Process the remaining [0, Count * 7] elements via a jump table + // + // We end up handling any trailing elements in case 0 and in the + // worst case end up just doing the identity operation here if there + // were no trailing elements. + + (nuint blocks, nuint trailing) = Math.DivRem(remainder, (nuint)(Vector512.Count)); + blocks -= (misalignment == 0) ? 1u : 0u; + remainder -= trailing; + + switch (blocks) + { + case 7: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 7)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 7))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 6; + } + + case 6: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 6)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 6))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 5; + } + + case 5: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 5)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 5))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 4; + } + + case 4: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 4)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 4))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 3; + } + + case 3: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 3)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 3))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 2; + } + + case 2: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 2)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 2))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 1; + } + + case 1: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 1)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 1))); + vresult = TAggregationOperator.Invoke(vresult, vector); + goto case 0; + } + + case 0: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end = Vector512.ConditionalSelect(CreateRemainderMaskSingleVector512((int)(trailing)), end, Vector512.Create(TAggregationOperator.IdentityValue)); + vresult = TAggregationOperator.Invoke(vresult, end); + break; + } + } + + return TAggregationOperator.Invoke(vresult); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static float Vectorized512Small(ref float xRef, ref float yRef, nuint remainder) + { + float result = TAggregationOperator.IdentityValue; + + switch (remainder) + { + case 15: + case 14: + case 13: + case 12: + case 11: + case 10: + case 9: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + Vector256 vresult = Vector256.Create(TAggregationOperator.IdentityValue); + + Vector256 beg = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + Vector256.LoadUnsafe(ref yRef)); + Vector256 end = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count))); + + end = Vector256.ConditionalSelect(CreateRemainderMaskSingleVector256((int)(remainder % (uint)(Vector256.Count))), end, Vector256.Create(TAggregationOperator.IdentityValue)); + + vresult = TAggregationOperator.Invoke(vresult, beg); + vresult = TAggregationOperator.Invoke(vresult, end); + + result = TAggregationOperator.Invoke(vresult); + break; + } + + case 8: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + Vector256 vresult = Vector256.Create(TAggregationOperator.IdentityValue); + + Vector256 beg = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + Vector256.LoadUnsafe(ref yRef)); + vresult = TAggregationOperator.Invoke(vresult, beg); + + result = TAggregationOperator.Invoke(vresult); + break; + } + + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + Vector128 vresult = Vector128.Create(TAggregationOperator.IdentityValue); + + Vector128 beg = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef)); + Vector128 end = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count))); + + end = Vector128.ConditionalSelect(CreateRemainderMaskSingleVector128((int)(remainder % (uint)(Vector128.Count))), end, Vector128.Create(TAggregationOperator.IdentityValue)); + + vresult = TAggregationOperator.Invoke(vresult, beg); + vresult = TAggregationOperator.Invoke(vresult, end); + + result = TAggregationOperator.Invoke(vresult); + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + Vector128 vresult = Vector128.Create(TAggregationOperator.IdentityValue); + + Vector128 beg = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef)); + vresult = TAggregationOperator.Invoke(vresult, beg); + + result = TAggregationOperator.Invoke(vresult); + break; + } + + case 3: + { + result = TAggregationOperator.Invoke(result, TBinaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2))); + goto case 2; + } + + case 2: + { + result = TAggregationOperator.Invoke(result, TBinaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1))); + goto case 1; + } + + case 1: + { + result = TAggregationOperator.Invoke(result, TBinaryOperator.Invoke(xRef, yRef)); + goto case 0; + } + + case 0: + { + break; + } + } + + return result; + } +#endif + } + + /// + /// This is the same as + /// with an identity transform, except it early exits on NaN. + /// + private static float MinMaxCore(ReadOnlySpan x) + where TMinMaxOperator : struct, IAggregationOperator + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + + // This matches the IEEE 754:2019 `maximum`/`minimum` functions. + // It propagates NaN inputs back to the caller and + // otherwise returns the greater of the inputs. + // It treats +0 as greater than -0 as per the specification. + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated && x.Length >= Vector512.Count) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + // Load the first vector as the initial set of results, and bail immediately + // to scalar handling if it contains any NaNs (which don't compare equally to themselves). + Vector512 result = Vector512.LoadUnsafe(ref xRef, 0), current; + if (!Vector512.EqualsAll(result, result)) + { + return GetFirstNaN(result); + } + + int oneVectorFromEnd = x.Length - Vector512.Count; + int i = Vector512.Count; + + // Aggregate additional vectors into the result as long as there's at least one full vector left to process. + while (i <= oneVectorFromEnd) + { + // Load the next vector, and early exit on NaN. + current = Vector512.LoadUnsafe(ref xRef, (uint)i); + if (!Vector512.EqualsAll(current, current)) + { + return GetFirstNaN(current); + } + + result = TMinMaxOperator.Invoke(result, current); + i += Vector512.Count; + } + + // If any elements remain, handle them in one final vector. + if (i != x.Length) + { + current = Vector512.LoadUnsafe(ref xRef, (uint)(x.Length - Vector512.Count)); + if (!Vector512.EqualsAll(current, current)) + { + return GetFirstNaN(current); + } + + result = Vector512.ConditionalSelect( + Vector512.Equals(CreateRemainderMaskSingleVector512(x.Length - i), Vector512.Zero), + result, + TMinMaxOperator.Invoke(result, current)); + } + + // Aggregate the lanes in the vector to create the final scalar result. + return TMinMaxOperator.Invoke(result); + } +#endif + + if (Vector256.IsHardwareAccelerated && x.Length >= Vector256.Count) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + + // Load the first vector as the initial set of results, and bail immediately + // to scalar handling if it contains any NaNs (which don't compare equally to themselves). + Vector256 result = Vector256.LoadUnsafe(ref xRef, 0), current; + if (!Vector256.EqualsAll(result, result)) + { + return GetFirstNaN(result); + } + + int oneVectorFromEnd = x.Length - Vector256.Count; + int i = Vector256.Count; + + // Aggregate additional vectors into the result as long as there's at least one full vector left to process. + while (i <= oneVectorFromEnd) + { + // Load the next vector, and early exit on NaN. + current = Vector256.LoadUnsafe(ref xRef, (uint)i); + if (!Vector256.EqualsAll(current, current)) + { + return GetFirstNaN(current); + } + + result = TMinMaxOperator.Invoke(result, current); + i += Vector256.Count; + } + + // If any elements remain, handle them in one final vector. + if (i != x.Length) + { + current = Vector256.LoadUnsafe(ref xRef, (uint)(x.Length - Vector256.Count)); + if (!Vector256.EqualsAll(current, current)) + { + return GetFirstNaN(current); + } + + result = Vector256.ConditionalSelect( + Vector256.Equals(CreateRemainderMaskSingleVector256(x.Length - i), Vector256.Zero), + result, + TMinMaxOperator.Invoke(result, current)); + } + + // Aggregate the lanes in the vector to create the final scalar result. + return TMinMaxOperator.Invoke(result); + } + + if (Vector128.IsHardwareAccelerated && x.Length >= Vector128.Count) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + + // Load the first vector as the initial set of results, and bail immediately + // to scalar handling if it contains any NaNs (which don't compare equally to themselves). + Vector128 result = Vector128.LoadUnsafe(ref xRef, 0), current; + if (!Vector128.EqualsAll(result, result)) + { + return GetFirstNaN(result); + } + + int oneVectorFromEnd = x.Length - Vector128.Count; + int i = Vector128.Count; + + // Aggregate additional vectors into the result as long as there's at least one full vector left to process. + while (i <= oneVectorFromEnd) + { + // Load the next vector, and early exit on NaN. + current = Vector128.LoadUnsafe(ref xRef, (uint)i); + if (!Vector128.EqualsAll(current, current)) + { + return GetFirstNaN(current); + } + + result = TMinMaxOperator.Invoke(result, current); + i += Vector128.Count; + } + + // If any elements remain, handle them in one final vector. + if (i != x.Length) + { + current = Vector128.LoadUnsafe(ref xRef, (uint)(x.Length - Vector128.Count)); + if (!Vector128.EqualsAll(current, current)) + { + return GetFirstNaN(current); + } + + result = Vector128.ConditionalSelect( + Vector128.Equals(CreateRemainderMaskSingleVector128(x.Length - i), Vector128.Zero), + result, + TMinMaxOperator.Invoke(result, current)); + } + + // Aggregate the lanes in the vector to create the final scalar result. + return TMinMaxOperator.Invoke(result); + } + + // Scalar path used when either vectorization is not supported or the input is too small to vectorize. + { + float result = x[0]; + if (float.IsNaN(result)) + { + return result; + } + + for (int i = 1; i < x.Length; i++) + { + float current = x[i]; + if (float.IsNaN(current)) + { + return current; + } + + result = TMinMaxOperator.Invoke(result, current); + } + + return result; + } + } + + private static int IndexOfMinMaxCore(ReadOnlySpan x) where TIndexOfMinMax : struct, IIndexOfOperator + { + // This matches the IEEE 754:2019 `maximum`/`minimum` functions. + // It propagates NaN inputs back to the caller and + // otherwise returns the index of the greater of the inputs. + // It treats +0 as greater than -0 as per the specification. + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated && x.Length >= Vector512.Count) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + Vector512 resultIndex = Vector512.Create(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + Vector512 curIndex = resultIndex; + Vector512 increment = Vector512.Create(Vector512.Count); + + // Load the first vector as the initial set of results, and bail immediately + // to scalar handling if it contains any NaNs (which don't compare equally to themselves). + Vector512 result = Vector512.LoadUnsafe(ref xRef); + Vector512 current; + + Vector512 nanMask = ~Vector512.Equals(result, result); + if (nanMask != Vector512.Zero) + { + return IndexOfFirstMatch(nanMask); + } + + int oneVectorFromEnd = x.Length - Vector512.Count; + int i = Vector512.Count; + + // Aggregate additional vectors into the result as long as there's at least one full vector left to process. + while (i <= oneVectorFromEnd) + { + // Load the next vector, and early exit on NaN. + current = Vector512.LoadUnsafe(ref xRef, (uint)i); + curIndex += increment; + + nanMask = ~Vector512.Equals(current, current); + if (nanMask != Vector512.Zero) + { + return i + IndexOfFirstMatch(nanMask); + } + + TIndexOfMinMax.Invoke(ref result, current, ref resultIndex, curIndex); + + i += Vector512.Count; + } + + // If any elements remain, handle them in one final vector. + if (i != x.Length) + { + current = Vector512.LoadUnsafe(ref xRef, (uint)(x.Length - Vector512.Count)); + curIndex += Vector512.Create(x.Length - i); + + nanMask = ~Vector512.Equals(current, current); + if (nanMask != Vector512.Zero) + { + return curIndex[IndexOfFirstMatch(nanMask)]; + } + + TIndexOfMinMax.Invoke(ref result, current, ref resultIndex, curIndex); + } + + // Aggregate the lanes in the vector to create the final scalar result. + return TIndexOfMinMax.Invoke(result, resultIndex); + } +#endif + + if (Vector256.IsHardwareAccelerated && x.Length >= Vector256.Count) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + Vector256 resultIndex = Vector256.Create(0, 1, 2, 3, 4, 5, 6, 7); + Vector256 curIndex = resultIndex; + Vector256 increment = Vector256.Create(Vector256.Count); + + // Load the first vector as the initial set of results, and bail immediately + // to scalar handling if it contains any NaNs (which don't compare equally to themselves). + Vector256 result = Vector256.LoadUnsafe(ref xRef); + Vector256 current; + + Vector256 nanMask = ~Vector256.Equals(result, result); + if (nanMask != Vector256.Zero) + { + return IndexOfFirstMatch(nanMask); + } + + int oneVectorFromEnd = x.Length - Vector256.Count; + int i = Vector256.Count; + + // Aggregate additional vectors into the result as long as there's at least one full vector left to process. + while (i <= oneVectorFromEnd) + { + // Load the next vector, and early exit on NaN. + current = Vector256.LoadUnsafe(ref xRef, (uint)i); + curIndex += increment; + + nanMask = ~Vector256.Equals(current, current); + if (nanMask != Vector256.Zero) + { + return i + IndexOfFirstMatch(nanMask); + } + + TIndexOfMinMax.Invoke(ref result, current, ref resultIndex, curIndex); + + i += Vector256.Count; + } + + // If any elements remain, handle them in one final vector. + if (i != x.Length) + { + current = Vector256.LoadUnsafe(ref xRef, (uint)(x.Length - Vector256.Count)); + curIndex += Vector256.Create(x.Length - i); + + nanMask = ~Vector256.Equals(current, current); + if (nanMask != Vector256.Zero) + { + return curIndex[IndexOfFirstMatch(nanMask)]; + } + + TIndexOfMinMax.Invoke(ref result, current, ref resultIndex, curIndex); + } + + // Aggregate the lanes in the vector to create the final scalar result. + return TIndexOfMinMax.Invoke(result, resultIndex); + } + + if (Vector128.IsHardwareAccelerated && x.Length >= Vector128.Count) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + Vector128 resultIndex = Vector128.Create(0, 1, 2, 3); + Vector128 curIndex = resultIndex; + Vector128 increment = Vector128.Create(Vector128.Count); + + // Load the first vector as the initial set of results, and bail immediately + // to scalar handling if it contains any NaNs (which don't compare equally to themselves). + Vector128 result = Vector128.LoadUnsafe(ref xRef); + Vector128 current; + + Vector128 nanMask = ~Vector128.Equals(result, result); + if (nanMask != Vector128.Zero) + { + return IndexOfFirstMatch(nanMask); + } + + int oneVectorFromEnd = x.Length - Vector128.Count; + int i = Vector128.Count; + + // Aggregate additional vectors into the result as long as there's at least one full vector left to process. + while (i <= oneVectorFromEnd) + { + // Load the next vector, and early exit on NaN. + current = Vector128.LoadUnsafe(ref xRef, (uint)i); + curIndex += increment; + + nanMask = ~Vector128.Equals(current, current); + if (nanMask != Vector128.Zero) + { + return i + IndexOfFirstMatch(nanMask); + } + + TIndexOfMinMax.Invoke(ref result, current, ref resultIndex, curIndex); + + i += Vector128.Count; + } + + // If any elements remain, handle them in one final vector. + if (i != x.Length) + { + curIndex += Vector128.Create(x.Length - i); + + current = Vector128.LoadUnsafe(ref xRef, (uint)(x.Length - Vector128.Count)); + + nanMask = ~Vector128.Equals(current, current); + if (nanMask != Vector128.Zero) + { + return curIndex[IndexOfFirstMatch(nanMask)]; + } + + TIndexOfMinMax.Invoke(ref result, current, ref resultIndex, curIndex); + } + + // Aggregate the lanes in the vector to create the final scalar result. + return TIndexOfMinMax.Invoke(result, resultIndex); + } + + // Scalar path used when either vectorization is not supported or the input is too small to vectorize. + float curResult = x[0]; + int curIn = 0; + if (float.IsNaN(curResult)) + { + return curIn; + } + + for (int i = 1; i < x.Length; i++) + { + float current = x[i]; + if (float.IsNaN(current)) + { + return i; + } + + curIn = TIndexOfMinMax.Invoke(ref curResult, current, curIn, i); + } + + return curIn; + } + + private static int IndexOfFirstMatch(Vector128 mask) + { + return BitOperations.TrailingZeroCount(mask.ExtractMostSignificantBits()); + } + + private static int IndexOfFirstMatch(Vector256 mask) + { + return BitOperations.TrailingZeroCount(mask.ExtractMostSignificantBits()); + } + +#if NET8_0_OR_GREATER + private static int IndexOfFirstMatch(Vector512 mask) + { + return BitOperations.TrailingZeroCount(mask.ExtractMostSignificantBits()); + } +#endif + + /// Performs an element-wise operation on and writes the results to . + /// Specifies the operation to perform on each element loaded from . + private static void InvokeSpanIntoSpan( + ReadOnlySpan x, Span destination) + where TUnaryOperator : struct, IUnaryOperator + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ValidateInputOutputSpanNonOverlapping(x, destination); + + // Since every branch has a cost and since that cost is + // essentially lost for larger inputs, we do branches + // in a way that allows us to have the minimum possible + // for small sizes + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + nuint remainder = (uint)(x.Length); + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector512.Count)) + { + Vectorized512(ref xRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized512Small(ref xRef, ref dRef, remainder); + } + + return; + } +#endif + + if (Vector256.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector256.Count)) + { + Vectorized256(ref xRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized256Small(ref xRef, ref dRef, remainder); + } + + return; + } + + if (Vector128.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector128.Count)) + { + Vectorized128(ref xRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized128Small(ref xRef, ref dRef, remainder); + } + + return; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + SoftwareFallback(ref xRef, ref dRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void SoftwareFallback(ref float xRef, ref float dRef, nuint length) + { + for (nuint i = 0; i < length; i++) + { + Unsafe.Add(ref dRef, i) = TUnaryOperator.Invoke(Unsafe.Add(ref xRef, i)); + } + } + + static void Vectorized128(ref float xRef, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector128 beg = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef)); + Vector128 end = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count))); + + if (remainder > (uint)(Vector128.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector128)) - ((nuint)(dPtr) % (uint)(sizeof(Vector128)))) / sizeof(float); + + xPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector128))) == 0); + + remainder -= misalignment; + } + + Vector128 vector1; + Vector128 vector2; + Vector128 vector3; + Vector128 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0))); + vector2 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1))); + vector3 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2))); + vector4 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4))); + vector2 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5))); + vector3 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6))); + vector4 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + dPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0))); + vector2 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1))); + vector3 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2))); + vector4 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3))); + + vector1.Store(dPtr + (uint)(Vector128.Count * 0)); + vector2.Store(dPtr + (uint)(Vector128.Count * 1)); + vector3.Store(dPtr + (uint)(Vector128.Count * 2)); + vector4.Store(dPtr + (uint)(Vector128.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4))); + vector2 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5))); + vector3 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6))); + vector4 = TUnaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7))); + + vector1.Store(dPtr + (uint)(Vector128.Count * 4)); + vector2.Store(dPtr + (uint)(Vector128.Count * 5)); + vector3.Store(dPtr + (uint)(Vector128.Count * 6)); + vector4.Store(dPtr + (uint)(Vector128.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + dPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector128.Count - 1)) & (nuint)(-Vector128.Count); + + switch (remainder / (uint)(Vector128.Count)) + { + case 8: + { + Vector128 vector = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 8))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 8)); + goto case 7; + } + + case 7: + { + Vector128 vector = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 7))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 7)); + goto case 6; + } + + case 6: + { + Vector128 vector = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 6))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 6)); + goto case 5; + } + + case 5: + { + Vector128 vector = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 5))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 5)); + goto case 4; + } + + case 4: + { + Vector128 vector = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 4))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 4)); + goto case 3; + } + + case 3: + { + Vector128 vector = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 3))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 3)); + goto case 2; + } + + case 2: + { + Vector128 vector = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 2))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector128.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized128Small(ref float xRef, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 3: + { + Unsafe.Add(ref dRef, 2) = TUnaryOperator.Invoke(Unsafe.Add(ref xRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TUnaryOperator.Invoke(Unsafe.Add(ref xRef, 1)); + goto case 1; + } + + case 1: + { + dRef = TUnaryOperator.Invoke(xRef); + goto case 0; + } + + case 0: + { + break; + } + } + } + + static void Vectorized256(ref float xRef, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector256 beg = TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef)); + Vector256 end = TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count))); + + if (remainder > (uint)(Vector256.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector256)) - ((nuint)(dPtr) % (uint)(sizeof(Vector256)))) / sizeof(float); + + xPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector256))) == 0); + + remainder -= misalignment; + } + + Vector256 vector1; + Vector256 vector2; + Vector256 vector3; + Vector256 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0))); + vector2 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1))); + vector3 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2))); + vector4 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4))); + vector2 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5))); + vector3 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6))); + vector4 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + dPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0))); + vector2 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1))); + vector3 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2))); + vector4 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3))); + + vector1.Store(dPtr + (uint)(Vector256.Count * 0)); + vector2.Store(dPtr + (uint)(Vector256.Count * 1)); + vector3.Store(dPtr + (uint)(Vector256.Count * 2)); + vector4.Store(dPtr + (uint)(Vector256.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4))); + vector2 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5))); + vector3 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6))); + vector4 = TUnaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7))); + + vector1.Store(dPtr + (uint)(Vector256.Count * 4)); + vector2.Store(dPtr + (uint)(Vector256.Count * 5)); + vector3.Store(dPtr + (uint)(Vector256.Count * 6)); + vector4.Store(dPtr + (uint)(Vector256.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + dPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector256.Count - 1)) & (nuint)(-Vector256.Count); + + switch (remainder / (uint)(Vector256.Count)) + { + case 8: + { + Vector256 vector = TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 8))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 8)); + goto case 7; + } + + case 7: + { + Vector256 vector = TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 7))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 7)); + goto case 6; + } + + case 6: + { + Vector256 vector = TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 6))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 6)); + goto case 5; + } + + case 5: + { + Vector256 vector = TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 5))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 5)); + goto case 4; + } + + case 4: + { + Vector256 vector = TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 4))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 4)); + goto case 3; + } + + case 3: + { + Vector256 vector = TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 3))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 3)); + goto case 2; + } + + case 2: + { + Vector256 vector = TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 2))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector256.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized256Small(ref float xRef, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef)); + Vector128 end = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count))); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count)); + + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = TUnaryOperator.Invoke(Unsafe.Add(ref xRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TUnaryOperator.Invoke(Unsafe.Add(ref xRef, 1)); + goto case 1; + } + + case 1: + { + dRef = TUnaryOperator.Invoke(xRef); + goto case 0; + } + + case 0: + { + break; + } + } + } + +#if NET8_0_OR_GREATER + static void Vectorized512(ref float xRef, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector512 beg = TUnaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef)); + Vector512 end = TUnaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count))); + + if (remainder > (uint)(Vector512.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector512)) - ((nuint)(dPtr) % (uint)(sizeof(Vector512)))) / sizeof(float); + + xPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector512))) == 0); + + remainder -= misalignment; + } + + Vector512 vector1; + Vector512 vector2; + Vector512 vector3; + Vector512 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0))); + vector2 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1))); + vector3 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2))); + vector4 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4))); + vector2 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5))); + vector3 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6))); + vector4 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + dPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0))); + vector2 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1))); + vector3 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2))); + vector4 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3))); + + vector1.Store(dPtr + (uint)(Vector512.Count * 0)); + vector2.Store(dPtr + (uint)(Vector512.Count * 1)); + vector3.Store(dPtr + (uint)(Vector512.Count * 2)); + vector4.Store(dPtr + (uint)(Vector512.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4))); + vector2 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5))); + vector3 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6))); + vector4 = TUnaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7))); + + vector1.Store(dPtr + (uint)(Vector512.Count * 4)); + vector2.Store(dPtr + (uint)(Vector512.Count * 5)); + vector3.Store(dPtr + (uint)(Vector512.Count * 6)); + vector4.Store(dPtr + (uint)(Vector512.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + dPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector512.Count - 1)) & (nuint)(-Vector512.Count); + + switch (remainder / (uint)(Vector512.Count)) + { + case 8: + { + Vector512 vector = TUnaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 8))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 8)); + goto case 7; + } + + case 7: + { + Vector512 vector = TUnaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 7))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 7)); + goto case 6; + } + + case 6: + { + Vector512 vector = TUnaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 6))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 6)); + goto case 5; + } + + case 5: + { + Vector512 vector = TUnaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 5))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 5)); + goto case 4; + } + + case 4: + { + Vector512 vector = TUnaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 4))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 4)); + goto case 3; + } + + case 3: + { + Vector512 vector = TUnaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 3))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 3)); + goto case 2; + } + + case 2: + { + Vector512 vector = TUnaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 2))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector512.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized512Small(ref float xRef, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 15: + case 14: + case 13: + case 12: + case 11: + case 10: + case 9: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + + Vector256 beg = TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef)); + Vector256 end = TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count))); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count)); + + break; + } + + case 8: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + + Vector256 beg = TUnaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef)); + Vector128 end = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count))); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count)); + + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TUnaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = TUnaryOperator.Invoke(Unsafe.Add(ref xRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TUnaryOperator.Invoke(Unsafe.Add(ref xRef, 1)); + goto case 1; + } + + case 1: + { + dRef = TUnaryOperator.Invoke(xRef); + goto case 0; + } + + case 0: + { + break; + } + } + } +#endif + } + + /// + /// Performs an element-wise operation on and , + /// and writes the results to . + /// + /// + /// Specifies the operation to perform on the pair-wise elements loaded from and . + /// + private static void InvokeSpanSpanIntoSpan( + ReadOnlySpan x, ReadOnlySpan y, Span destination) + where TBinaryOperator : struct, IBinaryOperator + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ValidateInputOutputSpanNonOverlapping(x, destination); + ValidateInputOutputSpanNonOverlapping(y, destination); + + // Since every branch has a cost and since that cost is + // essentially lost for larger inputs, we do branches + // in a way that allows us to have the minimum possible + // for small sizes + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + nuint remainder = (uint)(x.Length); + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector512.Count)) + { + Vectorized512(ref xRef, ref yRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized512Small(ref xRef, ref yRef, ref dRef, remainder); + } + + return; + } +#endif + + if (Vector256.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector256.Count)) + { + Vectorized256(ref xRef, ref yRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized256Small(ref xRef, ref yRef, ref dRef, remainder); + } + + return; + } + + if (Vector128.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector128.Count)) + { + Vectorized128(ref xRef, ref yRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized128Small(ref xRef, ref yRef, ref dRef, remainder); + } + + return; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + SoftwareFallback(ref xRef, ref yRef, ref dRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void SoftwareFallback(ref float xRef, ref float yRef, ref float dRef, nuint length) + { + for (nuint i = 0; i < length; i++) + { + Unsafe.Add(ref dRef, i) = TBinaryOperator.Invoke(Unsafe.Add(ref xRef, i), + Unsafe.Add(ref yRef, i)); + } + } + + static void Vectorized128(ref float xRef, ref float yRef, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector128 beg = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef)); + Vector128 end = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count))); + + if (remainder > (uint)(Vector128.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* yPtr = py; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector128)) - ((nuint)(dPtr) % (uint)(sizeof(Vector128)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector128))) == 0); + + remainder -= misalignment; + } + + Vector128 vector1; + Vector128 vector2; + Vector128 vector3; + Vector128 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 0))); + vector2 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 1))); + vector3 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 2))); + vector4 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 3))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 4))); + vector2 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 5))); + vector3 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 6))); + vector4 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 7))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + yPtr += (uint)(Vector128.Count * 8); + dPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 0))); + vector2 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 1))); + vector3 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 2))); + vector4 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 3))); + + vector1.Store(dPtr + (uint)(Vector128.Count * 0)); + vector2.Store(dPtr + (uint)(Vector128.Count * 1)); + vector3.Store(dPtr + (uint)(Vector128.Count * 2)); + vector4.Store(dPtr + (uint)(Vector128.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 4))); + vector2 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 5))); + vector3 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 6))); + vector4 = TBinaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 7))); + + vector1.Store(dPtr + (uint)(Vector128.Count * 4)); + vector2.Store(dPtr + (uint)(Vector128.Count * 5)); + vector3.Store(dPtr + (uint)(Vector128.Count * 6)); + vector4.Store(dPtr + (uint)(Vector128.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + yPtr += (uint)(Vector128.Count * 8); + dPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector128.Count - 1)) & (nuint)(-Vector128.Count); + + switch (remainder / (uint)(Vector128.Count)) + { + case 8: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 8)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 8))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 8)); + goto case 7; + } + + case 7: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 7)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 7))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 7)); + goto case 6; + } + + case 6: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 6)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 6))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 6)); + goto case 5; + } + + case 5: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 5)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 5))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 5)); + goto case 4; + } + + case 4: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 4)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 4))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 4)); + goto case 3; + } + + case 3: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 3)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 3))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 3)); + goto case 2; + } + + case 2: + { + Vector128 vector = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 2)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 2))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector128.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized128Small(ref float xRef, ref float yRef, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 3: + { + Unsafe.Add(ref dRef, 2) = TBinaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TBinaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1)); + goto case 1; + } + + case 1: + { + dRef = TBinaryOperator.Invoke(xRef, yRef); + goto case 0; + } + + case 0: + { + break; + } + } + } + + static void Vectorized256(ref float xRef, ref float yRef, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector256 beg = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + Vector256.LoadUnsafe(ref yRef)); + Vector256 end = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count))); + + if (remainder > (uint)(Vector256.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* yPtr = py; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector256)) - ((nuint)(dPtr) % (uint)(sizeof(Vector256)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector256))) == 0); + + remainder -= misalignment; + } + + Vector256 vector1; + Vector256 vector2; + Vector256 vector3; + Vector256 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 0))); + vector2 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 1))); + vector3 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 2))); + vector4 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 3))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 4))); + vector2 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 5))); + vector3 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 6))); + vector4 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 7))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + yPtr += (uint)(Vector256.Count * 8); + dPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 0))); + vector2 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 1))); + vector3 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 2))); + vector4 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 3))); + + vector1.Store(dPtr + (uint)(Vector256.Count * 0)); + vector2.Store(dPtr + (uint)(Vector256.Count * 1)); + vector3.Store(dPtr + (uint)(Vector256.Count * 2)); + vector4.Store(dPtr + (uint)(Vector256.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 4))); + vector2 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 5))); + vector3 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 6))); + vector4 = TBinaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 7))); + + vector1.Store(dPtr + (uint)(Vector256.Count * 4)); + vector2.Store(dPtr + (uint)(Vector256.Count * 5)); + vector3.Store(dPtr + (uint)(Vector256.Count * 6)); + vector4.Store(dPtr + (uint)(Vector256.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + yPtr += (uint)(Vector256.Count * 8); + dPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector256.Count - 1)) & (nuint)(-Vector256.Count); + + switch (remainder / (uint)(Vector256.Count)) + { + case 8: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 8)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 8))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 8)); + goto case 7; + } + + case 7: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 7)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 7))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 7)); + goto case 6; + } + + case 6: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 6)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 6))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 6)); + goto case 5; + } + + case 5: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 5)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 5))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 5)); + goto case 4; + } + + case 4: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 4)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 4))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 4)); + goto case 3; + } + + case 3: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 3)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 3))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 3)); + goto case 2; + } + + case 2: + { + Vector256 vector = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 2)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 2))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector256.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized256Small(ref float xRef, ref float yRef, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef)); + Vector128 end = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count))); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count)); + + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = TBinaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TBinaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1)); + goto case 1; + } + + case 1: + { + dRef = TBinaryOperator.Invoke(xRef, yRef); + goto case 0; + } + + case 0: + { + break; + } + } + } + +#if NET8_0_OR_GREATER + static void Vectorized512(ref float xRef, ref float yRef, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector512 beg = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef), + Vector512.LoadUnsafe(ref yRef)); + Vector512 end = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count))); + + if (remainder > (uint)(Vector512.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* yPtr = py; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector512)) - ((nuint)(dPtr) % (uint)(sizeof(Vector512)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector512))) == 0); + + remainder -= misalignment; + } + + Vector512 vector1; + Vector512 vector2; + Vector512 vector3; + Vector512 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 0))); + vector2 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 1))); + vector3 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 2))); + vector4 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 3))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 4))); + vector2 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 5))); + vector3 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 6))); + vector4 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 7))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + yPtr += (uint)(Vector512.Count * 8); + dPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 0))); + vector2 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 1))); + vector3 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 2))); + vector4 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 3))); + + vector1.Store(dPtr + (uint)(Vector512.Count * 0)); + vector2.Store(dPtr + (uint)(Vector512.Count * 1)); + vector3.Store(dPtr + (uint)(Vector512.Count * 2)); + vector4.Store(dPtr + (uint)(Vector512.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 4))); + vector2 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 5))); + vector3 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 6))); + vector4 = TBinaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 7))); + + vector1.Store(dPtr + (uint)(Vector512.Count * 4)); + vector2.Store(dPtr + (uint)(Vector512.Count * 5)); + vector3.Store(dPtr + (uint)(Vector512.Count * 6)); + vector4.Store(dPtr + (uint)(Vector512.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + yPtr += (uint)(Vector512.Count * 8); + dPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector512.Count - 1)) & (nuint)(-Vector512.Count); + + switch (remainder / (uint)(Vector512.Count)) + { + case 8: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 8)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 8))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 8)); + goto case 7; + } + + case 7: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 7)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 7))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 7)); + goto case 6; + } + + case 6: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 6)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 6))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 6)); + goto case 5; + } + + case 5: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 5)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 5))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 5)); + goto case 4; + } + + case 4: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 4)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 4))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 4)); + goto case 3; + } + + case 3: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 3)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 3))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 3)); + goto case 2; + } + + case 2: + { + Vector512 vector = TBinaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 2)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 2))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector512.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized512Small(ref float xRef, ref float yRef, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 15: + case 14: + case 13: + case 12: + case 11: + case 10: + case 9: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + + Vector256 beg = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + Vector256.LoadUnsafe(ref yRef)); + Vector256 end = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count))); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count)); + + break; + } + + case 8: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + + Vector256 beg = TBinaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + Vector256.LoadUnsafe(ref yRef)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef)); + Vector128 end = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count))); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count)); + + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TBinaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = TBinaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TBinaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1)); + goto case 1; + } + + case 1: + { + dRef = TBinaryOperator.Invoke(xRef, yRef); + goto case 0; + } + + case 0: + { + break; + } + } + } +#endif + } + + /// + /// Performs an element-wise operation on and , + /// and writes the results to . + /// + /// + /// Specifies the operation to perform on each element loaded from with . + /// + private static void InvokeSpanScalarIntoSpan( + ReadOnlySpan x, float y, Span destination) + where TBinaryOperator : struct, IBinaryOperator => + InvokeSpanScalarIntoSpan(x, y, destination); + + /// + /// Performs an element-wise operation on and , + /// and writes the results to . + /// + /// + /// Specifies the operation to perform on each element loaded from . + /// It is not used with . + /// + /// + /// Specifies the operation to perform on the transformed value from with . + /// + private static void InvokeSpanScalarIntoSpan( + ReadOnlySpan x, float y, Span destination) + where TTransformOperator : struct, IUnaryOperator + where TBinaryOperator : struct, IBinaryOperator + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ValidateInputOutputSpanNonOverlapping(x, destination); + + // Since every branch has a cost and since that cost is + // essentially lost for larger inputs, we do branches + // in a way that allows us to have the minimum possible + // for small sizes + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + nuint remainder = (uint)(x.Length); + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector512.Count)) + { + Vectorized512(ref xRef, y, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized512Small(ref xRef, y, ref dRef, remainder); + } + + return; + } +#endif + + if (Vector256.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector256.Count)) + { + Vectorized256(ref xRef, y, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized256Small(ref xRef, y, ref dRef, remainder); + } + + return; + } + + if (Vector128.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector128.Count)) + { + Vectorized128(ref xRef, y, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized128Small(ref xRef, y, ref dRef, remainder); + } + + return; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + SoftwareFallback(ref xRef, y, ref dRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void SoftwareFallback(ref float xRef, float y, ref float dRef, nuint length) + { + for (nuint i = 0; i < length; i++) + { + Unsafe.Add(ref dRef, i) = TBinaryOperator.Invoke(TTransformOperator.Invoke(Unsafe.Add(ref xRef, i)), + y); + } + } + + static void Vectorized128(ref float xRef, float y, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector128 yVec = Vector128.Create(y); + + Vector128 beg = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef)), + yVec); + Vector128 end = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count))), + yVec); + + if (remainder > (uint)(Vector128.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector128)) - ((nuint)(dPtr) % (uint)(sizeof(Vector128)))) / sizeof(float); + + xPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector128))) == 0); + + remainder -= misalignment; + } + + Vector128 vector1; + Vector128 vector2; + Vector128 vector3; + Vector128 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0))), + yVec); + vector2 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1))), + yVec); + vector3 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2))), + yVec); + vector4 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3))), + yVec); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4))), + yVec); + vector2 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5))), + yVec); + vector3 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6))), + yVec); + vector4 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7))), + yVec); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + dPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0))), + yVec); + vector2 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1))), + yVec); + vector3 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2))), + yVec); + vector4 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3))), + yVec); + + vector1.Store(dPtr + (uint)(Vector128.Count * 0)); + vector2.Store(dPtr + (uint)(Vector128.Count * 1)); + vector3.Store(dPtr + (uint)(Vector128.Count * 2)); + vector4.Store(dPtr + (uint)(Vector128.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4))), + yVec); + vector2 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5))), + yVec); + vector3 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6))), + yVec); + vector4 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7))), + yVec); + + vector1.Store(dPtr + (uint)(Vector128.Count * 4)); + vector2.Store(dPtr + (uint)(Vector128.Count * 5)); + vector3.Store(dPtr + (uint)(Vector128.Count * 6)); + vector4.Store(dPtr + (uint)(Vector128.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + dPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector128.Count - 1)) & (nuint)(-Vector128.Count); + + switch (remainder / (uint)(Vector128.Count)) + { + case 8: + { + Vector128 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 8))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 8)); + goto case 7; + } + + case 7: + { + Vector128 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 7))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 7)); + goto case 6; + } + + case 6: + { + Vector128 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 6))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 6)); + goto case 5; + } + + case 5: + { + Vector128 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 5))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 5)); + goto case 4; + } + + case 4: + { + Vector128 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 4))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 4)); + goto case 3; + } + + case 3: + { + Vector128 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 3))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 3)); + goto case 2; + } + + case 2: + { + Vector128 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 2))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector128.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized128Small(ref float xRef, float y, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 3: + { + Unsafe.Add(ref dRef, 2) = TBinaryOperator.Invoke(TTransformOperator.Invoke(Unsafe.Add(ref xRef, 2)), + y); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TBinaryOperator.Invoke(TTransformOperator.Invoke(Unsafe.Add(ref xRef, 1)), + y); + goto case 1; + } + + case 1: + { + dRef = TBinaryOperator.Invoke(TTransformOperator.Invoke(xRef), y); + goto case 0; + } + + case 0: + { + break; + } + } + } + + static void Vectorized256(ref float xRef, float y, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector256 yVec = Vector256.Create(y); + + Vector256 beg = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef)), + yVec); + Vector256 end = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count))), + yVec); + + if (remainder > (uint)(Vector256.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector256)) - ((nuint)(dPtr) % (uint)(sizeof(Vector256)))) / sizeof(float); + + xPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector256))) == 0); + + remainder -= misalignment; + } + + Vector256 vector1; + Vector256 vector2; + Vector256 vector3; + Vector256 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0))), + yVec); + vector2 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1))), + yVec); + vector3 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2))), + yVec); + vector4 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3))), + yVec); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4))), + yVec); + vector2 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5))), + yVec); + vector3 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6))), + yVec); + vector4 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7))), + yVec); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + dPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0))), + yVec); + vector2 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1))), + yVec); + vector3 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2))), + yVec); + vector4 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3))), + yVec); + + vector1.Store(dPtr + (uint)(Vector256.Count * 0)); + vector2.Store(dPtr + (uint)(Vector256.Count * 1)); + vector3.Store(dPtr + (uint)(Vector256.Count * 2)); + vector4.Store(dPtr + (uint)(Vector256.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4))), + yVec); + vector2 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5))), + yVec); + vector3 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6))), + yVec); + vector4 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7))), + yVec); + + vector1.Store(dPtr + (uint)(Vector256.Count * 4)); + vector2.Store(dPtr + (uint)(Vector256.Count * 5)); + vector3.Store(dPtr + (uint)(Vector256.Count * 6)); + vector4.Store(dPtr + (uint)(Vector256.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + dPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector256.Count - 1)) & (nuint)(-Vector256.Count); + + switch (remainder / (uint)(Vector256.Count)) + { + case 8: + { + Vector256 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 8))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 8)); + goto case 7; + } + + case 7: + { + Vector256 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 7))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 7)); + goto case 6; + } + + case 6: + { + Vector256 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 6))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 6)); + goto case 5; + } + + case 5: + { + Vector256 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 5))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 5)); + goto case 4; + } + + case 4: + { + Vector256 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 4))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 4)); + goto case 3; + } + + case 3: + { + Vector256 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 3))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 3)); + goto case 2; + } + + case 2: + { + Vector256 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 2))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector256.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized256Small(ref float xRef, float y, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 yVec = Vector128.Create(y); + + Vector128 beg = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef)), + yVec); + Vector128 end = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count))), + yVec); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count)); + + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef)), + Vector128.Create(y)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = TBinaryOperator.Invoke(TTransformOperator.Invoke(Unsafe.Add(ref xRef, 2)), + y); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TBinaryOperator.Invoke(TTransformOperator.Invoke(Unsafe.Add(ref xRef, 1)), + y); + goto case 1; + } + + case 1: + { + dRef = TBinaryOperator.Invoke(TTransformOperator.Invoke(xRef), y); + goto case 0; + } + + case 0: + { + break; + } + } + } + +#if NET8_0_OR_GREATER + static void Vectorized512(ref float xRef, float y, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector512 yVec = Vector512.Create(y); + + Vector512 beg = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef)), + yVec); + Vector512 end = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count))), + yVec); + + if (remainder > (uint)(Vector512.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector512)) - ((nuint)(dPtr) % (uint)(sizeof(Vector512)))) / sizeof(float); + + xPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector512))) == 0); + + remainder -= misalignment; + } + + Vector512 vector1; + Vector512 vector2; + Vector512 vector3; + Vector512 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0))), + yVec); + vector2 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1))), + yVec); + vector3 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2))), + yVec); + vector4 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3))), + yVec); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4))), + yVec); + vector2 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5))), + yVec); + vector3 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6))), + yVec); + vector4 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7))), + yVec); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + dPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0))), + yVec); + vector2 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1))), + yVec); + vector3 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2))), + yVec); + vector4 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3))), + yVec); + + vector1.Store(dPtr + (uint)(Vector512.Count * 0)); + vector2.Store(dPtr + (uint)(Vector512.Count * 1)); + vector3.Store(dPtr + (uint)(Vector512.Count * 2)); + vector4.Store(dPtr + (uint)(Vector512.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4))), + yVec); + vector2 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5))), + yVec); + vector3 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6))), + yVec); + vector4 = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7))), + yVec); + + vector1.Store(dPtr + (uint)(Vector512.Count * 4)); + vector2.Store(dPtr + (uint)(Vector512.Count * 5)); + vector3.Store(dPtr + (uint)(Vector512.Count * 6)); + vector4.Store(dPtr + (uint)(Vector512.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + dPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector512.Count - 1)) & (nuint)(-Vector512.Count); + + switch (remainder / (uint)(Vector512.Count)) + { + case 8: + { + Vector512 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 8))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 8)); + goto case 7; + } + + case 7: + { + Vector512 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 7))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 7)); + goto case 6; + } + + case 6: + { + Vector512 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 6))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 6)); + goto case 5; + } + + case 5: + { + Vector512 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 5))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 5)); + goto case 4; + } + + case 4: + { + Vector512 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 4))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 4)); + goto case 3; + } + + case 3: + { + Vector512 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 3))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 3)); + goto case 2; + } + + case 2: + { + Vector512 vector = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 2))), + yVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector512.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized512Small(ref float xRef, float y, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 15: + case 14: + case 13: + case 12: + case 11: + case 10: + case 9: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + + Vector256 yVec = Vector256.Create(y); + + Vector256 beg = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef)), + yVec); + Vector256 end = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count))), + yVec); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count)); + + break; + } + + case 8: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + + Vector256 beg = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector256.LoadUnsafe(ref xRef)), + Vector256.Create(y)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 yVec = Vector128.Create(y); + + Vector128 beg = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef)), + yVec); + Vector128 end = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count))), + yVec); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count)); + + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TBinaryOperator.Invoke(TTransformOperator.Invoke(Vector128.LoadUnsafe(ref xRef)), + Vector128.Create(y)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = TBinaryOperator.Invoke(TTransformOperator.Invoke(Unsafe.Add(ref xRef, 2)), + y); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TBinaryOperator.Invoke(TTransformOperator.Invoke(Unsafe.Add(ref xRef, 1)), + y); + goto case 1; + } + + case 1: + { + dRef = TBinaryOperator.Invoke(TTransformOperator.Invoke(xRef), y); + goto case 0; + } + + case 0: + { + break; + } + } + } +#endif + } + + /// + /// Performs an element-wise operation on , , and , + /// and writes the results to . + /// + /// + /// Specifies the operation to perform on the pair-wise elements loaded from , , + /// and . + /// + private static void InvokeSpanSpanSpanIntoSpan( + ReadOnlySpan x, ReadOnlySpan y, ReadOnlySpan z, Span destination) + where TTernaryOperator : struct, ITernaryOperator + { + if (x.Length != y.Length || x.Length != z.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ValidateInputOutputSpanNonOverlapping(x, destination); + ValidateInputOutputSpanNonOverlapping(y, destination); + ValidateInputOutputSpanNonOverlapping(z, destination); + + // Since every branch has a cost and since that cost is + // essentially lost for larger inputs, we do branches + // in a way that allows us to have the minimum possible + // for small sizes + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float zRef = ref MemoryMarshal.GetReference(z); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + nuint remainder = (uint)(x.Length); + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector512.Count)) + { + Vectorized512(ref xRef, ref yRef, ref zRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized512Small(ref xRef, ref yRef, ref zRef, ref dRef, remainder); + } + + return; + } +#endif + + if (Vector256.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector256.Count)) + { + Vectorized256(ref xRef, ref yRef, ref zRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized256Small(ref xRef, ref yRef, ref zRef, ref dRef, remainder); + } + + return; + } + + if (Vector128.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector128.Count)) + { + Vectorized128(ref xRef, ref yRef, ref zRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized128Small(ref xRef, ref yRef, ref zRef, ref dRef, remainder); + } + + return; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + SoftwareFallback(ref xRef, ref yRef, ref zRef, ref dRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void SoftwareFallback(ref float xRef, ref float yRef, ref float zRef, ref float dRef, nuint length) + { + for (nuint i = 0; i < length; i++) + { + Unsafe.Add(ref dRef, i) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, i), + Unsafe.Add(ref yRef, i), + Unsafe.Add(ref zRef, i)); + } + } + + static void Vectorized128(ref float xRef, ref float yRef, ref float zRef, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef), + Vector128.LoadUnsafe(ref zRef)); + Vector128 end = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count))); + + if (remainder > (uint)(Vector128.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + fixed (float* pz = &zRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* yPtr = py; + float* zPtr = pz; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector128)) - ((nuint)(dPtr) % (uint)(sizeof(Vector128)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + zPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector128))) == 0); + + remainder -= misalignment; + } + + Vector128 vector1; + Vector128 vector2; + Vector128 vector3; + Vector128 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 0)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 0))); + vector2 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 1)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 1))); + vector3 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 2)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 2))); + vector4 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 3)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 3))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 4)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 4))); + vector2 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 5)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 5))); + vector3 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 6)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 6))); + vector4 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 7)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 7))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + yPtr += (uint)(Vector128.Count * 8); + zPtr += (uint)(Vector128.Count * 8); + dPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 0)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 0))); + vector2 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 1)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 1))); + vector3 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 2)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 2))); + vector4 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 3)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 3))); + + vector1.Store(dPtr + (uint)(Vector128.Count * 0)); + vector2.Store(dPtr + (uint)(Vector128.Count * 1)); + vector3.Store(dPtr + (uint)(Vector128.Count * 2)); + vector4.Store(dPtr + (uint)(Vector128.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 4)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 4))); + vector2 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 5)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 5))); + vector3 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 6)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 6))); + vector4 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 7)), + Vector128.Load(zPtr + (uint)(Vector128.Count * 7))); + + vector1.Store(dPtr + (uint)(Vector128.Count * 4)); + vector2.Store(dPtr + (uint)(Vector128.Count * 5)); + vector3.Store(dPtr + (uint)(Vector128.Count * 6)); + vector4.Store(dPtr + (uint)(Vector128.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + yPtr += (uint)(Vector128.Count * 8); + zPtr += (uint)(Vector128.Count * 8); + dPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + zRef = ref *zPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector128.Count - 1)) & (nuint)(-Vector128.Count); + + switch (remainder / (uint)(Vector128.Count)) + { + case 8: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 8)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 8)), + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 8))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 8)); + goto case 7; + } + + case 7: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 7)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 7)), + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 7))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 7)); + goto case 6; + } + + case 6: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 6)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 6)), + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 6))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 6)); + goto case 5; + } + + case 5: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 5)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 5)), + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 5))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 5)); + goto case 4; + } + + case 4: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 4)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 4)), + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 4))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 4)); + goto case 3; + } + + case 3: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 3)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 3)), + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 3))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 3)); + goto case 2; + } + + case 2: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 2)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 2)), + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 2))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector128.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized128Small(ref float xRef, ref float yRef, ref float zRef, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 3: + { + Unsafe.Add(ref dRef, 2) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2), + Unsafe.Add(ref zRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1), + Unsafe.Add(ref zRef, 1)); + goto case 1; + } + + case 1: + { + dRef = TTernaryOperator.Invoke(xRef, yRef, zRef); + goto case 0; + } + + case 0: + { + break; + } + } + } + + static void Vectorized256(ref float xRef, ref float yRef, ref float zRef, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector256 beg = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + Vector256.LoadUnsafe(ref yRef), + Vector256.LoadUnsafe(ref zRef)); + Vector256 end = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count)), + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count))); + + if (remainder > (uint)(Vector256.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + fixed (float* pz = &zRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* yPtr = py; + float* zPtr = pz; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector256)) - ((nuint)(dPtr) % (uint)(sizeof(Vector256)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + zPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector256))) == 0); + + remainder -= misalignment; + } + + Vector256 vector1; + Vector256 vector2; + Vector256 vector3; + Vector256 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 0)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 0))); + vector2 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 1)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 1))); + vector3 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 2)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 2))); + vector4 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 3)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 3))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 4)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 4))); + vector2 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 5)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 5))); + vector3 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 6)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 6))); + vector4 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 7)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 7))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + yPtr += (uint)(Vector256.Count * 8); + zPtr += (uint)(Vector256.Count * 8); + dPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 0)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 0))); + vector2 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 1)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 1))); + vector3 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 2)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 2))); + vector4 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 3)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 3))); + + vector1.Store(dPtr + (uint)(Vector256.Count * 0)); + vector2.Store(dPtr + (uint)(Vector256.Count * 1)); + vector3.Store(dPtr + (uint)(Vector256.Count * 2)); + vector4.Store(dPtr + (uint)(Vector256.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 4)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 4))); + vector2 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 5)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 5))); + vector3 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 6)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 6))); + vector4 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 7)), + Vector256.Load(zPtr + (uint)(Vector256.Count * 7))); + + vector1.Store(dPtr + (uint)(Vector256.Count * 4)); + vector2.Store(dPtr + (uint)(Vector256.Count * 5)); + vector3.Store(dPtr + (uint)(Vector256.Count * 6)); + vector4.Store(dPtr + (uint)(Vector256.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + yPtr += (uint)(Vector256.Count * 8); + zPtr += (uint)(Vector256.Count * 8); + dPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + zRef = ref *zPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector256.Count - 1)) & (nuint)(-Vector256.Count); + + switch (remainder / (uint)(Vector256.Count)) + { + case 8: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 8)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 8)), + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 8))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 8)); + goto case 7; + } + + case 7: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 7)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 7)), + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 7))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 7)); + goto case 6; + } + + case 6: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 6)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 6)), + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 6))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 6)); + goto case 5; + } + + case 5: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 5)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 5)), + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 5))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 5)); + goto case 4; + } + + case 4: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 4)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 4)), + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 4))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 4)); + goto case 3; + } + + case 3: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 3)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 3)), + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 3))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 3)); + goto case 2; + } + + case 2: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 2)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 2)), + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 2))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector256.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized256Small(ref float xRef, ref float yRef, ref float zRef, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef), + Vector128.LoadUnsafe(ref zRef)); + Vector128 end = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count))); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count)); + + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef), + Vector128.LoadUnsafe(ref zRef)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2), + Unsafe.Add(ref zRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1), + Unsafe.Add(ref zRef, 1)); + goto case 1; + } + + case 1: + { + dRef = TTernaryOperator.Invoke(xRef, yRef, zRef); + goto case 0; + } + + case 0: + { + break; + } + } + } + +#if NET8_0_OR_GREATER + static void Vectorized512(ref float xRef, ref float yRef, ref float zRef, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector512 beg = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef), + Vector512.LoadUnsafe(ref yRef), + Vector512.LoadUnsafe(ref zRef)); + Vector512 end = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count)), + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count))); + + if (remainder > (uint)(Vector512.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + fixed (float* pz = &zRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* yPtr = py; + float* zPtr = pz; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector512)) - ((nuint)(dPtr) % (uint)(sizeof(Vector512)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + zPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector512))) == 0); + + remainder -= misalignment; + } + + Vector512 vector1; + Vector512 vector2; + Vector512 vector3; + Vector512 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 0)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 0))); + vector2 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 1)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 1))); + vector3 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 2)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 2))); + vector4 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 3)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 3))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 4)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 4))); + vector2 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 5)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 5))); + vector3 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 6)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 6))); + vector4 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 7)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 7))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + yPtr += (uint)(Vector512.Count * 8); + zPtr += (uint)(Vector512.Count * 8); + dPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 0)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 0))); + vector2 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 1)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 1))); + vector3 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 2)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 2))); + vector4 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 3)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 3))); + + vector1.Store(dPtr + (uint)(Vector512.Count * 0)); + vector2.Store(dPtr + (uint)(Vector512.Count * 1)); + vector3.Store(dPtr + (uint)(Vector512.Count * 2)); + vector4.Store(dPtr + (uint)(Vector512.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 4)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 4))); + vector2 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 5)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 5))); + vector3 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 6)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 6))); + vector4 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 7)), + Vector512.Load(zPtr + (uint)(Vector512.Count * 7))); + + vector1.Store(dPtr + (uint)(Vector512.Count * 4)); + vector2.Store(dPtr + (uint)(Vector512.Count * 5)); + vector3.Store(dPtr + (uint)(Vector512.Count * 6)); + vector4.Store(dPtr + (uint)(Vector512.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + yPtr += (uint)(Vector512.Count * 8); + zPtr += (uint)(Vector512.Count * 8); + dPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + zRef = ref *zPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector512.Count - 1)) & (nuint)(-Vector512.Count); + + switch (remainder / (uint)(Vector512.Count)) + { + case 8: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 8)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 8)), + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 8))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 8)); + goto case 7; + } + + case 7: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 7)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 7)), + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 7))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 7)); + goto case 6; + } + + case 6: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 6)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 6)), + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 6))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 6)); + goto case 5; + } + + case 5: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 5)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 5)), + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 5))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 5)); + goto case 4; + } + + case 4: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 4)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 4)), + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 4))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 4)); + goto case 3; + } + + case 3: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 3)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 3)), + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 3))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 3)); + goto case 2; + } + + case 2: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 2)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 2)), + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 2))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector512.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized512Small(ref float xRef, ref float yRef, ref float zRef, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 15: + case 14: + case 13: + case 12: + case 11: + case 10: + case 9: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + + Vector256 beg = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + Vector256.LoadUnsafe(ref yRef), + Vector256.LoadUnsafe(ref zRef)); + Vector256 end = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count)), + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count))); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count)); + + break; + } + + case 8: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + + Vector256 beg = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + Vector256.LoadUnsafe(ref yRef), + Vector256.LoadUnsafe(ref zRef)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef), + Vector128.LoadUnsafe(ref zRef)); + Vector128 end = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count))); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count)); + + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef), + Vector128.LoadUnsafe(ref zRef)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2), + Unsafe.Add(ref zRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1), + Unsafe.Add(ref zRef, 1)); + goto case 1; + } + + case 1: + { + dRef = TTernaryOperator.Invoke(xRef, yRef, zRef); + goto case 0; + } + + case 0: + { + break; + } + } + } +#endif + } + + /// + /// Performs an element-wise operation on , , and , + /// and writes the results to . + /// + /// + /// Specifies the operation to perform on the pair-wise elements loaded from and + /// with . + /// + private static void InvokeSpanSpanScalarIntoSpan( + ReadOnlySpan x, ReadOnlySpan y, float z, Span destination) + where TTernaryOperator : struct, ITernaryOperator + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ValidateInputOutputSpanNonOverlapping(x, destination); + ValidateInputOutputSpanNonOverlapping(y, destination); + + // Since every branch has a cost and since that cost is + // essentially lost for larger inputs, we do branches + // in a way that allows us to have the minimum possible + // for small sizes + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + nuint remainder = (uint)(x.Length); + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector512.Count)) + { + Vectorized512(ref xRef, ref yRef, z, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized512Small(ref xRef, ref yRef, z, ref dRef, remainder); + } + + return; + } +#endif + + if (Vector256.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector256.Count)) + { + Vectorized256(ref xRef, ref yRef, z, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized256Small(ref xRef, ref yRef, z, ref dRef, remainder); + } + + return; + } + + if (Vector128.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector128.Count)) + { + Vectorized128(ref xRef, ref yRef, z, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized128Small(ref xRef, ref yRef, z, ref dRef, remainder); + } + + return; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + SoftwareFallback(ref xRef, ref yRef, z, ref dRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void SoftwareFallback(ref float xRef, ref float yRef, float z, ref float dRef, nuint length) + { + for (nuint i = 0; i < length; i++) + { + Unsafe.Add(ref dRef, i) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, i), + Unsafe.Add(ref yRef, i), + z); + } + } + + static void Vectorized128(ref float xRef, ref float yRef, float z, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector128 zVec = Vector128.Create(z); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef), + zVec); + Vector128 end = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count)), + zVec); + + if (remainder > (uint)(Vector128.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* yPtr = py; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector128)) - ((nuint)(dPtr) % (uint)(sizeof(Vector128)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector128))) == 0); + + remainder -= misalignment; + } + + Vector128 vector1; + Vector128 vector2; + Vector128 vector3; + Vector128 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 0)), + zVec); + vector2 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 1)), + zVec); + vector3 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 2)), + zVec); + vector4 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 3)), + zVec); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 4)), + zVec); + vector2 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 5)), + zVec); + vector3 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 6)), + zVec); + vector4 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 7)), + zVec); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + yPtr += (uint)(Vector128.Count * 8); + dPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 0)), + zVec); + vector2 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 1)), + zVec); + vector3 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 2)), + zVec); + vector4 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 3)), + zVec); + + vector1.Store(dPtr + (uint)(Vector128.Count * 0)); + vector2.Store(dPtr + (uint)(Vector128.Count * 1)); + vector3.Store(dPtr + (uint)(Vector128.Count * 2)); + vector4.Store(dPtr + (uint)(Vector128.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 4)), + zVec); + vector2 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 5)), + zVec); + vector3 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 6)), + zVec); + vector4 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7)), + Vector128.Load(yPtr + (uint)(Vector128.Count * 7)), + zVec); + + vector1.Store(dPtr + (uint)(Vector128.Count * 4)); + vector2.Store(dPtr + (uint)(Vector128.Count * 5)); + vector3.Store(dPtr + (uint)(Vector128.Count * 6)); + vector4.Store(dPtr + (uint)(Vector128.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + yPtr += (uint)(Vector128.Count * 8); + dPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector128.Count - 1)) & (nuint)(-Vector128.Count); + + switch (remainder / (uint)(Vector128.Count)) + { + case 8: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 8)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 8)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 8)); + goto case 7; + } + + case 7: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 7)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 7)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 7)); + goto case 6; + } + + case 6: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 6)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 6)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 6)); + goto case 5; + } + + case 5: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 5)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 5)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 5)); + goto case 4; + } + + case 4: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 4)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 4)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 4)); + goto case 3; + } + + case 3: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 3)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 3)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 3)); + goto case 2; + } + + case 2: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 2)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count * 2)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector128.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized128Small(ref float xRef, ref float yRef, float z, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 3: + { + Unsafe.Add(ref dRef, 2) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2), + z); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1), + z); + goto case 1; + } + + case 1: + { + dRef = TTernaryOperator.Invoke(xRef, yRef, z); + goto case 0; + } + + case 0: + { + break; + } + } + } + + static void Vectorized256(ref float xRef, ref float yRef, float z, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector256 zVec = Vector256.Create(z); + + Vector256 beg = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + Vector256.LoadUnsafe(ref yRef), + zVec); + Vector256 end = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count)), + zVec); + + if (remainder > (uint)(Vector256.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* yPtr = py; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector256)) - ((nuint)(dPtr) % (uint)(sizeof(Vector256)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector256))) == 0); + + remainder -= misalignment; + } + + Vector256 vector1; + Vector256 vector2; + Vector256 vector3; + Vector256 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 0)), + zVec); + vector2 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 1)), + zVec); + vector3 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 2)), + zVec); + vector4 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 3)), + zVec); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 4)), + zVec); + vector2 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 5)), + zVec); + vector3 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 6)), + zVec); + vector4 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 7)), + zVec); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + yPtr += (uint)(Vector256.Count * 8); + dPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 0)), + zVec); + vector2 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 1)), + zVec); + vector3 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 2)), + zVec); + vector4 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 3)), + zVec); + + vector1.Store(dPtr + (uint)(Vector256.Count * 0)); + vector2.Store(dPtr + (uint)(Vector256.Count * 1)); + vector3.Store(dPtr + (uint)(Vector256.Count * 2)); + vector4.Store(dPtr + (uint)(Vector256.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 4)), + zVec); + vector2 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 5)), + zVec); + vector3 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 6)), + zVec); + vector4 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7)), + Vector256.Load(yPtr + (uint)(Vector256.Count * 7)), + zVec); + + vector1.Store(dPtr + (uint)(Vector256.Count * 4)); + vector2.Store(dPtr + (uint)(Vector256.Count * 5)); + vector3.Store(dPtr + (uint)(Vector256.Count * 6)); + vector4.Store(dPtr + (uint)(Vector256.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + yPtr += (uint)(Vector256.Count * 8); + dPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector256.Count - 1)) & (nuint)(-Vector256.Count); + + switch (remainder / (uint)(Vector256.Count)) + { + case 8: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 8)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 8)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 8)); + goto case 7; + } + + case 7: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 7)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 7)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 7)); + goto case 6; + } + + case 6: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 6)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 6)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 6)); + goto case 5; + } + + case 5: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 5)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 5)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 5)); + goto case 4; + } + + case 4: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 4)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 4)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 4)); + goto case 3; + } + + case 3: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 3)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 3)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 3)); + goto case 2; + } + + case 2: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 2)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count * 2)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector256.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized256Small(ref float xRef, ref float yRef, float z, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 zVec = Vector128.Create(z); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef), + zVec); + Vector128 end = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count)), + zVec); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count)); + + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef), + Vector128.Create(z)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2), + z); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1), + z); + goto case 1; + } + + case 1: + { + dRef = TTernaryOperator.Invoke(xRef, yRef, z); + goto case 0; + } + + case 0: + { + break; + } + } + } + +#if NET8_0_OR_GREATER + static void Vectorized512(ref float xRef, ref float yRef, float z, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector512 zVec = Vector512.Create(z); + + Vector512 beg = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef), + Vector512.LoadUnsafe(ref yRef), + zVec); + Vector512 end = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count)), + zVec); + + if (remainder > (uint)(Vector512.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* yPtr = py; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector512)) - ((nuint)(dPtr) % (uint)(sizeof(Vector512)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector512))) == 0); + + remainder -= misalignment; + } + + Vector512 vector1; + Vector512 vector2; + Vector512 vector3; + Vector512 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 0)), + zVec); + vector2 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 1)), + zVec); + vector3 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 2)), + zVec); + vector4 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 3)), + zVec); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 4)), + zVec); + vector2 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 5)), + zVec); + vector3 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 6)), + zVec); + vector4 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 7)), + zVec); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + yPtr += (uint)(Vector512.Count * 8); + dPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 0)), + zVec); + vector2 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 1)), + zVec); + vector3 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 2)), + zVec); + vector4 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 3)), + zVec); + + vector1.Store(dPtr + (uint)(Vector512.Count * 0)); + vector2.Store(dPtr + (uint)(Vector512.Count * 1)); + vector3.Store(dPtr + (uint)(Vector512.Count * 2)); + vector4.Store(dPtr + (uint)(Vector512.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 4)), + zVec); + vector2 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 5)), + zVec); + vector3 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 6)), + zVec); + vector4 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7)), + Vector512.Load(yPtr + (uint)(Vector512.Count * 7)), + zVec); + + vector1.Store(dPtr + (uint)(Vector512.Count * 4)); + vector2.Store(dPtr + (uint)(Vector512.Count * 5)); + vector3.Store(dPtr + (uint)(Vector512.Count * 6)); + vector4.Store(dPtr + (uint)(Vector512.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + yPtr += (uint)(Vector512.Count * 8); + dPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector512.Count - 1)) & (nuint)(-Vector512.Count); + + switch (remainder / (uint)(Vector512.Count)) + { + case 8: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 8)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 8)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 8)); + goto case 7; + } + + case 7: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 7)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 7)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 7)); + goto case 6; + } + + case 6: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 6)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 6)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 6)); + goto case 5; + } + + case 5: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 5)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 5)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 5)); + goto case 4; + } + + case 4: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 4)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 4)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 4)); + goto case 3; + } + + case 3: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 3)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 3)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 3)); + goto case 2; + } + + case 2: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 2)), + Vector512.LoadUnsafe(ref yRef, remainder - (uint)(Vector512.Count * 2)), + zVec); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector512.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized512Small(ref float xRef, ref float yRef, float z, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 15: + case 14: + case 13: + case 12: + case 11: + case 10: + case 9: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + + Vector256 zVec = Vector256.Create(z); + + Vector256 beg = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + Vector256.LoadUnsafe(ref yRef), + zVec); + Vector256 end = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count)), + Vector256.LoadUnsafe(ref yRef, remainder - (uint)(Vector256.Count)), + zVec); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count)); + + break; + } + + case 8: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + + Vector256 beg = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + Vector256.LoadUnsafe(ref yRef), + Vector256.Create(z)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 zVec = Vector128.Create(z); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef), + zVec); + Vector128 end = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + Vector128.LoadUnsafe(ref yRef, remainder - (uint)(Vector128.Count)), + zVec); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count)); + + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.LoadUnsafe(ref yRef), + Vector128.Create(z)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2), + z); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1), + z); + goto case 1; + } + + case 1: + { + dRef = TTernaryOperator.Invoke(xRef, yRef, z); + goto case 0; + } + + case 0: + { + break; + } + } + } +#endif + } + + /// + /// Performs an element-wise operation on , , and , + /// and writes the results to . + /// + /// + /// Specifies the operation to perform on the pair-wise element loaded from , with , + /// and the element loaded from . + /// + private static void InvokeSpanScalarSpanIntoSpan( + ReadOnlySpan x, float y, ReadOnlySpan z, Span destination) + where TTernaryOperator : struct, ITernaryOperator + { + if (x.Length != z.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ValidateInputOutputSpanNonOverlapping(x, destination); + ValidateInputOutputSpanNonOverlapping(z, destination); + + // Since every branch has a cost and since that cost is + // essentially lost for larger inputs, we do branches + // in a way that allows us to have the minimum possible + // for small sizes + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float zRef = ref MemoryMarshal.GetReference(z); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + nuint remainder = (uint)(x.Length); + +#if NET8_0_OR_GREATER + if (Vector512.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector512.Count)) + { + Vectorized512(ref xRef, y, ref zRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized512Small(ref xRef, y, ref zRef, ref dRef, remainder); + } + + return; + } +#endif + + if (Vector256.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector256.Count)) + { + Vectorized256(ref xRef, y, ref zRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized256Small(ref xRef, y, ref zRef, ref dRef, remainder); + } + + return; + } + + if (Vector128.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector128.Count)) + { + Vectorized128(ref xRef, y, ref zRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + Vectorized128Small(ref xRef, y, ref zRef, ref dRef, remainder); + } + + return; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + SoftwareFallback(ref xRef, y, ref zRef, ref dRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void SoftwareFallback(ref float xRef, float y, ref float zRef, ref float dRef, nuint length) + { + for (nuint i = 0; i < length; i++) + { + Unsafe.Add(ref dRef, i) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, i), + y, + Unsafe.Add(ref zRef, i)); + } + } + + static void Vectorized128(ref float xRef, float y, ref float zRef, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector128 yVec = Vector128.Create(y); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + yVec, + Vector128.LoadUnsafe(ref zRef)); + Vector128 end = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + yVec, + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count))); + + if (remainder > (uint)(Vector128.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* pz = &zRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* zPtr = pz; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector128)) - ((nuint)(dPtr) % (uint)(sizeof(Vector128)))) / sizeof(float); + + xPtr += misalignment; + zPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector128))) == 0); + + remainder -= misalignment; + } + + Vector128 vector1; + Vector128 vector2; + Vector128 vector3; + Vector128 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 0))); + vector2 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 1))); + vector3 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 2))); + vector4 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 3))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 4))); + vector2 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 5))); + vector3 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 6))); + vector4 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 7))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector128.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + zPtr += (uint)(Vector128.Count * 8); + dPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector128.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 0)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 0))); + vector2 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 1)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 1))); + vector3 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 2)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 2))); + vector4 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 3)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 3))); + + vector1.Store(dPtr + (uint)(Vector128.Count * 0)); + vector2.Store(dPtr + (uint)(Vector128.Count * 1)); + vector3.Store(dPtr + (uint)(Vector128.Count * 2)); + vector4.Store(dPtr + (uint)(Vector128.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 4)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 4))); + vector2 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 5)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 5))); + vector3 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 6)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 6))); + vector4 = TTernaryOperator.Invoke(Vector128.Load(xPtr + (uint)(Vector128.Count * 7)), + yVec, + Vector128.Load(zPtr + (uint)(Vector128.Count * 7))); + + vector1.Store(dPtr + (uint)(Vector128.Count * 4)); + vector2.Store(dPtr + (uint)(Vector128.Count * 5)); + vector3.Store(dPtr + (uint)(Vector128.Count * 6)); + vector4.Store(dPtr + (uint)(Vector128.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector128.Count * 8); + zPtr += (uint)(Vector128.Count * 8); + dPtr += (uint)(Vector128.Count * 8); + + remainder -= (uint)(Vector128.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + zRef = ref *zPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector128.Count - 1)) & (nuint)(-Vector128.Count); + + switch (remainder / (uint)(Vector128.Count)) + { + case 8: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 8)), + yVec, + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 8))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 8)); + goto case 7; + } + + case 7: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 7)), + yVec, + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 7))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 7)); + goto case 6; + } + + case 6: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 6)), + yVec, + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 6))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 6)); + goto case 5; + } + + case 5: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 5)), + yVec, + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 5))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 5)); + goto case 4; + } + + case 4: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 4)), + yVec, + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 4))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 4)); + goto case 3; + } + + case 3: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 3)), + yVec, + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 3))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 3)); + goto case 2; + } + + case 2: + { + Vector128 vector = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count * 2)), + yVec, + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count * 2))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector128.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized128Small(ref float xRef, float y, ref float zRef, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 3: + { + Unsafe.Add(ref dRef, 2) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + y, + Unsafe.Add(ref zRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + y, + Unsafe.Add(ref zRef, 1)); + goto case 1; + } + + case 1: + { + dRef = TTernaryOperator.Invoke(xRef, y, zRef); + goto case 0; + } + + case 0: + { + break; + } + } + } + + static void Vectorized256(ref float xRef, float y, ref float zRef, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector256 yVec = Vector256.Create(y); + + Vector256 beg = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + yVec, + Vector256.LoadUnsafe(ref zRef)); + Vector256 end = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count)), + yVec, + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count))); + + if (remainder > (uint)(Vector256.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* pz = &zRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* zPtr = pz; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector256)) - ((nuint)(dPtr) % (uint)(sizeof(Vector256)))) / sizeof(float); + + xPtr += misalignment; + zPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector256))) == 0); + + remainder -= misalignment; + } + + Vector256 vector1; + Vector256 vector2; + Vector256 vector3; + Vector256 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 0))); + vector2 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 1))); + vector3 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 2))); + vector4 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 3))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 4))); + vector2 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 5))); + vector3 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 6))); + vector4 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 7))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector256.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + zPtr += (uint)(Vector256.Count * 8); + dPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector256.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 0)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 0))); + vector2 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 1)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 1))); + vector3 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 2)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 2))); + vector4 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 3)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 3))); + + vector1.Store(dPtr + (uint)(Vector256.Count * 0)); + vector2.Store(dPtr + (uint)(Vector256.Count * 1)); + vector3.Store(dPtr + (uint)(Vector256.Count * 2)); + vector4.Store(dPtr + (uint)(Vector256.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 4)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 4))); + vector2 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 5)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 5))); + vector3 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 6)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 6))); + vector4 = TTernaryOperator.Invoke(Vector256.Load(xPtr + (uint)(Vector256.Count * 7)), + yVec, + Vector256.Load(zPtr + (uint)(Vector256.Count * 7))); + + vector1.Store(dPtr + (uint)(Vector256.Count * 4)); + vector2.Store(dPtr + (uint)(Vector256.Count * 5)); + vector3.Store(dPtr + (uint)(Vector256.Count * 6)); + vector4.Store(dPtr + (uint)(Vector256.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector256.Count * 8); + zPtr += (uint)(Vector256.Count * 8); + dPtr += (uint)(Vector256.Count * 8); + + remainder -= (uint)(Vector256.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + zRef = ref *zPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector256.Count - 1)) & (nuint)(-Vector256.Count); + + switch (remainder / (uint)(Vector256.Count)) + { + case 8: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 8)), + yVec, + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 8))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 8)); + goto case 7; + } + + case 7: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 7)), + yVec, + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 7))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 7)); + goto case 6; + } + + case 6: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 6)), + yVec, + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 6))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 6)); + goto case 5; + } + + case 5: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 5)), + yVec, + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 5))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 5)); + goto case 4; + } + + case 4: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 4)), + yVec, + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 4))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 4)); + goto case 3; + } + + case 3: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 3)), + yVec, + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 3))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 3)); + goto case 2; + } + + case 2: + { + Vector256 vector = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count * 2)), + yVec, + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count * 2))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector256.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized256Small(ref float xRef, float y, ref float zRef, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 yVec = Vector128.Create(y); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + yVec, + Vector128.LoadUnsafe(ref zRef)); + Vector128 end = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + yVec, + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count))); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count)); + + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.Create(y), + Vector128.LoadUnsafe(ref zRef)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + y, + Unsafe.Add(ref zRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + y, + Unsafe.Add(ref zRef, 1)); + goto case 1; + } + + case 1: + { + dRef = TTernaryOperator.Invoke(xRef, y, zRef); + goto case 0; + } + + case 0: + { + break; + } + } + } + +#if NET8_0_OR_GREATER + static void Vectorized512(ref float xRef, float y, ref float zRef, ref float dRef, nuint remainder) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector512 yVec = Vector512.Create(y); + + Vector512 beg = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef), + yVec, + Vector512.LoadUnsafe(ref zRef)); + Vector512 end = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count)), + yVec, + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count))); + + if (remainder > (uint)(Vector512.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* pz = &zRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* zPtr = pz; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector512)) - ((nuint)(dPtr) % (uint)(sizeof(Vector512)))) / sizeof(float); + + xPtr += misalignment; + zPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector512))) == 0); + + remainder -= misalignment; + } + + Vector512 vector1; + Vector512 vector2; + Vector512 vector3; + Vector512 vector4; + + if ((remainder > (NonTemporalByteThreshold / sizeof(float))) && canAlign) + { + // This loop stores the data non-temporally, which benefits us when there + // is a large amount of data involved as it avoids polluting the cache. + + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 0))); + vector2 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 1))); + vector3 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 2))); + vector4 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 3))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 0)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 1)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 2)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 4))); + vector2 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 5))); + vector3 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 6))); + vector4 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 7))); + + vector1.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 4)); + vector2.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 5)); + vector3.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 6)); + vector4.StoreAlignedNonTemporal(dPtr + (uint)(Vector512.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + zPtr += (uint)(Vector512.Count * 8); + dPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + } + else + { + while (remainder >= (uint)(Vector512.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 0)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 0))); + vector2 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 1)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 1))); + vector3 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 2)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 2))); + vector4 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 3)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 3))); + + vector1.Store(dPtr + (uint)(Vector512.Count * 0)); + vector2.Store(dPtr + (uint)(Vector512.Count * 1)); + vector3.Store(dPtr + (uint)(Vector512.Count * 2)); + vector4.Store(dPtr + (uint)(Vector512.Count * 3)); + + // We load, process, and store the next four vectors + + vector1 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 4)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 4))); + vector2 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 5)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 5))); + vector3 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 6)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 6))); + vector4 = TTernaryOperator.Invoke(Vector512.Load(xPtr + (uint)(Vector512.Count * 7)), + yVec, + Vector512.Load(zPtr + (uint)(Vector512.Count * 7))); + + vector1.Store(dPtr + (uint)(Vector512.Count * 4)); + vector2.Store(dPtr + (uint)(Vector512.Count * 5)); + vector3.Store(dPtr + (uint)(Vector512.Count * 6)); + vector4.Store(dPtr + (uint)(Vector512.Count * 7)); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector512.Count * 8); + zPtr += (uint)(Vector512.Count * 8); + dPtr += (uint)(Vector512.Count * 8); + + remainder -= (uint)(Vector512.Count * 8); + } + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + zRef = ref *zPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector512.Count - 1)) & (nuint)(-Vector512.Count); + + switch (remainder / (uint)(Vector512.Count)) + { + case 8: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 8)), + yVec, + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 8))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 8)); + goto case 7; + } + + case 7: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 7)), + yVec, + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 7))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 7)); + goto case 6; + } + + case 6: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 6)), + yVec, + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 6))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 6)); + goto case 5; + } + + case 5: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 5)), + yVec, + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 5))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 5)); + goto case 4; + } + + case 4: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 4)), + yVec, + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 4))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 4)); + goto case 3; + } + + case 3: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 3)), + yVec, + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 3))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 3)); + goto case 2; + } + + case 2: + { + Vector512 vector = TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, remainder - (uint)(Vector512.Count * 2)), + yVec, + Vector512.LoadUnsafe(ref zRef, remainder - (uint)(Vector512.Count * 2))); + vector.StoreUnsafe(ref dRef, remainder - (uint)(Vector512.Count * 2)); + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end.StoreUnsafe(ref dRef, endIndex - (uint)Vector512.Count); + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + beg.StoreUnsafe(ref dRefBeg); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void Vectorized512Small(ref float xRef, float y, ref float zRef, ref float dRef, nuint remainder) + { + switch (remainder) + { + case 15: + case 14: + case 13: + case 12: + case 11: + case 10: + case 9: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + + Vector256 yVec = Vector256.Create(y); + + Vector256 beg = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + yVec, + Vector256.LoadUnsafe(ref zRef)); + Vector256 end = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, remainder - (uint)(Vector256.Count)), + yVec, + Vector256.LoadUnsafe(ref zRef, remainder - (uint)(Vector256.Count))); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector256.Count)); + + break; + } + + case 8: + { + Debug.Assert(Vector256.IsHardwareAccelerated); + + Vector256 beg = TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef), + Vector256.Create(y), + Vector256.LoadUnsafe(ref zRef)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 7: + case 6: + case 5: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 yVec = Vector128.Create(y); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + yVec, + Vector128.LoadUnsafe(ref zRef)); + Vector128 end = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, remainder - (uint)(Vector128.Count)), + yVec, + Vector128.LoadUnsafe(ref zRef, remainder - (uint)(Vector128.Count))); + + beg.StoreUnsafe(ref dRef); + end.StoreUnsafe(ref dRef, remainder - (uint)(Vector128.Count)); + + break; + } + + case 4: + { + Debug.Assert(Vector128.IsHardwareAccelerated); + + Vector128 beg = TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef), + Vector128.Create(y), + Vector128.LoadUnsafe(ref zRef)); + beg.StoreUnsafe(ref dRef); + + break; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 2), + y, + Unsafe.Add(ref zRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, 1), + y, + Unsafe.Add(ref zRef, 1)); + goto case 1; + } + + case 1: + { + dRef = TTernaryOperator.Invoke(xRef, y, zRef); + goto case 0; + } + + case 0: + { + break; + } + } + } +#endif + } + + /// Performs (x * y) + z. It will be rounded as one ternary operation if such an operation is accelerated on the current hardware. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128 FusedMultiplyAdd(Vector128 x, Vector128 y, Vector128 addend) + { + if (Fma.IsSupported) + { + return Fma.MultiplyAdd(x, y, addend); + } + + if (AdvSimd.IsSupported) + { + return AdvSimd.FusedMultiplyAdd(addend, x, y); + } + + return (x * y) + addend; + } + + /// Performs (x * y) + z. It will be rounded as one ternary operation if such an operation is accelerated on the current hardware. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector256 FusedMultiplyAdd(Vector256 x, Vector256 y, Vector256 addend) + { + if (Fma.IsSupported) + { + return Fma.MultiplyAdd(x, y, addend); + } + + return (x * y) + addend; + } + +#if NET8_0_OR_GREATER + /// Performs (x * y) + z. It will be rounded as one ternary operation if such an operation is accelerated on the current hardware. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector512 FusedMultiplyAdd(Vector512 x, Vector512 y, Vector512 addend) + { + if (Avx512F.IsSupported) + { + return Avx512F.FusedMultiplyAdd(x, y, addend); + } + + return (x * y) + addend; + } +#endif + + /// Aggregates all of the elements in the into a single value. + /// Specifies the operation to be performed on each pair of values. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static float HorizontalAggregate(Vector128 x) where TAggregate : struct, IBinaryOperator + { + // We need to do log2(count) operations to compute the total sum + + x = TAggregate.Invoke(x, Vector128.Shuffle(x, Vector128.Create(2, 3, 0, 1))); + x = TAggregate.Invoke(x, Vector128.Shuffle(x, Vector128.Create(1, 0, 3, 2))); + + return x.ToScalar(); + } + + /// Aggregates all of the elements in the into a single value. + /// Specifies the operation to be performed on each pair of values. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static float HorizontalAggregate(Vector256 x) where TAggregate : struct, IBinaryOperator => + HorizontalAggregate(TAggregate.Invoke(x.GetLower(), x.GetUpper())); + +#if NET8_0_OR_GREATER + /// Aggregates all of the elements in the into a single value. + /// Specifies the operation to be performed on each pair of values. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static float HorizontalAggregate(Vector512 x) where TAggregate : struct, IBinaryOperator => + HorizontalAggregate(TAggregate.Invoke(x.GetLower(), x.GetUpper())); +#endif + + /// Gets whether the specified is negative. + private static bool IsNegative(float f) => float.IsNegative(f); + + /// Gets whether each specified is negative. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128 IsNegative(Vector128 vector) => + Vector128.LessThan(vector.AsInt32(), Vector128.Zero).AsSingle(); + + /// Gets whether each specified is negative. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector256 IsNegative(Vector256 vector) => + Vector256.LessThan(vector.AsInt32(), Vector256.Zero).AsSingle(); + +#if NET8_0_OR_GREATER + /// Gets whether each specified is negative. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector512 IsNegative(Vector512 vector) => + Vector512.LessThan(vector.AsInt32(), Vector512.Zero).AsSingle(); +#endif + + /// Gets whether the specified is positive. + private static bool IsPositive(float f) => float.IsPositive(f); + + /// Gets whether each specified is positive. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128 IsPositive(Vector128 vector) => + Vector128.GreaterThan(vector.AsInt32(), Vector128.AllBitsSet).AsSingle(); + + /// Gets whether each specified is positive. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector256 IsPositive(Vector256 vector) => + Vector256.GreaterThan(vector.AsInt32(), Vector256.AllBitsSet).AsSingle(); + +#if NET8_0_OR_GREATER + /// Gets whether each specified is positive. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector512 IsPositive(Vector512 vector) => + Vector512.GreaterThan(vector.AsInt32(), Vector512.AllBitsSet).AsSingle(); +#endif + + /// Finds and returns the first NaN value in . + /// The vector must have already been validated to contain a NaN. + private static float GetFirstNaN(Vector128 vector) + { + Debug.Assert(!Vector128.EqualsAll(vector, vector), "Expected vector to contain a NaN"); + return vector.GetElement(BitOperations.TrailingZeroCount((~Vector128.Equals(vector, vector)).ExtractMostSignificantBits())); + } + + /// Finds and returns the first NaN index value in . + /// The vector must have already been validated to contain a NaN. + private static int GetFirstNaNIndex(Vector128 vector, Vector128 index) + { + Debug.Assert(!Vector128.EqualsAll(vector, vector), "Expected vector to contain a NaN"); + return index.GetElement(BitOperations.TrailingZeroCount((~Vector128.Equals(vector, vector)).ExtractMostSignificantBits())); + } + + /// Finds and returns the first NaN value in . + /// The vector must have already been validated to contain a NaN. + private static float GetFirstNaN(Vector256 vector) + { + Debug.Assert(!Vector256.EqualsAll(vector, vector), "Expected vector to contain a NaN"); + return vector.GetElement(BitOperations.TrailingZeroCount((~Vector256.Equals(vector, vector)).ExtractMostSignificantBits())); + } + + /// Finds and returns the first NaN index value in . + /// The vector must have already been validated to contain a NaN. + private static int GetFirstNaNIndex(Vector256 vector, Vector256 index) + { + Debug.Assert(!Vector256.EqualsAll(vector, vector), "Expected vector to contain a NaN"); + return index.GetElement(BitOperations.TrailingZeroCount((~Vector256.Equals(vector, vector)).ExtractMostSignificantBits())); + } + +#if NET8_0_OR_GREATER + /// Finds and returns the first NaN value in . + /// The vector must have already been validated to contain a NaN. + private static float GetFirstNaN(Vector512 vector) + { + Debug.Assert(!Vector512.EqualsAll(vector, vector), "Expected vector to contain a NaN"); + return vector.GetElement(BitOperations.TrailingZeroCount((~Vector512.Equals(vector, vector)).ExtractMostSignificantBits())); + } + + /// Finds and returns the first NaN value in . + /// The vector must have already been validated to contain a NaN. + private static int GetFirstNaNIndex(Vector512 vector, Vector512 index) + { + Debug.Assert(!Vector512.EqualsAll(vector, vector), "Expected vector to contain a NaN"); + return index.GetElement(BitOperations.TrailingZeroCount((~Vector512.Equals(vector, vector)).ExtractMostSignificantBits())); + } +#endif + + /// Gets the base 2 logarithm of . + private static float Log2(float x) => MathF.Log2(x); + + /// + /// Gets a vector mask that will be all-ones-set for the last elements + /// and zero for all other elements. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128 CreateAlignmentMaskSingleVector128(int count) => + Vector128.LoadUnsafe( + ref Unsafe.As(ref MemoryMarshal.GetReference(AlignmentUInt32Mask_16x16)), + (uint)(count * 16)); // first four floats in the row + + /// + /// Gets a vector mask that will be all-ones-set for the last elements + /// and zero for all other elements. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector256 CreateAlignmentMaskSingleVector256(int count) => + Vector256.LoadUnsafe( + ref Unsafe.As(ref MemoryMarshal.GetReference(AlignmentUInt32Mask_16x16)), + (uint)(count * 16)); // first eight floats in the row + +#if NET8_0_OR_GREATER + /// + /// Gets a vector mask that will be all-ones-set for the last elements + /// and zero for all other elements. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector512 CreateAlignmentMaskSingleVector512(int count) => + Vector512.LoadUnsafe( + ref Unsafe.As(ref MemoryMarshal.GetReference(AlignmentUInt32Mask_16x16)), + (uint)(count * 16)); // all sixteen floats in the row +#endif + + /// + /// Gets a vector mask that will be all-ones-set for the last elements + /// and zero for all other elements. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128 CreateRemainderMaskSingleVector128(int count) => + Vector128.LoadUnsafe( + ref Unsafe.As(ref MemoryMarshal.GetReference(RemainderUInt32Mask_16x16)), + (uint)((count * 16) + 12)); // last four floats in the row + + /// + /// Gets a vector mask that will be all-ones-set for the last elements + /// and zero for all other elements. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector256 CreateRemainderMaskSingleVector256(int count) => + Vector256.LoadUnsafe( + ref Unsafe.As(ref MemoryMarshal.GetReference(RemainderUInt32Mask_16x16)), + (uint)((count * 16) + 8)); // last eight floats in the row + +#if NET8_0_OR_GREATER + /// + /// Gets a vector mask that will be all-ones-set for the last elements + /// and zero for all other elements. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector512 CreateRemainderMaskSingleVector512(int count) => + Vector512.LoadUnsafe( + ref Unsafe.As(ref MemoryMarshal.GetReference(RemainderUInt32Mask_16x16)), + (uint)(count * 16)); // all sixteen floats in the row +#endif + + /// x + y + private readonly struct AddOperator : IAggregationOperator + { + public static float Invoke(float x, float y) => x + y; + public static Vector128 Invoke(Vector128 x, Vector128 y) => x + y; + public static Vector256 Invoke(Vector256 x, Vector256 y) => x + y; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x, Vector512 y) => x + y; +#endif + + public static float Invoke(Vector128 x) => Vector128.Sum(x); + public static float Invoke(Vector256 x) => Vector256.Sum(x); +#if NET8_0_OR_GREATER + public static float Invoke(Vector512 x) => Vector512.Sum(x); +#endif + + public static float IdentityValue => 0; + } + + /// x - y + private readonly struct SubtractOperator : IBinaryOperator + { + public static float Invoke(float x, float y) => x - y; + public static Vector128 Invoke(Vector128 x, Vector128 y) => x - y; + public static Vector256 Invoke(Vector256 x, Vector256 y) => x - y; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x, Vector512 y) => x - y; +#endif + } + + /// (x - y) * (x - y) + private readonly struct SubtractSquaredOperator : IBinaryOperator + { + public static float Invoke(float x, float y) + { + float tmp = x - y; + return tmp * tmp; + } + + public static Vector128 Invoke(Vector128 x, Vector128 y) + { + Vector128 tmp = x - y; + return tmp * tmp; + } + + public static Vector256 Invoke(Vector256 x, Vector256 y) + { + Vector256 tmp = x - y; + return tmp * tmp; + } + +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x, Vector512 y) + { + Vector512 tmp = x - y; + return tmp * tmp; + } +#endif + } + + /// x * y + private readonly struct MultiplyOperator : IAggregationOperator + { + public static float Invoke(float x, float y) => x * y; + public static Vector128 Invoke(Vector128 x, Vector128 y) => x * y; + public static Vector256 Invoke(Vector256 x, Vector256 y) => x * y; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x, Vector512 y) => x * y; +#endif + + public static float Invoke(Vector128 x) => HorizontalAggregate(x); + public static float Invoke(Vector256 x) => HorizontalAggregate(x); +#if NET8_0_OR_GREATER + public static float Invoke(Vector512 x) => HorizontalAggregate(x); +#endif + + public static float IdentityValue => 1; + } + + /// x / y + private readonly struct DivideOperator : IBinaryOperator + { + public static float Invoke(float x, float y) => x / y; + public static Vector128 Invoke(Vector128 x, Vector128 y) => x / y; + public static Vector256 Invoke(Vector256 x, Vector256 y) => x / y; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x, Vector512 y) => x / y; +#endif + } + + /// MathF.Max(x, y) (but NaNs may not be propagated) + private readonly struct MaxOperator : IAggregationOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Invoke(float x, float y) => + x == y ? + (IsNegative(x) ? y : x) : + (y > x ? y : x); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 Invoke(Vector128 x, Vector128 y) + { + if (AdvSimd.IsSupported) + { + return AdvSimd.Max(x, y); + } + + return + Vector128.ConditionalSelect(Vector128.Equals(x, y), + Vector128.ConditionalSelect(IsNegative(x), y, x), + Vector128.Max(x, y)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 Invoke(Vector256 x, Vector256 y) => + Vector256.ConditionalSelect(Vector256.Equals(x, y), + Vector256.ConditionalSelect(IsNegative(x), y, x), + Vector256.Max(x, y)); + +#if NET8_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 Invoke(Vector512 x, Vector512 y) => + Vector512.ConditionalSelect(Vector512.Equals(x, y), + Vector512.ConditionalSelect(IsNegative(x), y, x), + Vector512.Max(x, y)); +#endif + + public static float Invoke(Vector128 x) => HorizontalAggregate(x); + public static float Invoke(Vector256 x) => HorizontalAggregate(x); +#if NET8_0_OR_GREATER + public static float Invoke(Vector512 x) => HorizontalAggregate(x); +#endif + } + + private interface IIndexOfOperator + { + static abstract int Invoke(ref float result, float current, int resultIndex, int curIndex); + static abstract int Invoke(Vector128 result, Vector128 resultIndex); + static abstract void Invoke(ref Vector128 result, Vector128 current, ref Vector128 resultIndex, Vector128 curIndex); + static abstract int Invoke(Vector256 result, Vector256 resultIndex); + static abstract void Invoke(ref Vector256 result, Vector256 current, ref Vector256 resultIndex, Vector256 curIndex); +#if NET8_0_OR_GREATER + static abstract int Invoke(Vector512 result, Vector512 resultIndex); + static abstract void Invoke(ref Vector512 result, Vector512 current, ref Vector512 resultIndex, Vector512 curIndex); +#endif + } + + /// Returns the index of MathF.Max(x, y) + private readonly struct IndexOfMaxOperator : IIndexOfOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(Vector128 result, Vector128 maxIndex) + { + Vector128 tmpResult = Vector128.Shuffle(result, Vector128.Create(2, 3, 0, 1)); + Vector128 tmpIndex = Vector128.Shuffle(maxIndex, Vector128.Create(2, 3, 0, 1)); + + Invoke(ref result, tmpResult, ref maxIndex, tmpIndex); + + tmpResult = Vector128.Shuffle(result, Vector128.Create(1, 0, 3, 2)); + tmpIndex = Vector128.Shuffle(maxIndex, Vector128.Create(1, 0, 3, 2)); + + Invoke(ref result, tmpResult, ref maxIndex, tmpIndex); + return maxIndex.ToScalar(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Invoke(ref Vector128 max, Vector128 current, ref Vector128 maxIndex, Vector128 curIndex) + { + Vector128 greaterThanMask = Vector128.GreaterThan(max, current); + + Vector128 equalMask = Vector128.Equals(max, current); + if (equalMask.AsInt32() != Vector128.Zero) + { + Vector128 negativeMask = IsNegative(current); + Vector128 lessThanMask = Vector128.LessThan(maxIndex, curIndex); + + greaterThanMask |= (negativeMask & equalMask) | (~IsNegative(max) & equalMask & lessThanMask.AsSingle()); + } + + max = ElementWiseSelect(greaterThanMask, max, current); + + maxIndex = ElementWiseSelect(greaterThanMask.AsInt32(), maxIndex, curIndex); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(Vector256 result, Vector256 maxIndex) + { + // Max the upper/lower halves of the Vector256 + Vector128 resultLower = result.GetLower(); + Vector128 indexLower = maxIndex.GetLower(); + + Invoke(ref resultLower, result.GetUpper(), ref indexLower, maxIndex.GetUpper()); + return Invoke(resultLower, indexLower); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Invoke(ref Vector256 max, Vector256 current, ref Vector256 maxIndex, Vector256 curIndex) + { + Vector256 greaterThanMask = Vector256.GreaterThan(max, current); + + Vector256 equalMask = Vector256.Equals(max, current); + if (equalMask.AsInt32() != Vector256.Zero) + { + Vector256 negativeMask = IsNegative(current); + Vector256 lessThanMask = Vector256.LessThan(maxIndex, curIndex); + + greaterThanMask |= (negativeMask & equalMask) | (~IsNegative(max) & equalMask & lessThanMask.AsSingle()); + } + + max = ElementWiseSelect(greaterThanMask, max, current); + + maxIndex = ElementWiseSelect(greaterThanMask.AsInt32(), maxIndex, curIndex); + } + +#if NET8_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(Vector512 result, Vector512 resultIndex) + { + // Min the upper/lower halves of the Vector512 + Vector256 resultLower = result.GetLower(); + Vector256 indexLower = resultIndex.GetLower(); + + Invoke(ref resultLower, result.GetUpper(), ref indexLower, resultIndex.GetUpper()); + return Invoke(resultLower, indexLower); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Invoke(ref Vector512 max, Vector512 current, ref Vector512 maxIndex, Vector512 curIndex) + { + Vector512 greaterThanMask = Vector512.GreaterThan(max, current); + + Vector512 equalMask = Vector512.Equals(max, current); + if (equalMask.AsInt32() != Vector512.Zero) + { + Vector512 negativeMask = IsNegative(current); + Vector512 lessThanMask = Vector512.LessThan(maxIndex, curIndex); + + greaterThanMask |= (negativeMask & equalMask) | (~IsNegative(max) & equalMask & lessThanMask.AsSingle()); + } + + max = ElementWiseSelect(greaterThanMask, max, current); + + maxIndex = ElementWiseSelect(greaterThanMask.AsInt32(), maxIndex, curIndex); + } +#endif + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(ref float result, float current, int resultIndex, int curIndex) + { + if (result == current) + { + if (IsNegative(result) && !IsNegative(current)) + { + result = current; + return curIndex; + } + } + else if (current > result) + { + result = current; + return curIndex; + } + + return resultIndex; + } + } + + private readonly struct IndexOfMaxMagnitudeOperator : IIndexOfOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(Vector128 result, Vector128 maxIndex) + { + Vector128 tmpResult = Vector128.Shuffle(result, Vector128.Create(2, 3, 0, 1)); + Vector128 tmpIndex = Vector128.Shuffle(maxIndex, Vector128.Create(2, 3, 0, 1)); + + Invoke(ref result, tmpResult, ref maxIndex, tmpIndex); + + tmpResult = Vector128.Shuffle(result, Vector128.Create(1, 0, 3, 2)); + tmpIndex = Vector128.Shuffle(maxIndex, Vector128.Create(1, 0, 3, 2)); + + Invoke(ref result, tmpResult, ref maxIndex, tmpIndex); + return maxIndex.ToScalar(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Invoke(ref Vector128 max, Vector128 current, ref Vector128 maxIndex, Vector128 curIndex) + { + Vector128 maxMag = Vector128.Abs(max), currentMag = Vector128.Abs(current); + + Vector128 greaterThanMask = Vector128.GreaterThan(maxMag, currentMag); + + Vector128 equalMask = Vector128.Equals(max, current); + if (equalMask.AsInt32() != Vector128.Zero) + { + Vector128 negativeMask = IsNegative(current); + Vector128 lessThanMask = Vector128.LessThan(maxIndex, curIndex); + + greaterThanMask |= (negativeMask & equalMask) | (~IsNegative(max) & equalMask & lessThanMask.AsSingle()); + } + + max = ElementWiseSelect(greaterThanMask, max, current); + + maxIndex = ElementWiseSelect(greaterThanMask.AsInt32(), maxIndex, curIndex); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(Vector256 result, Vector256 maxIndex) + { + // Max the upper/lower halves of the Vector256 + Vector128 resultLower = result.GetLower(); + Vector128 indexLower = maxIndex.GetLower(); + + Invoke(ref resultLower, result.GetUpper(), ref indexLower, maxIndex.GetUpper()); + return Invoke(resultLower, indexLower); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Invoke(ref Vector256 max, Vector256 current, ref Vector256 maxIndex, Vector256 curIndex) + { + Vector256 maxMag = Vector256.Abs(max), currentMag = Vector256.Abs(current); + + Vector256 greaterThanMask = Vector256.GreaterThan(maxMag, currentMag); + + Vector256 equalMask = Vector256.Equals(max, current); + if (equalMask.AsInt32() != Vector256.Zero) + { + Vector256 negativeMask = IsNegative(current); + Vector256 lessThanMask = Vector256.LessThan(maxIndex, curIndex); + + greaterThanMask |= (negativeMask & equalMask) | (~IsNegative(max) & equalMask & lessThanMask.AsSingle()); + } + + max = ElementWiseSelect(greaterThanMask, max, current); + + maxIndex = ElementWiseSelect(greaterThanMask.AsInt32(), maxIndex, curIndex); + } + +#if NET8_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(Vector512 result, Vector512 resultIndex) + { + // Min the upper/lower halves of the Vector512 + Vector256 resultLower = result.GetLower(); + Vector256 indexLower = resultIndex.GetLower(); + + Invoke(ref resultLower, result.GetUpper(), ref indexLower, resultIndex.GetUpper()); + return Invoke(resultLower, indexLower); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Invoke(ref Vector512 max, Vector512 current, ref Vector512 maxIndex, Vector512 curIndex) + { + Vector512 maxMag = Vector512.Abs(max), currentMag = Vector512.Abs(current); + Vector512 greaterThanMask = Vector512.GreaterThan(maxMag, currentMag); + + Vector512 equalMask = Vector512.Equals(max, current); + if (equalMask.AsInt32() != Vector512.Zero) + { + Vector512 negativeMask = IsNegative(current); + Vector512 lessThanMask = Vector512.LessThan(maxIndex, curIndex); + + greaterThanMask |= (negativeMask & equalMask) | (~IsNegative(max) & equalMask & lessThanMask.AsSingle()); + } + + max = ElementWiseSelect(greaterThanMask, max, current); + + maxIndex = ElementWiseSelect(greaterThanMask.AsInt32(), maxIndex, curIndex); + } +#endif + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(ref float result, float current, int resultIndex, int curIndex) + { + float curMaxAbs = MathF.Abs(result); + float currentAbs = MathF.Abs(current); + + if (curMaxAbs == currentAbs) + { + if (IsNegative(result) && !IsNegative(current)) + { + result = current; + return curIndex; + } + } + else if (currentAbs > curMaxAbs) + { + result = current; + return curIndex; + } + + return resultIndex; + } + } + + /// Returns the index of MathF.Min(x, y) + private readonly struct IndexOfMinOperator : IIndexOfOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(Vector128 result, Vector128 resultIndex) + { + Vector128 tmpResult = Vector128.Shuffle(result, Vector128.Create(2, 3, 0, 1)); + Vector128 tmpIndex = Vector128.Shuffle(resultIndex, Vector128.Create(2, 3, 0, 1)); + + Invoke(ref result, tmpResult, ref resultIndex, tmpIndex); + + tmpResult = Vector128.Shuffle(result, Vector128.Create(1, 0, 3, 2)); + tmpIndex = Vector128.Shuffle(resultIndex, Vector128.Create(1, 0, 3, 2)); + + Invoke(ref result, tmpResult, ref resultIndex, tmpIndex); + return resultIndex.ToScalar(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Invoke(ref Vector128 result, Vector128 current, ref Vector128 resultIndex, Vector128 curIndex) + { + Vector128 lessThanMask = Vector128.LessThan(result, current); + + Vector128 equalMask = Vector128.Equals(result, current); + if (equalMask.AsInt32() != Vector128.Zero) + { + Vector128 negativeMask = IsNegative(current); + Vector128 lessThanIndexMask = Vector128.LessThan(resultIndex, curIndex); + + lessThanMask |= (~negativeMask & equalMask) | (IsNegative(result) & equalMask & lessThanIndexMask.AsSingle()); + } + + result = ElementWiseSelect(lessThanMask, result, current); + + resultIndex = ElementWiseSelect(lessThanMask.AsInt32(), resultIndex, curIndex); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(Vector256 result, Vector256 resultIndex) + { + // Min the upper/lower halves of the Vector256 + Vector128 resultLower = result.GetLower(); + Vector128 indexLower = resultIndex.GetLower(); + + Invoke(ref resultLower, result.GetUpper(), ref indexLower, resultIndex.GetUpper()); + return Invoke(resultLower, indexLower); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Invoke(ref Vector256 result, Vector256 current, ref Vector256 resultIndex, Vector256 curIndex) + { + Vector256 lessThanMask = Vector256.LessThan(result, current); + + Vector256 equalMask = Vector256.Equals(result, current); + if (equalMask.AsInt32() != Vector256.Zero) + { + Vector256 negativeMask = IsNegative(current); + Vector256 lessThanIndexMask = Vector256.LessThan(resultIndex, curIndex); + + lessThanMask |= (~negativeMask & equalMask) | (IsNegative(result) & equalMask & lessThanIndexMask.AsSingle()); + } + + result = ElementWiseSelect(lessThanMask, result, current); + + resultIndex = ElementWiseSelect(lessThanMask.AsInt32(), resultIndex, curIndex); + } + +#if NET8_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(Vector512 result, Vector512 resultIndex) + { + // Min the upper/lower halves of the Vector512 + Vector256 resultLower = result.GetLower(); + Vector256 indexLower = resultIndex.GetLower(); + + Invoke(ref resultLower, result.GetUpper(), ref indexLower, resultIndex.GetUpper()); + return Invoke(resultLower, indexLower); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Invoke(ref Vector512 result, Vector512 current, ref Vector512 resultIndex, Vector512 curIndex) + { + Vector512 lessThanMask = Vector512.LessThan(result, current); + + Vector512 equalMask = Vector512.Equals(result, current); + if (equalMask.AsInt32() != Vector512.Zero) + { + Vector512 negativeMask = IsNegative(current); + Vector512 lessThanIndexMask = Vector512.LessThan(resultIndex, curIndex); + + lessThanMask |= (~negativeMask & equalMask) | (IsNegative(result) & equalMask & lessThanIndexMask.AsSingle()); + } + + result = ElementWiseSelect(lessThanMask, result, current); + + resultIndex = ElementWiseSelect(lessThanMask.AsInt32(), resultIndex, curIndex); + } +#endif + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(ref float result, float current, int resultIndex, int curIndex) + { + if (result == current) + { + if (IsPositive(result) && !IsPositive(current)) + { + result = current; + return curIndex; + } + } + else if (current < result) + { + result = current; + return curIndex; + } + + return resultIndex; + } + } + + private readonly struct IndexOfMinMagnitudeOperator : IIndexOfOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(Vector128 result, Vector128 resultIndex) + { + Vector128 tmpResult = Vector128.Shuffle(result, Vector128.Create(2, 3, 0, 1)); + Vector128 tmpIndex = Vector128.Shuffle(resultIndex, Vector128.Create(2, 3, 0, 1)); + + Invoke(ref result, tmpResult, ref resultIndex, tmpIndex); + + tmpResult = Vector128.Shuffle(result, Vector128.Create(1, 0, 3, 2)); + tmpIndex = Vector128.Shuffle(resultIndex, Vector128.Create(1, 0, 3, 2)); + + Invoke(ref result, tmpResult, ref resultIndex, tmpIndex); + return resultIndex.ToScalar(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Invoke(ref Vector128 result, Vector128 current, ref Vector128 resultIndex, Vector128 curIndex) + { + Vector128 minMag = Vector128.Abs(result), currentMag = Vector128.Abs(current); + + Vector128 lessThanMask = Vector128.LessThan(minMag, currentMag); + + Vector128 equalMask = Vector128.Equals(result, current); + if (equalMask.AsInt32() != Vector128.Zero) + { + Vector128 negativeMask = IsNegative(current); + Vector128 lessThanIndexMask = Vector128.LessThan(resultIndex, curIndex); + + lessThanMask |= (~negativeMask & equalMask) | (IsNegative(result) & equalMask & lessThanIndexMask.AsSingle()); + } + + result = ElementWiseSelect(lessThanMask, result, current); + + resultIndex = ElementWiseSelect(lessThanMask.AsInt32(), resultIndex, curIndex); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(Vector256 result, Vector256 resultIndex) + { + // Min the upper/lower halves of the Vector256 + Vector128 resultLower = result.GetLower(); + Vector128 indexLower = resultIndex.GetLower(); + + Invoke(ref resultLower, result.GetUpper(), ref indexLower, resultIndex.GetUpper()); + return Invoke(resultLower, indexLower); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Invoke(ref Vector256 result, Vector256 current, ref Vector256 resultIndex, Vector256 curIndex) + { + Vector256 minMag = Vector256.Abs(result), currentMag = Vector256.Abs(current); + + Vector256 lessThanMask = Vector256.LessThan(minMag, currentMag); + + Vector256 equalMask = Vector256.Equals(result, current); + if (equalMask.AsInt32() != Vector256.Zero) + { + Vector256 negativeMask = IsNegative(current); + Vector256 lessThanIndexMask = Vector256.LessThan(resultIndex, curIndex); + + lessThanMask |= (~negativeMask & equalMask) | (IsNegative(result) & equalMask & lessThanIndexMask.AsSingle()); + } + + result = ElementWiseSelect(lessThanMask, result, current); + + resultIndex = ElementWiseSelect(lessThanMask.AsInt32(), resultIndex, curIndex); + } + +#if NET8_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(Vector512 result, Vector512 resultIndex) + { + // Min the upper/lower halves of the Vector512 + Vector256 resultLower = result.GetLower(); + Vector256 indexLower = resultIndex.GetLower(); + + Invoke(ref resultLower, result.GetUpper(), ref indexLower, resultIndex.GetUpper()); + return Invoke(resultLower, indexLower); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Invoke(ref Vector512 result, Vector512 current, ref Vector512 resultIndex, Vector512 curIndex) + { + Vector512 minMag = Vector512.Abs(result), currentMag = Vector512.Abs(current); + + Vector512 lessThanMask = Vector512.LessThan(minMag, currentMag); + + Vector512 equalMask = Vector512.Equals(result, current); + if (equalMask.AsInt32() != Vector512.Zero) + { + Vector512 negativeMask = IsNegative(current); + Vector512 lessThanIndexMask = Vector512.LessThan(resultIndex, curIndex); + + lessThanMask |= (~negativeMask & equalMask) | (IsNegative(result) & equalMask & lessThanIndexMask.AsSingle()); + } + + result = ElementWiseSelect(lessThanMask, result, current); + + resultIndex = ElementWiseSelect(lessThanMask.AsInt32(), resultIndex, curIndex); + } +#endif + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Invoke(ref float result, float current, int resultIndex, int curIndex) + { + float curMinAbs = MathF.Abs(result); + float currentAbs = MathF.Abs(current); + if (curMinAbs == currentAbs) + { + if (IsPositive(result) && !IsPositive(current)) + { + result = current; + return curIndex; + } + } + else if (currentAbs < curMinAbs) + { + result = current; + return curIndex; + } + + return resultIndex; + } + } + + /// MathF.Max(x, y) + private readonly struct MaxPropagateNaNOperator : IBinaryOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Invoke(float x, float y) => MathF.Max(x, y); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 Invoke(Vector128 x, Vector128 y) + { + if (AdvSimd.IsSupported) + { + return AdvSimd.Max(x, y); + } + + return + Vector128.ConditionalSelect(Vector128.Equals(x, x), + Vector128.ConditionalSelect(Vector128.Equals(y, y), + Vector128.ConditionalSelect(Vector128.Equals(x, y), + Vector128.ConditionalSelect(IsNegative(x), y, x), + Vector128.Max(x, y)), + y), + x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 Invoke(Vector256 x, Vector256 y) => + Vector256.ConditionalSelect(Vector256.Equals(x, x), + Vector256.ConditionalSelect(Vector256.Equals(y, y), + Vector256.ConditionalSelect(Vector256.Equals(x, y), + Vector256.ConditionalSelect(IsNegative(x), y, x), + Vector256.Max(x, y)), + y), + x); + +#if NET8_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 Invoke(Vector512 x, Vector512 y) => + Vector512.ConditionalSelect(Vector512.Equals(x, x), + Vector512.ConditionalSelect(Vector512.Equals(y, y), + Vector512.ConditionalSelect(Vector512.Equals(x, y), + Vector512.ConditionalSelect(IsNegative(x), y, x), + Vector512.Max(x, y)), + y), + x); +#endif + } + + /// Operator to get x or y based on which has the larger MathF.Abs (but NaNs may not be propagated) + private readonly struct MaxMagnitudeOperator : IAggregationOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Invoke(float x, float y) + { + float xMag = MathF.Abs(x), yMag = MathF.Abs(y); + return + xMag == yMag ? + (IsNegative(x) ? y : x) : + (xMag > yMag ? x : y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 Invoke(Vector128 x, Vector128 y) + { + Vector128 xMag = Vector128.Abs(x), yMag = Vector128.Abs(y); + return + Vector128.ConditionalSelect(Vector128.Equals(xMag, yMag), + Vector128.ConditionalSelect(IsNegative(x), y, x), + Vector128.ConditionalSelect(Vector128.GreaterThan(xMag, yMag), x, y)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 Invoke(Vector256 x, Vector256 y) + { + Vector256 xMag = Vector256.Abs(x), yMag = Vector256.Abs(y); + return + Vector256.ConditionalSelect(Vector256.Equals(xMag, yMag), + Vector256.ConditionalSelect(IsNegative(x), y, x), + Vector256.ConditionalSelect(Vector256.GreaterThan(xMag, yMag), x, y)); + } + +#if NET8_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 Invoke(Vector512 x, Vector512 y) + { + Vector512 xMag = Vector512.Abs(x), yMag = Vector512.Abs(y); + return + Vector512.ConditionalSelect(Vector512.Equals(xMag, yMag), + Vector512.ConditionalSelect(IsNegative(x), y, x), + Vector512.ConditionalSelect(Vector512.GreaterThan(xMag, yMag), x, y)); + } +#endif + + public static float Invoke(Vector128 x) => HorizontalAggregate(x); + public static float Invoke(Vector256 x) => HorizontalAggregate(x); +#if NET8_0_OR_GREATER + public static float Invoke(Vector512 x) => HorizontalAggregate(x); +#endif + } + + /// Operator to get x or y based on which has the larger MathF.Abs + private readonly struct MaxMagnitudePropagateNaNOperator : IBinaryOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Invoke(float x, float y) => MathF.MaxMagnitude(x, y); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 Invoke(Vector128 x, Vector128 y) + { + Vector128 xMag = Vector128.Abs(x), yMag = Vector128.Abs(y); + return + Vector128.ConditionalSelect(Vector128.Equals(x, x), + Vector128.ConditionalSelect(Vector128.Equals(y, y), + Vector128.ConditionalSelect(Vector128.Equals(yMag, xMag), + Vector128.ConditionalSelect(IsNegative(x), y, x), + Vector128.ConditionalSelect(Vector128.GreaterThan(yMag, xMag), y, x)), + y), + x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 Invoke(Vector256 x, Vector256 y) + { + Vector256 xMag = Vector256.Abs(x), yMag = Vector256.Abs(y); + return + Vector256.ConditionalSelect(Vector256.Equals(x, x), + Vector256.ConditionalSelect(Vector256.Equals(y, y), + Vector256.ConditionalSelect(Vector256.Equals(xMag, yMag), + Vector256.ConditionalSelect(IsNegative(x), y, x), + Vector256.ConditionalSelect(Vector256.GreaterThan(xMag, yMag), x, y)), + y), + x); + } + +#if NET8_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 Invoke(Vector512 x, Vector512 y) + { + Vector512 xMag = Vector512.Abs(x), yMag = Vector512.Abs(y); + return + Vector512.ConditionalSelect(Vector512.Equals(x, x), + Vector512.ConditionalSelect(Vector512.Equals(y, y), + Vector512.ConditionalSelect(Vector512.Equals(xMag, yMag), + Vector512.ConditionalSelect(IsNegative(x), y, x), + Vector512.ConditionalSelect(Vector512.GreaterThan(xMag, yMag), x, y)), + y), + x); + } +#endif + } + + /// MathF.Min(x, y) (but NaNs may not be propagated) + private readonly struct MinOperator : IAggregationOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Invoke(float x, float y) => + x == y ? + (IsNegative(y) ? y : x) : + (y < x ? y : x); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 Invoke(Vector128 x, Vector128 y) + { + if (AdvSimd.IsSupported) + { + return AdvSimd.Min(x, y); + } + + return + Vector128.ConditionalSelect(Vector128.Equals(x, y), + Vector128.ConditionalSelect(IsNegative(y), y, x), + Vector128.Min(x, y)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 Invoke(Vector256 x, Vector256 y) => + Vector256.ConditionalSelect(Vector256.Equals(x, y), + Vector256.ConditionalSelect(IsNegative(y), y, x), + Vector256.Min(x, y)); + +#if NET8_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 Invoke(Vector512 x, Vector512 y) => + Vector512.ConditionalSelect(Vector512.Equals(x, y), + Vector512.ConditionalSelect(IsNegative(y), y, x), + Vector512.Min(x, y)); +#endif + + public static float Invoke(Vector128 x) => HorizontalAggregate(x); + public static float Invoke(Vector256 x) => HorizontalAggregate(x); +#if NET8_0_OR_GREATER + public static float Invoke(Vector512 x) => HorizontalAggregate(x); +#endif + } + + /// MathF.Min(x, y) + private readonly struct MinPropagateNaNOperator : IBinaryOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Invoke(float x, float y) => MathF.Min(x, y); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 Invoke(Vector128 x, Vector128 y) + { + if (AdvSimd.IsSupported) + { + return AdvSimd.Min(x, y); + } + + return + Vector128.ConditionalSelect(Vector128.Equals(x, x), + Vector128.ConditionalSelect(Vector128.Equals(y, y), + Vector128.ConditionalSelect(Vector128.Equals(x, y), + Vector128.ConditionalSelect(IsNegative(x), x, y), + Vector128.Min(x, y)), + y), + x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 Invoke(Vector256 x, Vector256 y) => + Vector256.ConditionalSelect(Vector256.Equals(x, x), + Vector256.ConditionalSelect(Vector256.Equals(y, y), + Vector256.ConditionalSelect(Vector256.Equals(x, y), + Vector256.ConditionalSelect(IsNegative(x), x, y), + Vector256.Min(x, y)), + y), + x); + +#if NET8_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 Invoke(Vector512 x, Vector512 y) => + Vector512.ConditionalSelect(Vector512.Equals(x, x), + Vector512.ConditionalSelect(Vector512.Equals(y, y), + Vector512.ConditionalSelect(Vector512.Equals(x, y), + Vector512.ConditionalSelect(IsNegative(x), x, y), + Vector512.Min(x, y)), + y), + x); +#endif + } + + /// Operator to get x or y based on which has the smaller MathF.Abs (but NaNs may not be propagated) + private readonly struct MinMagnitudeOperator : IAggregationOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Invoke(float x, float y) + { + float xMag = MathF.Abs(x), yMag = MathF.Abs(y); + return xMag == yMag ? + (IsNegative(y) ? y : x) : + (yMag < xMag ? y : x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 Invoke(Vector128 x, Vector128 y) + { + Vector128 xMag = Vector128.Abs(x), yMag = Vector128.Abs(y); + return + Vector128.ConditionalSelect(Vector128.Equals(yMag, xMag), + Vector128.ConditionalSelect(IsNegative(y), y, x), + Vector128.ConditionalSelect(Vector128.LessThan(yMag, xMag), y, x)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 Invoke(Vector256 x, Vector256 y) + { + Vector256 xMag = Vector256.Abs(x), yMag = Vector256.Abs(y); + return + Vector256.ConditionalSelect(Vector256.Equals(yMag, xMag), + Vector256.ConditionalSelect(IsNegative(y), y, x), + Vector256.ConditionalSelect(Vector256.LessThan(yMag, xMag), y, x)); + } + +#if NET8_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 Invoke(Vector512 x, Vector512 y) + { + Vector512 xMag = Vector512.Abs(x), yMag = Vector512.Abs(y); + return + Vector512.ConditionalSelect(Vector512.Equals(yMag, xMag), + Vector512.ConditionalSelect(IsNegative(y), y, x), + Vector512.ConditionalSelect(Vector512.LessThan(yMag, xMag), y, x)); + } +#endif + + public static float Invoke(Vector128 x) => HorizontalAggregate(x); + public static float Invoke(Vector256 x) => HorizontalAggregate(x); +#if NET8_0_OR_GREATER + public static float Invoke(Vector512 x) => HorizontalAggregate(x); +#endif + } + + /// Operator to get x or y based on which has the smaller MathF.Abs + private readonly struct MinMagnitudePropagateNaNOperator : IBinaryOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Invoke(float x, float y) => MathF.MinMagnitude(x, y); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 Invoke(Vector128 x, Vector128 y) + { + Vector128 xMag = Vector128.Abs(x), yMag = Vector128.Abs(y); + return + Vector128.ConditionalSelect(Vector128.Equals(x, x), + Vector128.ConditionalSelect(Vector128.Equals(y, y), + Vector128.ConditionalSelect(Vector128.Equals(yMag, xMag), + Vector128.ConditionalSelect(IsNegative(x), x, y), + Vector128.ConditionalSelect(Vector128.LessThan(xMag, yMag), x, y)), + y), + x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 Invoke(Vector256 x, Vector256 y) + { + Vector256 xMag = Vector256.Abs(x), yMag = Vector256.Abs(y); + return + Vector256.ConditionalSelect(Vector256.Equals(x, x), + Vector256.ConditionalSelect(Vector256.Equals(y, y), + Vector256.ConditionalSelect(Vector256.Equals(yMag, xMag), + Vector256.ConditionalSelect(IsNegative(x), x, y), + Vector256.ConditionalSelect(Vector256.LessThan(xMag, yMag), x, y)), + y), + x); + } + +#if NET8_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 Invoke(Vector512 x, Vector512 y) + { + Vector512 xMag = Vector512.Abs(x), yMag = Vector512.Abs(y); + return + Vector512.ConditionalSelect(Vector512.Equals(x, x), + Vector512.ConditionalSelect(Vector512.Equals(y, y), + Vector512.ConditionalSelect(Vector512.Equals(yMag, xMag), + Vector512.ConditionalSelect(IsNegative(x), x, y), + Vector512.ConditionalSelect(Vector512.LessThan(xMag, yMag), x, y)), + y), + x); + } +#endif + } + + /// -x + private readonly struct NegateOperator : IUnaryOperator + { + public static float Invoke(float x) => -x; + public static Vector128 Invoke(Vector128 x) => -x; + public static Vector256 Invoke(Vector256 x) => -x; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x) => -x; +#endif + } + + /// (x + y) * z + private readonly struct AddMultiplyOperator : ITernaryOperator + { + public static float Invoke(float x, float y, float z) => (x + y) * z; + public static Vector128 Invoke(Vector128 x, Vector128 y, Vector128 z) => (x + y) * z; + public static Vector256 Invoke(Vector256 x, Vector256 y, Vector256 z) => (x + y) * z; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x, Vector512 y, Vector512 z) => (x + y) * z; +#endif + } + + /// (x * y) + z + private readonly struct MultiplyAddOperator : ITernaryOperator + { + public static float Invoke(float x, float y, float z) => (x * y) + z; + public static Vector128 Invoke(Vector128 x, Vector128 y, Vector128 z) => (x * y) + z; + public static Vector256 Invoke(Vector256 x, Vector256 y, Vector256 z) => (x * y) + z; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x, Vector512 y, Vector512 z) => (x * y) + z; +#endif + } + + /// x + private readonly struct IdentityOperator : IUnaryOperator + { + public static float Invoke(float x) => x; + public static Vector128 Invoke(Vector128 x) => x; + public static Vector256 Invoke(Vector256 x) => x; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x) => x; +#endif + } + + /// x * x + private readonly struct SquaredOperator : IUnaryOperator + { + public static float Invoke(float x) => x * x; + public static Vector128 Invoke(Vector128 x) => x * x; + public static Vector256 Invoke(Vector256 x) => x * x; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x) => x * x; +#endif + } + + /// MathF.Abs(x) + private readonly struct AbsoluteOperator : IUnaryOperator + { + public static float Invoke(float x) => MathF.Abs(x); + public static Vector128 Invoke(Vector128 x) => Vector128.Abs(x); + public static Vector256 Invoke(Vector256 x) => Vector256.Abs(x); +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x) => Vector512.Abs(x); +#endif + } + + /// MathF.Exp(x) + private readonly struct ExpOperator : IUnaryOperator + { + // This code is based on `vrs4_expf` from amd/aocl-libm-ose + // Copyright (C) 2019-2022 Advanced Micro Devices, Inc. All rights reserved. + // + // Licensed under the BSD 3-Clause "New" or "Revised" License + // See THIRD-PARTY-NOTICES.TXT for the full license text + + // Implementation Notes: + // 1. Argument Reduction: + // e^x = 2^(x/ln2) --- (1) + // + // Let x/ln(2) = z --- (2) + // + // Let z = n + r , where n is an integer --- (3) + // |r| <= 1/2 + // + // From (1), (2) and (3), + // e^x = 2^z + // = 2^(N+r) + // = (2^N)*(2^r) --- (4) + // + // 2. Polynomial Evaluation + // From (4), + // r = z - N + // 2^r = C1 + C2*r + C3*r^2 + C4*r^3 + C5 *r^4 + C6*r^5 + // + // 4. Reconstruction + // Thus, + // e^x = (2^N) * (2^r) + + private const uint V_ARG_MAX = 0x42AE0000; + private const uint V_MASK = 0x7FFFFFFF; + + private const float V_EXPF_MIN = -103.97208f; + private const float V_EXPF_MAX = 88.72284f; + + private const double V_EXPF_HUGE = 6755399441055744; + private const double V_TBL_LN2 = 1.4426950408889634; + + private const double C1 = 1.0000000754895704; + private const double C2 = 0.6931472254087585; + private const double C3 = 0.2402210737432219; + private const double C4 = 0.05550297297702539; + private const double C5 = 0.009676036358193323; + private const double C6 = 0.001341000536524434; + + public static float Invoke(float x) => MathF.Exp(x); + + public static Vector128 Invoke(Vector128 x) + { + // Convert x to double precision + (Vector128 xl, Vector128 xu) = Vector128.Widen(x); + + // x * (64.0 / ln(2)) + Vector128 v_tbl_ln2 = Vector128.Create(V_TBL_LN2); + + Vector128 zl = xl * v_tbl_ln2; + Vector128 zu = xu * v_tbl_ln2; + + Vector128 v_expf_huge = Vector128.Create(V_EXPF_HUGE); + + Vector128 dnl = zl + v_expf_huge; + Vector128 dnu = zu + v_expf_huge; + + // n = int (z) + Vector128 nl = dnl.AsUInt64(); + Vector128 nu = dnu.AsUInt64(); + + // dn = double(n) + dnl -= v_expf_huge; + dnu -= v_expf_huge; + + // r = z - dn + Vector128 c1 = Vector128.Create(C1); + Vector128 c2 = Vector128.Create(C2); + Vector128 c3 = Vector128.Create(C3); + Vector128 c4 = Vector128.Create(C4); + Vector128 c5 = Vector128.Create(C5); + Vector128 c6 = Vector128.Create(C6); + + Vector128 rl = zl - dnl; + + Vector128 rl2 = rl * rl; + Vector128 rl4 = rl2 * rl2; + + Vector128 polyl = (c4 * rl + c3) * rl2 + + ((c6 * rl + c5) * rl4 + + (c2 * rl + c1)); + + + Vector128 ru = zu - dnu; + + Vector128 ru2 = ru * ru; + Vector128 ru4 = ru2 * ru2; + + Vector128 polyu = (c4 * ru + c3) * ru2 + + ((c6 * ru + c5) * ru4 + + (c2 * ru + c1)); + + // result = (float)[poly + (n << 52)] + Vector128 ret = Vector128.Narrow( + (polyl.AsUInt64() + Vector128.ShiftLeft(nl, 52)).AsDouble(), + (polyu.AsUInt64() + Vector128.ShiftLeft(nu, 52)).AsDouble() + ); + + // Check if -103 < |x| < 88 + if (Vector128.GreaterThanAny(x.AsUInt32() & Vector128.Create(V_MASK), Vector128.Create(V_ARG_MAX))) + { + // (x > V_EXPF_MAX) ? float.PositiveInfinity : x + Vector128 infinityMask = Vector128.GreaterThan(x, Vector128.Create(V_EXPF_MAX)); + + ret = Vector128.ConditionalSelect( + infinityMask, + Vector128.Create(float.PositiveInfinity), + ret + ); + + // (x < V_EXPF_MIN) ? 0 : x + ret = Vector128.AndNot(ret, Vector128.LessThan(x, Vector128.Create(V_EXPF_MIN))); + } + + return ret; + } + + public static Vector256 Invoke(Vector256 x) + { + // Convert x to double precision + (Vector256 xl, Vector256 xu) = Vector256.Widen(x); + + // x * (64.0 / ln(2)) + Vector256 v_tbl_ln2 = Vector256.Create(V_TBL_LN2); + + Vector256 zl = xl * v_tbl_ln2; + Vector256 zu = xu * v_tbl_ln2; + + Vector256 v_expf_huge = Vector256.Create(V_EXPF_HUGE); + + Vector256 dnl = zl + v_expf_huge; + Vector256 dnu = zu + v_expf_huge; + + // n = int (z) + Vector256 nl = dnl.AsUInt64(); + Vector256 nu = dnu.AsUInt64(); + + // dn = double(n) + dnl -= v_expf_huge; + dnu -= v_expf_huge; + + // r = z - dn + Vector256 c1 = Vector256.Create(C1); + Vector256 c2 = Vector256.Create(C2); + Vector256 c3 = Vector256.Create(C3); + Vector256 c4 = Vector256.Create(C4); + Vector256 c5 = Vector256.Create(C5); + Vector256 c6 = Vector256.Create(C6); + + Vector256 rl = zl - dnl; + + Vector256 rl2 = rl * rl; + Vector256 rl4 = rl2 * rl2; + + Vector256 polyl = (c4 * rl + c3) * rl2 + + ((c6 * rl + c5) * rl4 + + (c2 * rl + c1)); + + + Vector256 ru = zu - dnu; + + Vector256 ru2 = ru * ru; + Vector256 ru4 = ru2 * ru2; + + Vector256 polyu = (c4 * ru + c3) * ru2 + + ((c6 * ru + c5) * ru4 + + (c2 * ru + c1)); + + // result = (float)[poly + (n << 52)] + Vector256 ret = Vector256.Narrow( + (polyl.AsUInt64() + Vector256.ShiftLeft(nl, 52)).AsDouble(), + (polyu.AsUInt64() + Vector256.ShiftLeft(nu, 52)).AsDouble() + ); + + // Check if -103 < |x| < 88 + if (Vector256.GreaterThanAny(x.AsUInt32() & Vector256.Create(V_MASK), Vector256.Create(V_ARG_MAX))) + { + // (x > V_EXPF_MAX) ? float.PositiveInfinity : x + Vector256 infinityMask = Vector256.GreaterThan(x, Vector256.Create(V_EXPF_MAX)); + + ret = Vector256.ConditionalSelect( + infinityMask, + Vector256.Create(float.PositiveInfinity), + ret + ); + + // (x < V_EXPF_MIN) ? 0 : x + ret = Vector256.AndNot(ret, Vector256.LessThan(x, Vector256.Create(V_EXPF_MIN))); + } + + return ret; + } + +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x) + { + // Convert x to double precision + (Vector512 xl, Vector512 xu) = Vector512.Widen(x); + + // x * (64.0 / ln(2)) + Vector512 v_tbl_ln2 = Vector512.Create(V_TBL_LN2); + + Vector512 zl = xl * v_tbl_ln2; + Vector512 zu = xu * v_tbl_ln2; + + Vector512 v_expf_huge = Vector512.Create(V_EXPF_HUGE); + + Vector512 dnl = zl + v_expf_huge; + Vector512 dnu = zu + v_expf_huge; + + // n = int (z) + Vector512 nl = dnl.AsUInt64(); + Vector512 nu = dnu.AsUInt64(); + + // dn = double(n) + dnl -= v_expf_huge; + dnu -= v_expf_huge; + + // r = z - dn + Vector512 c1 = Vector512.Create(C1); + Vector512 c2 = Vector512.Create(C2); + Vector512 c3 = Vector512.Create(C3); + Vector512 c4 = Vector512.Create(C4); + Vector512 c5 = Vector512.Create(C5); + Vector512 c6 = Vector512.Create(C6); + + Vector512 rl = zl - dnl; + + Vector512 rl2 = rl * rl; + Vector512 rl4 = rl2 * rl2; + + Vector512 polyl = (c4 * rl + c3) * rl2 + + ((c6 * rl + c5) * rl4 + + (c2 * rl + c1)); + + + Vector512 ru = zu - dnu; + + Vector512 ru2 = ru * ru; + Vector512 ru4 = ru2 * ru2; + + Vector512 polyu = (c4 * ru + c3) * ru2 + + ((c6 * ru + c5) * ru4 + + (c2 * ru + c1)); + + // result = (float)[poly + (n << 52)] + Vector512 ret = Vector512.Narrow( + (polyl.AsUInt64() + Vector512.ShiftLeft(nl, 52)).AsDouble(), + (polyu.AsUInt64() + Vector512.ShiftLeft(nu, 52)).AsDouble() + ); + + // Check if -103 < |x| < 88 + if (Vector512.GreaterThanAny(x.AsUInt32() & Vector512.Create(V_MASK), Vector512.Create(V_ARG_MAX))) + { + // (x > V_EXPF_MAX) ? float.PositiveInfinity : x + Vector512 infinityMask = Vector512.GreaterThan(x, Vector512.Create(V_EXPF_MAX)); + + ret = Vector512.ConditionalSelect( + infinityMask, + Vector512.Create(float.PositiveInfinity), + ret + ); + + // (x < V_EXPF_MIN) ? 0 : x + ret = Vector512.AndNot(ret, Vector512.LessThan(x, Vector512.Create(V_EXPF_MIN))); + } + + return ret; + } +#endif + } + + /// MathF.Cosh(x) + private readonly struct CoshOperator : IUnaryOperator + { + // This code is based on `vrs4_coshf` from amd/aocl-libm-ose + // Copyright (C) 2008-2022 Advanced Micro Devices, Inc. All rights reserved. + // + // Licensed under the BSD 3-Clause "New" or "Revised" License + // See THIRD-PARTY-NOTICES.TXT for the full license text + + // Spec: + // coshf(|x| > 89.415985107421875) = Infinity + // coshf(Infinity) = infinity + // coshf(-Infinity) = infinity + // + // cosh(x) = (exp(x) + exp(-x))/2 + // cosh(-x) = +cosh(x) + // + // checks for special cases + // if ( asint(x) > infinity) return x with overflow exception and + // return x. + // if x is NaN then raise invalid FP operation exception and return x. + // + // coshf = v/2 * exp(x - log(v)) where v = 0x1.0000e8p-1 + + private const float LOGV = 0.693161f; + private const float HALFV = 1.0000138f; + private const float INVV2 = 0.24999309f; + + public static float Invoke(float x) => MathF.Cosh(x); + + public static Vector128 Invoke(Vector128 x) + { + Vector128 y = Vector128.Abs(x); + Vector128 z = ExpOperator.Invoke(y - Vector128.Create(LOGV)); + return Vector128.Create(HALFV) * (z + (Vector128.Create(INVV2) / z)); + } + + public static Vector256 Invoke(Vector256 x) + { + Vector256 y = Vector256.Abs(x); + Vector256 z = ExpOperator.Invoke(y - Vector256.Create(LOGV)); + return Vector256.Create(HALFV) * (z + (Vector256.Create(INVV2) / z)); } - if (Vector128.IsHardwareAccelerated) +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x) { - oneVectorFromEnd = x.Length - Vector128.Count; - if (i <= oneVectorFromEnd) - { - Vector128 zVec = Vector128.Create(z); + Vector512 y = Vector512.Abs(x); + Vector512 z = ExpOperator.Invoke(y - Vector512.Create(LOGV)); + return Vector512.Create(HALFV) * (z + (Vector512.Create(INVV2) / z)); + } +#endif + } - // Loop handling one vector at a time. - do - { - TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i), - Vector128.LoadUnsafe(ref yRef, (uint)i), - zVec).StoreUnsafe(ref dRef, (uint)i); + /// MathF.Sinh(x) + private readonly struct SinhOperator : IUnaryOperator + { + // Same as cosh, but with `z -` rather than `z +`, and with the sign + // flipped on the result based on the sign of the input. - i += Vector128.Count; - } - while (i <= oneVectorFromEnd); + private const uint SIGN_MASK = 0x7FFFFFFF; + private const float LOGV = 0.693161f; + private const float HALFV = 1.0000138f; + private const float INVV2 = 0.24999309f; - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector128.Count); - TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, lastVectorIndex), - Vector128.LoadUnsafe(ref yRef, lastVectorIndex), - zVec).StoreUnsafe(ref dRef, lastVectorIndex); - } + public static float Invoke(float x) => MathF.Sinh(x); - return; - } + public static Vector128 Invoke(Vector128 x) + { + Vector128 y = Vector128.Abs(x); + Vector128 z = ExpOperator.Invoke(y - Vector128.Create(LOGV)); + Vector128 result = Vector128.Create(HALFV) * (z - (Vector128.Create(INVV2) / z)); + Vector128 sign = x.AsUInt32() & Vector128.Create(~SIGN_MASK); + return (sign ^ result.AsUInt32()).AsSingle(); } - while (i < x.Length) + public static Vector256 Invoke(Vector256 x) { - Unsafe.Add(ref dRef, i) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, i), - Unsafe.Add(ref yRef, i), - z); + Vector256 y = Vector256.Abs(x); + Vector256 z = ExpOperator.Invoke(y - Vector256.Create(LOGV)); + Vector256 result = Vector256.Create(HALFV) * (z - (Vector256.Create(INVV2) / z)); + Vector256 sign = x.AsUInt32() & Vector256.Create(~SIGN_MASK); + return (sign ^ result.AsUInt32()).AsSingle(); + } - i++; +#if NET8_0_OR_GREATER + public static Vector512 Invoke(Vector512 x) + { + Vector512 y = Vector512.Abs(x); + Vector512 z = ExpOperator.Invoke(y - Vector512.Create(LOGV)); + Vector512 result = Vector512.Create(HALFV) * (z - (Vector512.Create(INVV2) / z)); + Vector512 sign = x.AsUInt32() & Vector512.Create(~SIGN_MASK); + return (sign ^ result.AsUInt32()).AsSingle(); } +#endif } - private static unsafe void InvokeSpanScalarSpanIntoSpan( - ReadOnlySpan x, float y, ReadOnlySpan z, Span destination) - where TTernaryOperator : ITernaryOperator + /// MathF.Tanh(x) + private readonly struct TanhOperator : IUnaryOperator { - if (x.Length != z.Length) + // This code is based on `vrs4_tanhf` from amd/aocl-libm-ose + // Copyright (C) 2008-2022 Advanced Micro Devices, Inc. All rights reserved. + // + // Licensed under the BSD 3-Clause "New" or "Revised" License + // See THIRD-PARTY-NOTICES.TXT for the full license text + + // To compute vrs4_tanhf(v_f32x4_t x) + // Let y = |x| + // If 0 <= y < 0x1.154246p3 + // Let z = e^(-2.0 * y) - 1 -(1) + // + // Using (1), tanhf(y) can be calculated as, + // tanhf(y) = -z / (z + 2.0) + // + // For other cases, call scalar tanhf() + // + // If x < 0, then we use the identity + // tanhf(-x) = -tanhf(x) + + private const uint SIGN_MASK = 0x7FFFFFFF; + + public static float Invoke(float x) => MathF.Tanh(x); + + public static Vector128 Invoke(Vector128 x) { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + Vector128 y = Vector128.Abs(x); + Vector128 z = ExpOperator.Invoke(Vector128.Create(-2f) * y) - Vector128.Create(1f); + Vector128 sign = x.AsUInt32() & Vector128.Create(~SIGN_MASK); + return (sign ^ (-z / (z + Vector128.Create(2f))).AsUInt32()).AsSingle(); } - if (x.Length > destination.Length) + public static Vector256 Invoke(Vector256 x) { - ThrowHelper.ThrowArgument_DestinationTooShort(); + Vector256 y = Vector256.Abs(x); + Vector256 z = ExpOperator.Invoke(Vector256.Create(-2f) * y) - Vector256.Create(1f); + Vector256 sign = x.AsUInt32() & Vector256.Create(~SIGN_MASK); + return (sign ^ (-z / (z + Vector256.Create(2f))).AsUInt32()).AsSingle(); } - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float zRef = ref MemoryMarshal.GetReference(z); - ref float dRef = ref MemoryMarshal.GetReference(destination); - int i = 0, oneVectorFromEnd; - #if NET8_0_OR_GREATER - if (Vector512.IsHardwareAccelerated) + public static Vector512 Invoke(Vector512 x) { - oneVectorFromEnd = x.Length - Vector512.Count; - if (i <= oneVectorFromEnd) - { - Vector512 yVec = Vector512.Create(y); + Vector512 y = Vector512.Abs(x); + Vector512 z = ExpOperator.Invoke(Vector512.Create(-2f) * y) - Vector512.Create(1f); + Vector512 sign = x.AsUInt32() & Vector512.Create(~SIGN_MASK); + return (sign ^ (-z / (z + Vector512.Create(2f))).AsUInt32()).AsSingle(); + } +#endif + } - // Loop handling one vector at a time. - do - { - TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, (uint)i), - yVec, - Vector512.LoadUnsafe(ref zRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + /// MathF.Log(x) + private readonly struct LogOperator : IUnaryOperator + { + // This code is based on `vrs4_logf` from amd/aocl-libm-ose + // Copyright (C) 2018-2019 Advanced Micro Devices, Inc. All rights reserved. + // + // Licensed under the BSD 3-Clause "New" or "Revised" License + // See THIRD-PARTY-NOTICES.TXT for the full license text + + // Spec: + // logf(x) + // = logf(x) if x ∈ F and x > 0 + // = x if x = qNaN + // = 0 if x = 1 + // = -inf if x = (-0, 0} + // = NaN otherwise + // + // Assumptions/Expectations + // - ULP is derived to be << 4 (always) + // - Some FPU Exceptions may not be available + // - Performance is at least 3x + // + // Implementation Notes: + // 1. Range Reduction: + // x = 2^n*(1+f) .... (1) + // where n is exponent and is an integer + // (1+f) is mantissa ∈ [1,2). i.e., 1 ≤ 1+f < 2 .... (2) + // + // From (1), taking log on both sides + // log(x) = log(2^n * (1+f)) + // = log(2^n) + log(1+f) + // = n*log(2) + log(1+f) .... (3) + // + // let z = 1 + f + // log(z) = log(k) + log(z) - log(k) + // log(z) = log(kz) - log(k) + // + // From (2), range of z is [1, 2) + // by simply dividing range by 'k', z is in [1/k, 2/k) .... (4) + // Best choice of k is the one which gives equal and opposite values + // at extrema +- -+ + // 1 | 2 | + // --- - 1 = - |--- - 1 | + // k | k | .... (5) + // +- -+ + // + // Solving for k, k = 3/2, + // From (4), using 'k' value, range is therefore [-0.3333, 0.3333] + // + // 2. Polynomial Approximation: + // More information refer to tools/sollya/vrs4_logf.sollya + // + // 7th Deg - Error abs: 0x1.04c4ac98p-22 rel: 0x1.2216e6f8p-19 + // 6th Deg - Error abs: 0x1.179e97d8p-19 rel: 0x1.db676c1p-17 + + private const uint V_MIN = 0x00800000; + private const uint V_MAX = 0x7F800000; + private const uint V_MASK = 0x007FFFFF; + private const uint V_OFF = 0x3F2AAAAB; + + private const float V_LN2 = 0.6931472f; + + private const float C0 = 0.0f; + private const float C1 = 1.0f; + private const float C2 = -0.5000001f; + private const float C3 = 0.33332965f; + private const float C4 = -0.24999046f; + private const float C5 = 0.20018855f; + private const float C6 = -0.16700386f; + private const float C7 = 0.13902695f; + private const float C8 = -0.1197452f; + private const float C9 = 0.14401625f; + private const float C10 = -0.13657966f; + + public static float Invoke(float x) => MathF.Log(x); - i += Vector512.Count; - } - while (i <= oneVectorFromEnd); + public static Vector128 Invoke(Vector128 x) + { + Vector128 specialResult = x; - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector512.Count); - TTernaryOperator.Invoke(Vector512.LoadUnsafe(ref xRef, lastVectorIndex), - yVec, - Vector512.LoadUnsafe(ref zRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); - } + // x is subnormal or infinity or NaN + Vector128 specialMask = Vector128.GreaterThanOrEqual(x.AsUInt32() - Vector128.Create(V_MIN), Vector128.Create(V_MAX - V_MIN)); - return; + if (specialMask != Vector128.Zero) + { + // float.IsZero(x) ? float.NegativeInfinity : x + Vector128 zeroMask = Vector128.Equals(x, Vector128.Zero); + + specialResult = Vector128.ConditionalSelect( + zeroMask, + Vector128.Create(float.NegativeInfinity), + specialResult + ); + + // (x < 0) ? float.NaN : x + Vector128 lessThanZeroMask = Vector128.LessThan(x, Vector128.Zero); + + specialResult = Vector128.ConditionalSelect( + lessThanZeroMask, + Vector128.Create(float.NaN), + specialResult + ); + + // float.IsZero(x) | (x < 0) | float.IsNaN(x) | float.IsPositiveInfinity(x) + Vector128 temp = zeroMask + | lessThanZeroMask + | ~Vector128.Equals(x, x) + | Vector128.Equals(x, Vector128.Create(float.PositiveInfinity)); + + // subnormal + Vector128 subnormalMask = Vector128.AndNot(specialMask.AsSingle(), temp); + + x = Vector128.ConditionalSelect( + subnormalMask, + ((x * 8388608.0f).AsUInt32() - Vector128.Create(23u << 23)).AsSingle(), + x + ); + + specialMask = temp.AsUInt32(); } - } -#endif - if (Vector256.IsHardwareAccelerated) - { - oneVectorFromEnd = x.Length - Vector256.Count; - if (i <= oneVectorFromEnd) - { - Vector256 yVec = Vector256.Create(y); + Vector128 vx = x.AsUInt32() - Vector128.Create(V_OFF); + Vector128 n = Vector128.ConvertToSingle(Vector128.ShiftRightArithmetic(vx.AsInt32(), 23)); - // Loop handling one vector at a time. - do - { - TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, (uint)i), - yVec, - Vector256.LoadUnsafe(ref zRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + vx = (vx & Vector128.Create(V_MASK)) + Vector128.Create(V_OFF); - i += Vector256.Count; - } - while (i <= oneVectorFromEnd); + Vector128 r = vx.AsSingle() - Vector128.Create(1.0f); - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector256.Count); - TTernaryOperator.Invoke(Vector256.LoadUnsafe(ref xRef, lastVectorIndex), - yVec, - Vector256.LoadUnsafe(ref zRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); - } + Vector128 r2 = r * r; + Vector128 r4 = r2 * r2; + Vector128 r8 = r4 * r4; - return; - } + Vector128 q = (Vector128.Create(C10) * r2 + (Vector128.Create(C9) * r + Vector128.Create(C8))) + * r8 + (((Vector128.Create(C7) * r + Vector128.Create(C6)) + * r2 + (Vector128.Create(C5) * r + Vector128.Create(C4))) + * r4 + ((Vector128.Create(C3) * r + Vector128.Create(C2)) + * r2 + (Vector128.Create(C1) * r + Vector128.Create(C0)))); + + return Vector128.ConditionalSelect( + specialMask.AsSingle(), + specialResult, + n * Vector128.Create(V_LN2) + q + ); } - if (Vector128.IsHardwareAccelerated) + public static Vector256 Invoke(Vector256 x) { - oneVectorFromEnd = x.Length - Vector128.Count; - if (i <= oneVectorFromEnd) + Vector256 specialResult = x; + + // x is subnormal or infinity or NaN + Vector256 specialMask = Vector256.GreaterThanOrEqual(x.AsUInt32() - Vector256.Create(V_MIN), Vector256.Create(V_MAX - V_MIN)); + + if (specialMask != Vector256.Zero) { - Vector128 yVec = Vector128.Create(y); + // float.IsZero(x) ? float.NegativeInfinity : x + Vector256 zeroMask = Vector256.Equals(x, Vector256.Zero); + + specialResult = Vector256.ConditionalSelect( + zeroMask, + Vector256.Create(float.NegativeInfinity), + specialResult + ); + + // (x < 0) ? float.NaN : x + Vector256 lessThanZeroMask = Vector256.LessThan(x, Vector256.Zero); + + specialResult = Vector256.ConditionalSelect( + lessThanZeroMask, + Vector256.Create(float.NaN), + specialResult + ); + + // float.IsZero(x) | (x < 0) | float.IsNaN(x) | float.IsPositiveInfinity(x) + Vector256 temp = zeroMask + | lessThanZeroMask + | ~Vector256.Equals(x, x) + | Vector256.Equals(x, Vector256.Create(float.PositiveInfinity)); + + // subnormal + Vector256 subnormalMask = Vector256.AndNot(specialMask.AsSingle(), temp); + + x = Vector256.ConditionalSelect( + subnormalMask, + ((x * 8388608.0f).AsUInt32() - Vector256.Create(23u << 23)).AsSingle(), + x + ); + + specialMask = temp.AsUInt32(); + } - // Loop handling one vector at a time. - do - { - TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, (uint)i), - yVec, - Vector128.LoadUnsafe(ref zRef, (uint)i)).StoreUnsafe(ref dRef, (uint)i); + Vector256 vx = x.AsUInt32() - Vector256.Create(V_OFF); + Vector256 n = Vector256.ConvertToSingle(Vector256.ShiftRightArithmetic(vx.AsInt32(), 23)); - i += Vector128.Count; - } - while (i <= oneVectorFromEnd); + vx = (vx & Vector256.Create(V_MASK)) + Vector256.Create(V_OFF); - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - uint lastVectorIndex = (uint)(x.Length - Vector128.Count); - TTernaryOperator.Invoke(Vector128.LoadUnsafe(ref xRef, lastVectorIndex), - yVec, - Vector128.LoadUnsafe(ref zRef, lastVectorIndex)).StoreUnsafe(ref dRef, lastVectorIndex); - } + Vector256 r = vx.AsSingle() - Vector256.Create(1.0f); - return; - } - } + Vector256 r2 = r * r; + Vector256 r4 = r2 * r2; + Vector256 r8 = r4 * r4; - while (i < x.Length) - { - Unsafe.Add(ref dRef, i) = TTernaryOperator.Invoke(Unsafe.Add(ref xRef, i), - y, - Unsafe.Add(ref zRef, i)); + Vector256 q = (Vector256.Create(C10) * r2 + (Vector256.Create(C9) * r + Vector256.Create(C8))) + * r8 + (((Vector256.Create(C7) * r + Vector256.Create(C6)) + * r2 + (Vector256.Create(C5) * r + Vector256.Create(C4))) + * r4 + ((Vector256.Create(C3) * r + Vector256.Create(C2)) + * r2 + (Vector256.Create(C1) * r + Vector256.Create(C0)))); - i++; + return Vector256.ConditionalSelect( + specialMask.AsSingle(), + specialResult, + n * Vector256.Create(V_LN2) + q + ); } - } - private readonly struct AddOperator : IBinaryOperator - { - public static float Invoke(float x, float y) => x + y; - public static Vector128 Invoke(Vector128 x, Vector128 y) => x + y; - public static Vector256 Invoke(Vector256 x, Vector256 y) => x + y; #if NET8_0_OR_GREATER - public static Vector512 Invoke(Vector512 x, Vector512 y) => x + y; -#endif + public static Vector512 Invoke(Vector512 x) + { + Vector512 specialResult = x; - public static float Invoke(Vector128 x) => Vector128.Sum(x); - public static float Invoke(Vector256 x) => Vector256.Sum(x); -#if NET8_0_OR_GREATER - public static float Invoke(Vector512 x) => Vector512.Sum(x); -#endif - } + // x is subnormal or infinity or NaN + Vector512 specialMask = Vector512.GreaterThanOrEqual(x.AsUInt32() - Vector512.Create(V_MIN), Vector512.Create(V_MAX - V_MIN)); - private readonly struct SubtractOperator : IBinaryOperator - { - public static float Invoke(float x, float y) => x - y; - public static Vector128 Invoke(Vector128 x, Vector128 y) => x - y; - public static Vector256 Invoke(Vector256 x, Vector256 y) => x - y; -#if NET8_0_OR_GREATER - public static Vector512 Invoke(Vector512 x, Vector512 y) => x - y; -#endif + if (specialMask != Vector512.Zero) + { + // float.IsZero(x) ? float.NegativeInfinity : x + Vector512 zeroMask = Vector512.Equals(x, Vector512.Zero); + + specialResult = Vector512.ConditionalSelect( + zeroMask, + Vector512.Create(float.NegativeInfinity), + specialResult + ); + + // (x < 0) ? float.NaN : x + Vector512 lessThanZeroMask = Vector512.LessThan(x, Vector512.Zero); + + specialResult = Vector512.ConditionalSelect( + lessThanZeroMask, + Vector512.Create(float.NaN), + specialResult + ); + + // float.IsZero(x) | (x < 0) | float.IsNaN(x) | float.IsPositiveInfinity(x) + Vector512 temp = zeroMask + | lessThanZeroMask + | ~Vector512.Equals(x, x) + | Vector512.Equals(x, Vector512.Create(float.PositiveInfinity)); + + // subnormal + Vector512 subnormalMask = Vector512.AndNot(specialMask.AsSingle(), temp); + + x = Vector512.ConditionalSelect( + subnormalMask, + ((x * 8388608.0f).AsUInt32() - Vector512.Create(23u << 23)).AsSingle(), + x + ); + + specialMask = temp.AsUInt32(); + } - public static float Invoke(Vector128 x) => throw new NotSupportedException(); - public static float Invoke(Vector256 x) => throw new NotSupportedException(); -#if NET8_0_OR_GREATER - public static float Invoke(Vector512 x) => throw new NotSupportedException(); -#endif - } + Vector512 vx = x.AsUInt32() - Vector512.Create(V_OFF); + Vector512 n = Vector512.ConvertToSingle(Vector512.ShiftRightArithmetic(vx.AsInt32(), 23)); - private readonly struct SubtractSquaredOperator : IBinaryOperator - { - public static float Invoke(float x, float y) - { - float tmp = x - y; - return tmp * tmp; - } + vx = (vx & Vector512.Create(V_MASK)) + Vector512.Create(V_OFF); - public static Vector128 Invoke(Vector128 x, Vector128 y) - { - Vector128 tmp = x - y; - return tmp * tmp; - } + Vector512 r = vx.AsSingle() - Vector512.Create(1.0f); - public static Vector256 Invoke(Vector256 x, Vector256 y) - { - Vector256 tmp = x - y; - return tmp * tmp; - } + Vector512 r2 = r * r; + Vector512 r4 = r2 * r2; + Vector512 r8 = r4 * r4; -#if NET8_0_OR_GREATER - public static Vector512 Invoke(Vector512 x, Vector512 y) - { - Vector512 tmp = x - y; - return tmp * tmp; - } -#endif + Vector512 q = (Vector512.Create(C10) * r2 + (Vector512.Create(C9) * r + Vector512.Create(C8))) + * r8 + (((Vector512.Create(C7) * r + Vector512.Create(C6)) + * r2 + (Vector512.Create(C5) * r + Vector512.Create(C4))) + * r4 + ((Vector512.Create(C3) * r + Vector512.Create(C2)) + * r2 + (Vector512.Create(C1) * r + Vector512.Create(C0)))); - public static float Invoke(Vector128 x) => throw new NotSupportedException(); - public static float Invoke(Vector256 x) => throw new NotSupportedException(); -#if NET8_0_OR_GREATER - public static float Invoke(Vector512 x) => throw new NotSupportedException(); + return Vector512.ConditionalSelect( + specialMask.AsSingle(), + specialResult, + n * Vector512.Create(V_LN2) + q + ); + } #endif } - private readonly struct MultiplyOperator : IBinaryOperator + /// MathF.Log2(x) + private readonly struct Log2Operator : IUnaryOperator { - public static float Invoke(float x, float y) => x * y; - public static Vector128 Invoke(Vector128 x, Vector128 y) => x * y; - public static Vector256 Invoke(Vector256 x, Vector256 y) => x * y; -#if NET8_0_OR_GREATER - public static Vector512 Invoke(Vector512 x, Vector512 y) => x * y; -#endif + // This code is based on `vrs4_log2f` from amd/aocl-libm-ose + // Copyright (C) 2021-2022 Advanced Micro Devices, Inc. All rights reserved. + // + // Licensed under the BSD 3-Clause "New" or "Revised" License + // See THIRD-PARTY-NOTICES.TXT for the full license text + + // Spec: + // log2f(x) + // = log2f(x) if x ∈ F and x > 0 + // = x if x = qNaN + // = 0 if x = 1 + // = -inf if x = (-0, 0} + // = NaN otherwise + // + // Assumptions/Expectations + // - Maximum ULP is observed to be at 4 + // - Some FPU Exceptions may not be available + // - Performance is at least 3x + // + // Implementation Notes: + // 1. Range Reduction: + // x = 2^n*(1+f) .... (1) + // where n is exponent and is an integer + // (1+f) is mantissa ∈ [1,2). i.e., 1 ≤ 1+f < 2 .... (2) + // + // From (1), taking log on both sides + // log2(x) = log2(2^n * (1+f)) + // = n + log2(1+f) .... (3) + // + // let z = 1 + f + // log2(z) = log2(k) + log2(z) - log2(k) + // log2(z) = log2(kz) - log2(k) + // + // From (2), range of z is [1, 2) + // by simply dividing range by 'k', z is in [1/k, 2/k) .... (4) + // Best choice of k is the one which gives equal and opposite values + // at extrema +- -+ + // 1 | 2 | + // --- - 1 = - |--- - 1 | + // k | k | .... (5) + // +- -+ + // + // Solving for k, k = 3/2, + // From (4), using 'k' value, range is therefore [-0.3333, 0.3333] + // + // 2. Polynomial Approximation: + // More information refer to tools/sollya/vrs4_logf.sollya + // + // 7th Deg - Error abs: 0x1.04c4ac98p-22 rel: 0x1.2216e6f8p-19 + + private const uint V_MIN = 0x00800000; + private const uint V_MAX = 0x7F800000; + private const uint V_MASK = 0x007FFFFF; + private const uint V_OFF = 0x3F2AAAAB; + + private const float C0 = 0.0f; + private const float C1 = 1.4426951f; + private const float C2 = -0.72134554f; + private const float C3 = 0.48089063f; + private const float C4 = -0.36084408f; + private const float C5 = 0.2888971f; + private const float C6 = -0.23594281f; + private const float C7 = 0.19948183f; + private const float C8 = -0.22616665f; + private const float C9 = 0.21228963f; + + public static float Invoke(float x) => MathF.Log2(x); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Invoke(Vector128 x) + public static Vector128 Invoke(Vector128 x) { - float f = x[0]; - for (int i = 1; i < Vector128.Count; i++) + Vector128 specialResult = x; + + // x is subnormal or infinity or NaN + Vector128 specialMask = Vector128.GreaterThanOrEqual(x.AsUInt32() - Vector128.Create(V_MIN), Vector128.Create(V_MAX - V_MIN)); + + if (specialMask != Vector128.Zero) { - f *= x[i]; + // float.IsZero(x) ? float.NegativeInfinity : x + Vector128 zeroMask = Vector128.Equals(x, Vector128.Zero); + + specialResult = Vector128.ConditionalSelect( + zeroMask, + Vector128.Create(float.NegativeInfinity), + specialResult + ); + + // (x < 0) ? float.NaN : x + Vector128 lessThanZeroMask = Vector128.LessThan(x, Vector128.Zero); + + specialResult = Vector128.ConditionalSelect( + lessThanZeroMask, + Vector128.Create(float.NaN), + specialResult + ); + + // float.IsZero(x) | (x < 0) | float.IsNaN(x) | float.IsPositiveInfinity(x) + Vector128 temp = zeroMask + | lessThanZeroMask + | ~Vector128.Equals(x, x) + | Vector128.Equals(x, Vector128.Create(float.PositiveInfinity)); + + // subnormal + Vector128 subnormalMask = Vector128.AndNot(specialMask.AsSingle(), temp); + + x = Vector128.ConditionalSelect( + subnormalMask, + ((x * 8388608.0f).AsUInt32() - Vector128.Create(23u << 23)).AsSingle(), + x + ); + + specialMask = temp.AsUInt32(); } - return f; + + Vector128 vx = x.AsUInt32() - Vector128.Create(V_OFF); + Vector128 n = Vector128.ConvertToSingle(Vector128.ShiftRightArithmetic(vx.AsInt32(), 23)); + + vx = (vx & Vector128.Create(V_MASK)) + Vector128.Create(V_OFF); + + Vector128 r = vx.AsSingle() - Vector128.Create(1.0f); + + Vector128 r2 = r * r; + Vector128 r4 = r2 * r2; + Vector128 r8 = r4 * r4; + + Vector128 poly = (Vector128.Create(C9) * r + Vector128.Create(C8)) * r8 + + (((Vector128.Create(C7) * r + Vector128.Create(C6)) * r2 + + (Vector128.Create(C5) * r + Vector128.Create(C4))) * r4 + + ((Vector128.Create(C3) * r + Vector128.Create(C2)) * r2 + + (Vector128.Create(C1) * r + Vector128.Create(C0)))); + + return Vector128.ConditionalSelect( + specialMask.AsSingle(), + specialResult, + n + poly + ); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Invoke(Vector256 x) + public static Vector256 Invoke(Vector256 x) { - float f = x[0]; - for (int i = 1; i < Vector256.Count; i++) + Vector256 specialResult = x; + + // x is subnormal or infinity or NaN + Vector256 specialMask = Vector256.GreaterThanOrEqual(x.AsUInt32() - Vector256.Create(V_MIN), Vector256.Create(V_MAX - V_MIN)); + + if (specialMask != Vector256.Zero) { - f *= x[i]; + // float.IsZero(x) ? float.NegativeInfinity : x + Vector256 zeroMask = Vector256.Equals(x, Vector256.Zero); + + specialResult = Vector256.ConditionalSelect( + zeroMask, + Vector256.Create(float.NegativeInfinity), + specialResult + ); + + // (x < 0) ? float.NaN : x + Vector256 lessThanZeroMask = Vector256.LessThan(x, Vector256.Zero); + + specialResult = Vector256.ConditionalSelect( + lessThanZeroMask, + Vector256.Create(float.NaN), + specialResult + ); + + // float.IsZero(x) | (x < 0) | float.IsNaN(x) | float.IsPositiveInfinity(x) + Vector256 temp = zeroMask + | lessThanZeroMask + | ~Vector256.Equals(x, x) + | Vector256.Equals(x, Vector256.Create(float.PositiveInfinity)); + + // subnormal + Vector256 subnormalMask = Vector256.AndNot(specialMask.AsSingle(), temp); + + x = Vector256.ConditionalSelect( + subnormalMask, + ((x * 8388608.0f).AsUInt32() - Vector256.Create(23u << 23)).AsSingle(), + x + ); + + specialMask = temp.AsUInt32(); } - return f; + + Vector256 vx = x.AsUInt32() - Vector256.Create(V_OFF); + Vector256 n = Vector256.ConvertToSingle(Vector256.ShiftRightArithmetic(vx.AsInt32(), 23)); + + vx = (vx & Vector256.Create(V_MASK)) + Vector256.Create(V_OFF); + + Vector256 r = vx.AsSingle() - Vector256.Create(1.0f); + + Vector256 r2 = r * r; + Vector256 r4 = r2 * r2; + Vector256 r8 = r4 * r4; + + Vector256 poly = (Vector256.Create(C9) * r + Vector256.Create(C8)) * r8 + + (((Vector256.Create(C7) * r + Vector256.Create(C6)) * r2 + + (Vector256.Create(C5) * r + Vector256.Create(C4))) * r4 + + ((Vector256.Create(C3) * r + Vector256.Create(C2)) * r2 + + (Vector256.Create(C1) * r + Vector256.Create(C0)))); + + return Vector256.ConditionalSelect( + specialMask.AsSingle(), + specialResult, + n + poly + ); } #if NET8_0_OR_GREATER - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Invoke(Vector512 x) + public static Vector512 Invoke(Vector512 x) { - float f = x[0]; - for (int i = 1; i < Vector512.Count; i++) + Vector512 specialResult = x; + + // x is subnormal or infinity or NaN + Vector512 specialMask = Vector512.GreaterThanOrEqual(x.AsUInt32() - Vector512.Create(V_MIN), Vector512.Create(V_MAX - V_MIN)); + + if (specialMask != Vector512.Zero) { - f *= x[i]; + // float.IsZero(x) ? float.NegativeInfinity : x + Vector512 zeroMask = Vector512.Equals(x, Vector512.Zero); + + specialResult = Vector512.ConditionalSelect( + zeroMask, + Vector512.Create(float.NegativeInfinity), + specialResult + ); + + // (x < 0) ? float.NaN : x + Vector512 lessThanZeroMask = Vector512.LessThan(x, Vector512.Zero); + + specialResult = Vector512.ConditionalSelect( + lessThanZeroMask, + Vector512.Create(float.NaN), + specialResult + ); + + // float.IsZero(x) | (x < 0) | float.IsNaN(x) | float.IsPositiveInfinity(x) + Vector512 temp = zeroMask + | lessThanZeroMask + | ~Vector512.Equals(x, x) + | Vector512.Equals(x, Vector512.Create(float.PositiveInfinity)); + + // subnormal + Vector512 subnormalMask = Vector512.AndNot(specialMask.AsSingle(), temp); + + x = Vector512.ConditionalSelect( + subnormalMask, + ((x * 8388608.0f).AsUInt32() - Vector512.Create(23u << 23)).AsSingle(), + x + ); + + specialMask = temp.AsUInt32(); } - return f; + + Vector512 vx = x.AsUInt32() - Vector512.Create(V_OFF); + Vector512 n = Vector512.ConvertToSingle(Vector512.ShiftRightArithmetic(vx.AsInt32(), 23)); + + vx = (vx & Vector512.Create(V_MASK)) + Vector512.Create(V_OFF); + + Vector512 r = vx.AsSingle() - Vector512.Create(1.0f); + + Vector512 r2 = r * r; + Vector512 r4 = r2 * r2; + Vector512 r8 = r4 * r4; + + Vector512 poly = (Vector512.Create(C9) * r + Vector512.Create(C8)) * r8 + + (((Vector512.Create(C7) * r + Vector512.Create(C6)) * r2 + + (Vector512.Create(C5) * r + Vector512.Create(C4))) * r4 + + ((Vector512.Create(C3) * r + Vector512.Create(C2)) * r2 + + (Vector512.Create(C1) * r + Vector512.Create(C0)))); + + return Vector512.ConditionalSelect( + specialMask.AsSingle(), + specialResult, + n + poly + ); } #endif } - private readonly struct DivideOperator : IBinaryOperator + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128 ElementWiseSelect(Vector128 mask, Vector128 left, Vector128 right) { - public static float Invoke(float x, float y) => x / y; - public static Vector128 Invoke(Vector128 x, Vector128 y) => x / y; - public static Vector256 Invoke(Vector256 x, Vector256 y) => x / y; -#if NET8_0_OR_GREATER - public static Vector512 Invoke(Vector512 x, Vector512 y) => x / y; -#endif + if (Sse41.IsSupported) + return Sse41.BlendVariable(left, right, ~mask); - public static float Invoke(Vector128 x) => throw new NotSupportedException(); - public static float Invoke(Vector256 x) => throw new NotSupportedException(); -#if NET8_0_OR_GREATER - public static float Invoke(Vector512 x) => throw new NotSupportedException(); -#endif + return Vector128.ConditionalSelect(mask, left, right); } - private readonly struct NegateOperator : IUnaryOperator + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128 ElementWiseSelect(Vector128 mask, Vector128 left, Vector128 right) { - public static float Invoke(float x) => -x; - public static Vector128 Invoke(Vector128 x) => -x; - public static Vector256 Invoke(Vector256 x) => -x; -#if NET8_0_OR_GREATER - public static Vector512 Invoke(Vector512 x) => -x; -#endif - } + if (Sse41.IsSupported) + return Sse41.BlendVariable(left, right, ~mask); - private readonly struct AddMultiplyOperator : ITernaryOperator - { - public static float Invoke(float x, float y, float z) => (x + y) * z; - public static Vector128 Invoke(Vector128 x, Vector128 y, Vector128 z) => (x + y) * z; - public static Vector256 Invoke(Vector256 x, Vector256 y, Vector256 z) => (x + y) * z; -#if NET8_0_OR_GREATER - public static Vector512 Invoke(Vector512 x, Vector512 y, Vector512 z) => (x + y) * z; -#endif + return Vector128.ConditionalSelect(mask, left, right); } - private readonly struct MultiplyAddOperator : ITernaryOperator + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector256 ElementWiseSelect(Vector256 mask, Vector256 left, Vector256 right) { - public static float Invoke(float x, float y, float z) => (x * y) + z; - public static Vector128 Invoke(Vector128 x, Vector128 y, Vector128 z) => (x * y) + z; - public static Vector256 Invoke(Vector256 x, Vector256 y, Vector256 z) => (x * y) + z; -#if NET8_0_OR_GREATER - public static Vector512 Invoke(Vector512 x, Vector512 y, Vector512 z) => (x * y) + z; -#endif + if (Avx2.IsSupported) + return Avx2.BlendVariable(left, right, ~mask); + + return Vector256.ConditionalSelect(mask, left, right); } - private readonly struct IdentityOperator : IUnaryOperator + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector256 ElementWiseSelect(Vector256 mask, Vector256 left, Vector256 right) { - public static float Invoke(float x) => x; - public static Vector128 Invoke(Vector128 x) => x; - public static Vector256 Invoke(Vector256 x) => x; -#if NET8_0_OR_GREATER - public static Vector512 Invoke(Vector512 x) => x; -#endif + if (Avx2.IsSupported) + return Avx2.BlendVariable(left, right, ~mask); + + return Vector256.ConditionalSelect(mask, left, right); } - private readonly struct SquaredOperator : IUnaryOperator - { - public static float Invoke(float x) => x * x; - public static Vector128 Invoke(Vector128 x) => x * x; - public static Vector256 Invoke(Vector256 x) => x * x; #if NET8_0_OR_GREATER - public static Vector512 Invoke(Vector512 x) => x * x; -#endif + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector512 ElementWiseSelect(Vector512 mask, Vector512 left, Vector512 right) + { + if (Avx512F.IsSupported) + return Avx512F.BlendVariable(left, right, ~mask); + + return Vector512.ConditionalSelect(mask, left, right); } - private readonly struct AbsoluteOperator : IUnaryOperator + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector512 ElementWiseSelect(Vector512 mask, Vector512 left, Vector512 right) { - public static float Invoke(float x) => MathF.Abs(x); + if (Avx512F.IsSupported) + return Avx512F.BlendVariable(left, right, ~mask); - public static Vector128 Invoke(Vector128 x) - { - Vector128 raw = x.AsUInt32(); - Vector128 mask = Vector128.Create((uint)0x7FFFFFFF); - return (raw & mask).AsSingle(); - } - - public static Vector256 Invoke(Vector256 x) - { - Vector256 raw = x.AsUInt32(); - Vector256 mask = Vector256.Create((uint)0x7FFFFFFF); - return (raw & mask).AsSingle(); - } + return Vector512.ConditionalSelect(mask, left, right); + } +#endif + /// 1f / (1f + MathF.Exp(-x)) + private readonly struct SigmoidOperator : IUnaryOperator + { + public static float Invoke(float x) => 1.0f / (1.0f + MathF.Exp(-x)); + public static Vector128 Invoke(Vector128 x) => Vector128.Create(1f) / (Vector128.Create(1f) + ExpOperator.Invoke(-x)); + public static Vector256 Invoke(Vector256 x) => Vector256.Create(1f) / (Vector256.Create(1f) + ExpOperator.Invoke(-x)); #if NET8_0_OR_GREATER - public static Vector512 Invoke(Vector512 x) - { - Vector512 raw = x.AsUInt32(); - Vector512 mask = Vector512.Create((uint)0x7FFFFFFF); - return (raw & mask).AsSingle(); - } + public static Vector512 Invoke(Vector512 x) => Vector512.Create(1f) / (Vector512.Create(1f) + ExpOperator.Invoke(-x)); #endif } + /// Operator that takes one input value and returns a single value. private interface IUnaryOperator { static abstract float Invoke(float x); @@ -1248,20 +11570,30 @@ private interface IUnaryOperator #endif } + /// Operator that takes two input values and returns a single value. private interface IBinaryOperator { static abstract float Invoke(float x, float y); - static abstract Vector128 Invoke(Vector128 x, Vector128 y); - static abstract float Invoke(Vector128 x); static abstract Vector256 Invoke(Vector256 x, Vector256 y); - static abstract float Invoke(Vector256 x); #if NET8_0_OR_GREATER static abstract Vector512 Invoke(Vector512 x, Vector512 y); +#endif + } + + /// that specializes horizontal aggregation of all elements in a vector. + private interface IAggregationOperator : IBinaryOperator + { + static abstract float Invoke(Vector128 x); + static abstract float Invoke(Vector256 x); +#if NET8_0_OR_GREATER static abstract float Invoke(Vector512 x); #endif + + static virtual float IdentityValue => throw new NotSupportedException(); } + /// Operator that takes three input values and returns a single value. private interface ITernaryOperator { static abstract float Invoke(float x, float y, float z); diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs index ed8b3aea0d560f..c0039be0a08e2b 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -8,14 +9,8 @@ namespace System.Numerics.Tensors { public static partial class TensorPrimitives { - private static unsafe bool IsNegative(float f) => *(int*)&f < 0; - - private static float MaxMagnitude(float x, float y) => MathF.Abs(x) >= MathF.Abs(y) ? x : y; - - private static float MinMagnitude(float x, float y) => MathF.Abs(x) < MathF.Abs(y) ? x : y; - - private static float Log2(float x) => MathF.Log(x, 2); - + /// Computes the cosine similarity between the two specified non-empty, equal-length tensors of single-precision floating-point numbers. + /// Assumes arguments have already been validated to be non-empty and equal length. private static float CosineSimilarityCore(ReadOnlySpan x, ReadOnlySpan y) { // Compute the same as: @@ -26,9 +21,9 @@ private static float CosineSimilarityCore(ReadOnlySpan x, ReadOnlySpan= Vector.Count) + if (Vector.IsHardwareAccelerated && + Vector.Count <= 16 && // currently never greater than 8, but 16 would occur if/when AVX512 is supported, and logic in remainder handling assumes that maximum + x.Length >= Vector.Count) { ref float xRef = ref MemoryMarshal.GetReference(x); ref float yRef = ref MemoryMarshal.GetReference(y); @@ -39,6 +34,7 @@ private static float CosineSimilarityCore(ReadOnlySpan x, ReadOnlySpan.Count; + int i = 0; do { Vector xVec = AsVector(ref xRef, i); @@ -52,6 +48,21 @@ private static float CosineSimilarityCore(ReadOnlySpan x, ReadOnlySpan xVec = AsVector(ref xRef, x.Length - Vector.Count); + Vector yVec = AsVector(ref yRef, x.Length - Vector.Count); + + Vector remainderMask = CreateRemainderMaskSingleVector(x.Length - i); + xVec &= remainderMask; + yVec &= remainderMask; + + dotProductVector += xVec * yVec; + xSumOfSquaresVector += xVec * xVec; + ySumOfSquaresVector += yVec * yVec; + } + // Sum the vector lanes into the scalar result. for (int e = 0; e < Vector.Count; e++) { @@ -60,539 +71,3464 @@ private static float CosineSimilarityCore(ReadOnlySpan x, ReadOnlySpan( - float identityValue, ReadOnlySpan x, TLoad load = default, TAggregate aggregate = default) - where TLoad : struct, IUnaryOperator - where TAggregate : struct, IBinaryOperator - { - // Initialize the result to the identity value - float result = identityValue; - int i = 0; + /// Performs an aggregation over all elements in to produce a single-precision floating-point value. + /// Specifies the transform operation that should be applied to each element loaded from . + /// + /// Specifies the aggregation binary operation that should be applied to multiple values to aggregate them into a single value. + /// The aggregation is applied after the transform is applied to each element. + /// + private static unsafe float Aggregate( + ReadOnlySpan x, TTransformOperator transformOp = default, TAggregationOperator aggregationOp = default) + where TTransformOperator : struct, IUnaryOperator + where TAggregationOperator : struct, IAggregationOperator + { + // Since every branch has a cost and since that cost is + // essentially lost for larger inputs, we do branches + // in a way that allows us to have the minimum possible + // for small sizes + + ref float xRef = ref MemoryMarshal.GetReference(x); + + nuint remainder = (uint)(x.Length); + + if (Vector.IsHardwareAccelerated && transformOp.CanVectorize) + { + float result; + + if (remainder >= (uint)(Vector.Count)) + { + result = Vectorized(ref xRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + result = VectorizedSmall(ref xRef, remainder); + } + + return result; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + return SoftwareFallback(ref xRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static float SoftwareFallback(ref float xRef, nuint length, TTransformOperator transformOp = default, TAggregationOperator aggregationOp = default) + { + float result = aggregationOp.IdentityValue; + + for (nuint i = 0; i < length; i++) + { + result = aggregationOp.Invoke(result, transformOp.Invoke(Unsafe.Add(ref xRef, (nint)(i)))); + } + + return result; + } + + static float Vectorized(ref float xRef, nuint remainder, TTransformOperator transformOp = default, TAggregationOperator aggregationOp = default) + { + Vector vresult = new Vector(aggregationOp.IdentityValue); + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector beg = transformOp.Invoke(AsVector(ref xRef)); + Vector end = transformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count))); + + nuint misalignment = 0; + + if (remainder > (uint)(Vector.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + { + float* xPtr = px; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(xPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + misalignment = ((uint)(sizeof(Vector)) - ((nuint)(xPtr) % (uint)(sizeof(Vector)))) / sizeof(float); + + xPtr += misalignment; + + Debug.Assert(((nuint)(xPtr) % (uint)(sizeof(Vector))) == 0); + + remainder -= misalignment; + } + + Vector vector1; + Vector vector2; + Vector vector3; + Vector vector4; + + // We only need to load, so there isn't a lot of benefit to doing non-temporal operations + + while (remainder >= (uint)(Vector.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = transformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 0))); + vector2 = transformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 1))); + vector3 = transformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 2))); + vector4 = transformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 3))); + + vresult = aggregationOp.Invoke(vresult, vector1); + vresult = aggregationOp.Invoke(vresult, vector2); + vresult = aggregationOp.Invoke(vresult, vector3); + vresult = aggregationOp.Invoke(vresult, vector4); + + // We load, process, and store the next four vectors + + vector1 = transformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 4))); + vector2 = transformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 5))); + vector3 = transformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 6))); + vector4 = transformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 7))); + + vresult = aggregationOp.Invoke(vresult, vector1); + vresult = aggregationOp.Invoke(vresult, vector2); + vresult = aggregationOp.Invoke(vresult, vector3); + vresult = aggregationOp.Invoke(vresult, vector4); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector.Count * 8); + + remainder -= (uint)(Vector.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + } + } + + // Store the first block. Handling this separately simplifies the latter code as we know + // they come after and so we can relegate it to full blocks or the trailing elements + + beg = Vector.ConditionalSelect(CreateAlignmentMaskSingleVector((int)(misalignment)), beg, new Vector(aggregationOp.IdentityValue)); + vresult = aggregationOp.Invoke(vresult, beg); + + // Process the remaining [0, Count * 7] elements via a jump table + // + // We end up handling any trailing elements in case 0 and in the + // worst case end up just doing the identity operation here if there + // were no trailing elements. + + nuint blocks = remainder / (nuint)(Vector.Count); + nuint trailing = remainder - (blocks * (nuint)(Vector.Count)); + blocks -= (misalignment == 0) ? 1u : 0u; + remainder -= trailing; + + switch (blocks) + { + case 7: + { + Vector vector = transformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 7))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 6; + } + + case 6: + { + Vector vector = transformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 6))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 5; + } + + case 5: + { + Vector vector = transformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 5))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 4; + } + + case 4: + { + Vector vector = transformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 4))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 3; + } + + case 3: + { + Vector vector = transformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 3))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 2; + } + + case 2: + { + Vector vector = transformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 2))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 1; + } + + case 1: + { + Vector vector = transformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 1))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 0; + } + + case 0: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end = Vector.ConditionalSelect(CreateRemainderMaskSingleVector((int)(trailing)), end, new Vector(aggregationOp.IdentityValue)); + vresult = aggregationOp.Invoke(vresult, end); + break; + } + } + + float result = aggregationOp.IdentityValue; + + for (int i = 0; i < Vector.Count; i++) + { + result = aggregationOp.Invoke(result, vresult[i]); + } + + return result; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static float VectorizedSmall(ref float xRef, nuint remainder, TTransformOperator transformOp = default, TAggregationOperator aggregationOp = default) + { + float result = aggregationOp.IdentityValue; + + switch (remainder) + { + case 7: + { + result = aggregationOp.Invoke(result, transformOp.Invoke(Unsafe.Add(ref xRef, 6))); + goto case 6; + } + + case 6: + { + result = aggregationOp.Invoke(result, transformOp.Invoke(Unsafe.Add(ref xRef, 5))); + goto case 5; + } + + case 5: + { + result = aggregationOp.Invoke(result, transformOp.Invoke(Unsafe.Add(ref xRef, 4))); + goto case 4; + } + + case 4: + { + result = aggregationOp.Invoke(result, transformOp.Invoke(Unsafe.Add(ref xRef, 3))); + goto case 3; + } + + case 3: + { + result = aggregationOp.Invoke(result, transformOp.Invoke(Unsafe.Add(ref xRef, 2))); + goto case 2; + } + + case 2: + { + result = aggregationOp.Invoke(result, transformOp.Invoke(Unsafe.Add(ref xRef, 1))); + goto case 1; + } + + case 1: + { + result = aggregationOp.Invoke(result, transformOp.Invoke(xRef)); + goto case 0; + } + + case 0: + { + break; + } + } + + return result; + } + } + + /// Performs an aggregation over all pair-wise elements in and to produce a single-precision floating-point value. + /// Specifies the binary operation that should be applied to the pair-wise elements loaded from and . + /// + /// Specifies the aggregation binary operation that should be applied to multiple values to aggregate them into a single value. + /// The aggregation is applied to the results of the binary operations on the pair-wise values. + /// + private static unsafe float Aggregate( + ReadOnlySpan x, ReadOnlySpan y, TBinaryOperator binaryOp = default, TAggregationOperator aggregationOp = default) + where TBinaryOperator : struct, IBinaryOperator + where TAggregationOperator : struct, IAggregationOperator + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + // Since every branch has a cost and since that cost is + // essentially lost for larger inputs, we do branches + // in a way that allows us to have the minimum possible + // for small sizes + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + + nuint remainder = (uint)(x.Length); + + if (Vector.IsHardwareAccelerated) + { + float result; + + if (remainder >= (uint)(Vector.Count)) + { + result = Vectorized(ref xRef, ref yRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + result = VectorizedSmall(ref xRef, ref yRef, remainder); + } + + return result; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + return SoftwareFallback(ref xRef, ref yRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static float SoftwareFallback(ref float xRef, ref float yRef, nuint length, TBinaryOperator binaryOp = default, TAggregationOperator aggregationOp = default) + { + float result = aggregationOp.IdentityValue; + + for (nuint i = 0; i < length; i++) + { + result = aggregationOp.Invoke(result, binaryOp.Invoke(Unsafe.Add(ref xRef, (nint)(i)), + Unsafe.Add(ref yRef, (nint)(i)))); + } + + return result; + } + + static float Vectorized(ref float xRef, ref float yRef, nuint remainder, TBinaryOperator binaryOp = default, TAggregationOperator aggregationOp = default) + { + Vector vresult = new Vector(aggregationOp.IdentityValue); + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector beg = binaryOp.Invoke(AsVector(ref xRef), + AsVector(ref yRef)); + Vector end = binaryOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count)), + AsVector(ref yRef, remainder - (uint)(Vector.Count))); + + nuint misalignment = 0; + + if (remainder > (uint)(Vector.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + { + float* xPtr = px; + float* yPtr = py; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(xPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. This is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + misalignment = ((uint)(sizeof(Vector)) - ((nuint)(xPtr) % (uint)(sizeof(Vector)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + + Debug.Assert(((nuint)(xPtr) % (uint)(sizeof(Vector))) == 0); + + remainder -= misalignment; + } + + Vector vector1; + Vector vector2; + Vector vector3; + Vector vector4; + + // We only need to load, so there isn't a lot of benefit to doing non-temporal operations + + while (remainder >= (uint)(Vector.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = binaryOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 0)), + *(Vector*)(yPtr + (uint)(Vector.Count * 0))); + vector2 = binaryOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 1)), + *(Vector*)(yPtr + (uint)(Vector.Count * 1))); + vector3 = binaryOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 2)), + *(Vector*)(yPtr + (uint)(Vector.Count * 2))); + vector4 = binaryOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 3)), + *(Vector*)(yPtr + (uint)(Vector.Count * 3))); + + vresult = aggregationOp.Invoke(vresult, vector1); + vresult = aggregationOp.Invoke(vresult, vector2); + vresult = aggregationOp.Invoke(vresult, vector3); + vresult = aggregationOp.Invoke(vresult, vector4); + + // We load, process, and store the next four vectors + + vector1 = binaryOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 4)), + *(Vector*)(yPtr + (uint)(Vector.Count * 4))); + vector2 = binaryOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 5)), + *(Vector*)(yPtr + (uint)(Vector.Count * 5))); + vector3 = binaryOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 6)), + *(Vector*)(yPtr + (uint)(Vector.Count * 6))); + vector4 = binaryOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 7)), + *(Vector*)(yPtr + (uint)(Vector.Count * 7))); + + vresult = aggregationOp.Invoke(vresult, vector1); + vresult = aggregationOp.Invoke(vresult, vector2); + vresult = aggregationOp.Invoke(vresult, vector3); + vresult = aggregationOp.Invoke(vresult, vector4); + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector.Count * 8); + yPtr += (uint)(Vector.Count * 8); + + remainder -= (uint)(Vector.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + } + } + + // Store the first block. Handling this separately simplifies the latter code as we know + // they come after and so we can relegate it to full blocks or the trailing elements + + beg = Vector.ConditionalSelect(CreateAlignmentMaskSingleVector((int)(misalignment)), beg, new Vector(aggregationOp.IdentityValue)); + vresult = aggregationOp.Invoke(vresult, beg); + + // Process the remaining [0, Count * 7] elements via a jump table + // + // We end up handling any trailing elements in case 0 and in the + // worst case end up just doing the identity operation here if there + // were no trailing elements. + + nuint blocks = remainder / (nuint)(Vector.Count); + nuint trailing = remainder - (blocks * (nuint)(Vector.Count)); + blocks -= (misalignment == 0) ? 1u : 0u; + remainder -= trailing; + + switch (blocks) + { + case 7: + { + Vector vector = binaryOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 7)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 7))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 6; + } + + case 6: + { + Vector vector = binaryOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 6)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 6))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 5; + } + + case 5: + { + Vector vector = binaryOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 5)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 5))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 4; + } + + case 4: + { + Vector vector = binaryOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 4)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 4))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 3; + } + + case 3: + { + Vector vector = binaryOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 3)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 3))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 2; + } + + case 2: + { + Vector vector = binaryOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 2)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 2))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 1; + } + + case 1: + { + Vector vector = binaryOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 1)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 1))); + vresult = aggregationOp.Invoke(vresult, vector); + goto case 0; + } + + case 0: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + end = Vector.ConditionalSelect(CreateRemainderMaskSingleVector((int)(trailing)), end, new Vector(aggregationOp.IdentityValue)); + vresult = aggregationOp.Invoke(vresult, end); + break; + } + } + + float result = aggregationOp.IdentityValue; + + for (int i = 0; i < Vector.Count; i++) + { + result = aggregationOp.Invoke(result, vresult[i]); + } + + return result; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static float VectorizedSmall(ref float xRef, ref float yRef, nuint remainder, TBinaryOperator binaryOp = default, TAggregationOperator aggregationOp = default) + { + float result = aggregationOp.IdentityValue; + + switch (remainder) + { + case 7: + { + result = aggregationOp.Invoke(result, binaryOp.Invoke(Unsafe.Add(ref xRef, 6), + Unsafe.Add(ref yRef, 6))); + goto case 6; + } + + case 6: + { + result = aggregationOp.Invoke(result, binaryOp.Invoke(Unsafe.Add(ref xRef, 5), + Unsafe.Add(ref yRef, 5))); + goto case 5; + } + + case 5: + { + result = aggregationOp.Invoke(result, binaryOp.Invoke(Unsafe.Add(ref xRef, 4), + Unsafe.Add(ref yRef, 4))); + goto case 4; + } + + case 4: + { + result = aggregationOp.Invoke(result, binaryOp.Invoke(Unsafe.Add(ref xRef, 3), + Unsafe.Add(ref yRef, 3))); + goto case 3; + } + + case 3: + { + result = aggregationOp.Invoke(result, binaryOp.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2))); + goto case 2; + } + + case 2: + { + result = aggregationOp.Invoke(result, binaryOp.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1))); + goto case 1; + } + + case 1: + { + result = aggregationOp.Invoke(result, binaryOp.Invoke(xRef, yRef)); + goto case 0; + } + + case 0: + { + break; + } + } + + return result; + } + } + + /// + /// This is the same as + /// with an identity transform, except it early exits on NaN. + /// + private static float MinMaxCore(ReadOnlySpan x, TMinMaxOperator op = default) + where TMinMaxOperator : struct, IBinaryOperator + { + if (x.IsEmpty) + { + ThrowHelper.ThrowArgument_SpansMustBeNonEmpty(); + } + + // This matches the IEEE 754:2019 `maximum`/`minimum` functions. + // It propagates NaN inputs back to the caller and + // otherwise returns the greater of the inputs. + // It treats +0 as greater than -0 as per the specification. + + float result = x[0]; + int i = 0; + + if (Vector.IsHardwareAccelerated && x.Length >= Vector.Count) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + + // Load the first vector as the initial set of results, and bail immediately + // to scalar handling if it contains any NaNs (which don't compare equally to themselves). + Vector resultVector = AsVector(ref xRef, 0), current; + if (Vector.EqualsAll(resultVector, resultVector)) + { + int oneVectorFromEnd = x.Length - Vector.Count; + i = Vector.Count; + + // Aggregate additional vectors into the result as long as there's at least one full vector left to process. + while (i <= oneVectorFromEnd) + { + // Load the next vector, and early exit on NaN. + current = AsVector(ref xRef, i); + if (!Vector.EqualsAll(current, current)) + { + goto Scalar; + } + + resultVector = op.Invoke(resultVector, current); + i += Vector.Count; + } + + // If any elements remain, handle them in one final vector. + if (i != x.Length) + { + current = AsVector(ref xRef, x.Length - Vector.Count); + if (!Vector.EqualsAll(current, current)) + { + goto Scalar; + } + + resultVector = op.Invoke(resultVector, current); + } + + // Aggregate the lanes in the vector to create the final scalar result. + for (int f = 0; f < Vector.Count; f++) + { + result = op.Invoke(result, resultVector[f]); + } + + return result; + } + } + + // Scalar path used when either vectorization is not supported, the input is too small to vectorize, + // or a NaN is encountered. + Scalar: + for (; (uint)i < (uint)x.Length; i++) + { + float current = x[i]; + + if (float.IsNaN(current)) + { + return current; + } + + result = op.Invoke(result, current); + } + + return result; + } + + private static readonly int[] s_0through7 = [0, 1, 2, 3, 4, 5, 6, 7]; + + private static int IndexOfMinMaxCore(ReadOnlySpan x, TIndexOfMinMaxOperator op = default) + where TIndexOfMinMaxOperator : struct, IIndexOfOperator + { + // This matches the IEEE 754:2019 `maximum`/`minimum` functions. + // It propagates NaN inputs back to the caller and + // otherwise returns the index of the greater of the inputs. + // It treats +0 as greater than -0 as per the specification. + + int result; + int i = 0; + + if (Vector.IsHardwareAccelerated && Vector.Count <= 8 && x.Length >= Vector.Count) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + + Vector resultIndex = new Vector(s_0through7); + Vector curIndex = resultIndex; + Vector increment = new Vector(Vector.Count); + + // Load the first vector as the initial set of results, and bail immediately + // to scalar handling if it contains any NaNs (which don't compare equally to themselves). + Vector resultVector = AsVector(ref xRef, 0), current; + if (Vector.EqualsAll(resultVector, resultVector)) + { + int oneVectorFromEnd = x.Length - Vector.Count; + i = Vector.Count; + + // Aggregate additional vectors into the result as long as there's at least one full vector left to process. + while (i <= oneVectorFromEnd) + { + // Load the next vector, and early exit on NaN. + current = AsVector(ref xRef, i); + curIndex = Vector.Add(curIndex, increment); + + if (!Vector.EqualsAll(current, current)) + { + goto Scalar; + } + + op.Invoke(ref resultVector, current, ref resultIndex, curIndex); + i += Vector.Count; + } + + // If any elements remain, handle them in one final vector. + if (i != x.Length) + { + curIndex = Vector.Add(curIndex, new Vector(x.Length - i)); + + current = AsVector(ref xRef, x.Length - Vector.Count); + if (!Vector.EqualsAll(current, current)) + { + goto Scalar; + } + + op.Invoke(ref resultVector, current, ref resultIndex, curIndex); + } + + result = op.Invoke(resultVector, resultIndex); + + return result; + } + } + + // Scalar path used when either vectorization is not supported, the input is too small to vectorize, + // or a NaN is encountered. + Scalar: + float curResult = x[i]; + int curIn = i; + if (float.IsNaN(curResult)) + { + return curIn; + } + + for (; i < x.Length; i++) + { + float current = x[i]; + if (float.IsNaN(current)) + { + return i; + } + + curIn = op.Invoke(ref curResult, current, curIn, i); + } + + return curIn; + } + + /// Performs an element-wise operation on and writes the results to . + /// Specifies the operation to perform on each element loaded from . + private static unsafe void InvokeSpanIntoSpan( + ReadOnlySpan x, Span destination, TUnaryOperator op = default) + where TUnaryOperator : struct, IUnaryOperator + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ValidateInputOutputSpanNonOverlapping(x, destination); + + // Since every branch has a cost and since that cost is + // essentially lost for larger inputs, we do branches + // in a way that allows us to have the minimum possible + // for small sizes + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + nuint remainder = (uint)(x.Length); + + if (Vector.IsHardwareAccelerated && op.CanVectorize) + { + if (remainder >= (uint)(Vector.Count)) + { + Vectorized(ref xRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + VectorizedSmall(ref xRef, ref dRef, remainder); + } + + return; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + SoftwareFallback(ref xRef, ref dRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void SoftwareFallback(ref float xRef, ref float dRef, nuint length, TUnaryOperator op = default) + { + for (nuint i = 0; i < length; i++) + { + Unsafe.Add(ref dRef, (nint)(i)) = op.Invoke(Unsafe.Add(ref xRef, (nint)(i))); + } + } + + static void Vectorized(ref float xRef, ref float dRef, nuint remainder, TUnaryOperator op = default) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector beg = op.Invoke(AsVector(ref xRef)); + Vector end = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count))); + + if (remainder > (uint)(Vector.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. THis is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector)) - ((nuint)(dPtr) % (uint)(sizeof(Vector)))) / sizeof(float); + + xPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector))) == 0); + + remainder -= misalignment; + } + + Vector vector1; + Vector vector2; + Vector vector3; + Vector vector4; + + while (remainder >= (uint)(Vector.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 0))); + vector2 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 1))); + vector3 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 2))); + vector4 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 3))); + + *(Vector*)(dPtr + (uint)(Vector.Count * 0)) = vector1; + *(Vector*)(dPtr + (uint)(Vector.Count * 1)) = vector2; + *(Vector*)(dPtr + (uint)(Vector.Count * 2)) = vector3; + *(Vector*)(dPtr + (uint)(Vector.Count * 3)) = vector4; + + // We load, process, and store the next four vectors + + vector1 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 4))); + vector2 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 5))); + vector3 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 6))); + vector4 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 7))); + + *(Vector*)(dPtr + (uint)(Vector.Count * 4)) = vector1; + *(Vector*)(dPtr + (uint)(Vector.Count * 5)) = vector2; + *(Vector*)(dPtr + (uint)(Vector.Count * 6)) = vector3; + *(Vector*)(dPtr + (uint)(Vector.Count * 7)) = vector4; + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector.Count * 8); + dPtr += (uint)(Vector.Count * 8); + + remainder -= (uint)(Vector.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector.Count - 1)) & (nuint)(-Vector.Count); + + switch (remainder / (uint)(Vector.Count)) + { + case 8: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 8))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 8)) = vector; + goto case 7; + } + + case 7: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 7))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 7)) = vector; + goto case 6; + } + + case 6: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 6))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 6)) = vector; + goto case 5; + } + + case 5: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 5))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 5)) = vector; + goto case 4; + } + + case 4: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 4))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 4)) = vector; + goto case 3; + } + + case 3: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 3))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 3)) = vector; + goto case 2; + } + + case 2: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 2))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 2)) = vector; + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + AsVector(ref dRef, endIndex - (uint)Vector.Count) = end; + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + AsVector(ref dRefBeg) = beg; + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void VectorizedSmall(ref float xRef, ref float dRef, nuint remainder, TUnaryOperator op = default) + { + switch (remainder) + { + case 7: + { + Unsafe.Add(ref dRef, 6) = op.Invoke(Unsafe.Add(ref xRef, 6)); + goto case 6; + } + + case 6: + { + Unsafe.Add(ref dRef, 5) = op.Invoke(Unsafe.Add(ref xRef, 5)); + goto case 5; + } + + case 5: + { + Unsafe.Add(ref dRef, 4) = op.Invoke(Unsafe.Add(ref xRef, 4)); + goto case 4; + } + + case 4: + { + Unsafe.Add(ref dRef, 3) = op.Invoke(Unsafe.Add(ref xRef, 3)); + goto case 3; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = op.Invoke(Unsafe.Add(ref xRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = op.Invoke(Unsafe.Add(ref xRef, 1)); + goto case 1; + } + + case 1: + { + dRef = op.Invoke(xRef); + goto case 0; + } + + case 0: + { + break; + } + } + } + } + + /// + /// Performs an element-wise operation on and , + /// and writes the results to . + /// + /// + /// Specifies the operation to perform on the pair-wise elements loaded from and . + /// + private static unsafe void InvokeSpanSpanIntoSpan( + ReadOnlySpan x, ReadOnlySpan y, Span destination, TBinaryOperator op = default) + where TBinaryOperator : struct, IBinaryOperator + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ValidateInputOutputSpanNonOverlapping(x, destination); + ValidateInputOutputSpanNonOverlapping(y, destination); + + // Since every branch has a cost and since that cost is + // essentially lost for larger inputs, we do branches + // in a way that allows us to have the minimum possible + // for small sizes + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + nuint remainder = (uint)(x.Length); + + if (Vector.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector.Count)) + { + Vectorized(ref xRef, ref yRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + VectorizedSmall(ref xRef, ref yRef, ref dRef, remainder); + } + + return; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + SoftwareFallback(ref xRef, ref yRef, ref dRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void SoftwareFallback(ref float xRef, ref float yRef, ref float dRef, nuint length, TBinaryOperator op = default) + { + for (nuint i = 0; i < length; i++) + { + Unsafe.Add(ref dRef, (nint)(i)) = op.Invoke(Unsafe.Add(ref xRef, (nint)(i)), + Unsafe.Add(ref yRef, (nint)(i))); + } + } + + static void Vectorized(ref float xRef, ref float yRef, ref float dRef, nuint remainder, TBinaryOperator op = default) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector beg = op.Invoke(AsVector(ref xRef), + AsVector(ref yRef)); + Vector end = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count)), + AsVector(ref yRef, remainder - (uint)(Vector.Count))); + + if (remainder > (uint)(Vector.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* yPtr = py; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. THis is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector)) - ((nuint)(dPtr) % (uint)(sizeof(Vector)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector))) == 0); + + remainder -= misalignment; + } + + Vector vector1; + Vector vector2; + Vector vector3; + Vector vector4; + + while (remainder >= (uint)(Vector.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 0)), + *(Vector*)(yPtr + (uint)(Vector.Count * 0))); + vector2 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 1)), + *(Vector*)(yPtr + (uint)(Vector.Count * 1))); + vector3 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 2)), + *(Vector*)(yPtr + (uint)(Vector.Count * 2))); + vector4 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 3)), + *(Vector*)(yPtr + (uint)(Vector.Count * 3))); + + *(Vector*)(dPtr + (uint)(Vector.Count * 0)) = vector1; + *(Vector*)(dPtr + (uint)(Vector.Count * 1)) = vector2; + *(Vector*)(dPtr + (uint)(Vector.Count * 2)) = vector3; + *(Vector*)(dPtr + (uint)(Vector.Count * 3)) = vector4; + + // We load, process, and store the next four vectors + + vector1 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 4)), + *(Vector*)(yPtr + (uint)(Vector.Count * 4))); + vector2 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 5)), + *(Vector*)(yPtr + (uint)(Vector.Count * 5))); + vector3 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 6)), + *(Vector*)(yPtr + (uint)(Vector.Count * 6))); + vector4 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 7)), + *(Vector*)(yPtr + (uint)(Vector.Count * 7))); + + *(Vector*)(dPtr + (uint)(Vector.Count * 4)) = vector1; + *(Vector*)(dPtr + (uint)(Vector.Count * 5)) = vector2; + *(Vector*)(dPtr + (uint)(Vector.Count * 6)) = vector3; + *(Vector*)(dPtr + (uint)(Vector.Count * 7)) = vector4; + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector.Count * 8); + yPtr += (uint)(Vector.Count * 8); + dPtr += (uint)(Vector.Count * 8); + + remainder -= (uint)(Vector.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector.Count - 1)) & (nuint)(-Vector.Count); + + switch (remainder / (uint)(Vector.Count)) + { + case 8: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 8)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 8))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 8)) = vector; + goto case 7; + } + + case 7: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 7)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 7))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 7)) = vector; + goto case 6; + } + + case 6: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 6)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 6))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 6)) = vector; + goto case 5; + } + + case 5: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 5)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 5))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 5)) = vector; + goto case 4; + } + + case 4: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 4)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 4))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 4)) = vector; + goto case 3; + } + + case 3: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 3)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 3))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 3)) = vector; + goto case 2; + } + + case 2: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 2)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 2))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 2)) = vector; + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + AsVector(ref dRef, endIndex - (uint)Vector.Count) = end; + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + AsVector(ref dRefBeg) = beg; + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void VectorizedSmall(ref float xRef, ref float yRef, ref float dRef, nuint remainder, TBinaryOperator op = default) + { + switch (remainder) + { + case 7: + { + Unsafe.Add(ref dRef, 6) = op.Invoke(Unsafe.Add(ref xRef, 6), + Unsafe.Add(ref yRef, 6)); + goto case 6; + } + + case 6: + { + Unsafe.Add(ref dRef, 5) = op.Invoke(Unsafe.Add(ref xRef, 5), + Unsafe.Add(ref yRef, 5)); + goto case 5; + } + + case 5: + { + Unsafe.Add(ref dRef, 4) = op.Invoke(Unsafe.Add(ref xRef, 4), + Unsafe.Add(ref yRef, 4)); + goto case 4; + } + + case 4: + { + Unsafe.Add(ref dRef, 3) = op.Invoke(Unsafe.Add(ref xRef, 3), + Unsafe.Add(ref yRef, 3)); + goto case 3; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = op.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = op.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1)); + goto case 1; + } + + case 1: + { + dRef = op.Invoke(xRef, yRef); + goto case 0; + } + + case 0: + { + break; + } + } + } + } + + /// + /// Performs an element-wise operation on and , + /// and writes the results to . + /// + /// + /// Specifies the operation to perform on each element loaded from with . + /// + private static void InvokeSpanScalarIntoSpan( + ReadOnlySpan x, float y, Span destination, TBinaryOperator op = default) + where TBinaryOperator : struct, IBinaryOperator => + InvokeSpanScalarIntoSpan(x, y, destination, default, op); + + /// + /// Performs an element-wise operation on and , + /// and writes the results to . + /// + /// + /// Specifies the operation to perform on each element loaded from . + /// It is not used with . + /// + /// + /// Specifies the operation to perform on the transformed value from with . + /// + private static unsafe void InvokeSpanScalarIntoSpan( + ReadOnlySpan x, float y, Span destination, TTransformOperator xTransformOp = default, TBinaryOperator binaryOp = default) + where TTransformOperator : struct, IUnaryOperator + where TBinaryOperator : struct, IBinaryOperator + { + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ValidateInputOutputSpanNonOverlapping(x, destination); + + // Since every branch has a cost and since that cost is + // essentially lost for larger inputs, we do branches + // in a way that allows us to have the minimum possible + // for small sizes + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + nuint remainder = (uint)(x.Length); + + if (Vector.IsHardwareAccelerated && xTransformOp.CanVectorize) + { + if (remainder >= (uint)(Vector.Count)) + { + Vectorized(ref xRef, y, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + VectorizedSmall(ref xRef, y, ref dRef, remainder); + } + + return; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + SoftwareFallback(ref xRef, y, ref dRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void SoftwareFallback(ref float xRef, float y, ref float dRef, nuint length, TTransformOperator xTransformOp = default, TBinaryOperator binaryOp = default) + { + for (nuint i = 0; i < length; i++) + { + Unsafe.Add(ref dRef, (nint)(i)) = binaryOp.Invoke(xTransformOp.Invoke(Unsafe.Add(ref xRef, (nint)(i))), + y); + } + } + + static void Vectorized(ref float xRef, float y, ref float dRef, nuint remainder, TTransformOperator xTransformOp = default, TBinaryOperator binaryOp = default) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector yVec = new Vector(y); + + Vector beg = binaryOp.Invoke(xTransformOp.Invoke(AsVector(ref xRef)), + yVec); + Vector end = binaryOp.Invoke(xTransformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count))), + yVec); + + if (remainder > (uint)(Vector.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. THis is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector)) - ((nuint)(dPtr) % (uint)(sizeof(Vector)))) / sizeof(float); + + xPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector))) == 0); + + remainder -= misalignment; + } + + Vector vector1; + Vector vector2; + Vector vector3; + Vector vector4; + + while (remainder >= (uint)(Vector.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = binaryOp.Invoke(xTransformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 0))), + yVec); + vector2 = binaryOp.Invoke(xTransformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 1))), + yVec); + vector3 = binaryOp.Invoke(xTransformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 2))), + yVec); + vector4 = binaryOp.Invoke(xTransformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 3))), + yVec); + + *(Vector*)(dPtr + (uint)(Vector.Count * 0)) = vector1; + *(Vector*)(dPtr + (uint)(Vector.Count * 1)) = vector2; + *(Vector*)(dPtr + (uint)(Vector.Count * 2)) = vector3; + *(Vector*)(dPtr + (uint)(Vector.Count * 3)) = vector4; + + // We load, process, and store the next four vectors + + vector1 = binaryOp.Invoke(xTransformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 4))), + yVec); + vector2 = binaryOp.Invoke(xTransformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 5))), + yVec); + vector3 = binaryOp.Invoke(xTransformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 6))), + yVec); + vector4 = binaryOp.Invoke(xTransformOp.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 7))), + yVec); + + *(Vector*)(dPtr + (uint)(Vector.Count * 4)) = vector1; + *(Vector*)(dPtr + (uint)(Vector.Count * 5)) = vector2; + *(Vector*)(dPtr + (uint)(Vector.Count * 6)) = vector3; + *(Vector*)(dPtr + (uint)(Vector.Count * 7)) = vector4; + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector.Count * 8); + dPtr += (uint)(Vector.Count * 8); + + remainder -= (uint)(Vector.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector.Count - 1)) & (nuint)(-Vector.Count); + + switch (remainder / (uint)(Vector.Count)) + { + case 8: + { + Vector vector = binaryOp.Invoke(xTransformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 8))), + yVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 8)) = vector; + goto case 7; + } + + case 7: + { + Vector vector = binaryOp.Invoke(xTransformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 7))), + yVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 7)) = vector; + goto case 6; + } + + case 6: + { + Vector vector = binaryOp.Invoke(xTransformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 6))), + yVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 6)) = vector; + goto case 5; + } + + case 5: + { + Vector vector = binaryOp.Invoke(xTransformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 5))), + yVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 5)) = vector; + goto case 4; + } + + case 4: + { + Vector vector = binaryOp.Invoke(xTransformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 4))), + yVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 4)) = vector; + goto case 3; + } + + case 3: + { + Vector vector = binaryOp.Invoke(xTransformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 3))), + yVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 3)) = vector; + goto case 2; + } + + case 2: + { + Vector vector = binaryOp.Invoke(xTransformOp.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 2))), + yVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 2)) = vector; + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + AsVector(ref dRef, endIndex - (uint)Vector.Count) = end; + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + AsVector(ref dRefBeg) = beg; + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void VectorizedSmall(ref float xRef, float y, ref float dRef, nuint remainder, TTransformOperator xTransformOp = default, TBinaryOperator binaryOp = default) + { + switch (remainder) + { + case 7: + { + Unsafe.Add(ref dRef, 6) = binaryOp.Invoke(xTransformOp.Invoke(Unsafe.Add(ref xRef, 6)), + y); + goto case 6; + } + + case 6: + { + Unsafe.Add(ref dRef, 5) = binaryOp.Invoke(xTransformOp.Invoke(Unsafe.Add(ref xRef, 5)), + y); + goto case 5; + } + + case 5: + { + Unsafe.Add(ref dRef, 4) = binaryOp.Invoke(xTransformOp.Invoke(Unsafe.Add(ref xRef, 4)), + y); + goto case 4; + } + + case 4: + { + Unsafe.Add(ref dRef, 3) = binaryOp.Invoke(xTransformOp.Invoke(Unsafe.Add(ref xRef, 3)), + y); + goto case 3; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = binaryOp.Invoke(xTransformOp.Invoke(Unsafe.Add(ref xRef, 2)), + y); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = binaryOp.Invoke(xTransformOp.Invoke(Unsafe.Add(ref xRef, 1)), + y); + goto case 1; + } + + case 1: + { + dRef = binaryOp.Invoke(xTransformOp.Invoke(xRef), y); + goto case 0; + } + + case 0: + { + break; + } + } + } + } + + /// + /// Performs an element-wise operation on , , and , + /// and writes the results to . + /// + /// + /// Specifies the operation to perform on the pair-wise elements loaded from , , + /// and . + /// + private static unsafe void InvokeSpanSpanSpanIntoSpan( + ReadOnlySpan x, ReadOnlySpan y, ReadOnlySpan z, Span destination, TTernaryOperator op = default) + where TTernaryOperator : struct, ITernaryOperator + { + if (x.Length != y.Length || x.Length != z.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ValidateInputOutputSpanNonOverlapping(x, destination); + ValidateInputOutputSpanNonOverlapping(y, destination); + ValidateInputOutputSpanNonOverlapping(z, destination); + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float zRef = ref MemoryMarshal.GetReference(z); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + nuint remainder = (uint)(x.Length); + + if (Vector.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector.Count)) + { + Vectorized(ref xRef, ref yRef, ref zRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + VectorizedSmall(ref xRef, ref yRef, ref zRef, ref dRef, remainder); + } + + return; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + SoftwareFallback(ref xRef, ref yRef, ref zRef, ref dRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void SoftwareFallback(ref float xRef, ref float yRef, ref float zRef, ref float dRef, nuint length, TTernaryOperator op = default) + { + for (nuint i = 0; i < length; i++) + { + Unsafe.Add(ref dRef, (nint)(i)) = op.Invoke(Unsafe.Add(ref xRef, (nint)(i)), + Unsafe.Add(ref yRef, (nint)(i)), + Unsafe.Add(ref zRef, (nint)(i))); + } + } + + static void Vectorized(ref float xRef, ref float yRef, ref float zRef, ref float dRef, nuint remainder, TTernaryOperator op = default) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector beg = op.Invoke(AsVector(ref xRef), + AsVector(ref yRef), + AsVector(ref zRef)); + Vector end = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count)), + AsVector(ref yRef, remainder - (uint)(Vector.Count)), + AsVector(ref zRef, remainder - (uint)(Vector.Count))); + + if (remainder > (uint)(Vector.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + fixed (float* pz = &zRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* yPtr = py; + float* zPtr = pz; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. THis is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector)) - ((nuint)(dPtr) % (uint)(sizeof(Vector)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + zPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector))) == 0); + + remainder -= misalignment; + } + + Vector vector1; + Vector vector2; + Vector vector3; + Vector vector4; + + while (remainder >= (uint)(Vector.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 0)), + *(Vector*)(yPtr + (uint)(Vector.Count * 0)), + *(Vector*)(zPtr + (uint)(Vector.Count * 0))); + vector2 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 1)), + *(Vector*)(yPtr + (uint)(Vector.Count * 1)), + *(Vector*)(zPtr + (uint)(Vector.Count * 1))); + vector3 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 2)), + *(Vector*)(yPtr + (uint)(Vector.Count * 2)), + *(Vector*)(zPtr + (uint)(Vector.Count * 2))); + vector4 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 3)), + *(Vector*)(yPtr + (uint)(Vector.Count * 3)), + *(Vector*)(zPtr + (uint)(Vector.Count * 3))); + + *(Vector*)(dPtr + (uint)(Vector.Count * 0)) = vector1; + *(Vector*)(dPtr + (uint)(Vector.Count * 1)) = vector2; + *(Vector*)(dPtr + (uint)(Vector.Count * 2)) = vector3; + *(Vector*)(dPtr + (uint)(Vector.Count * 3)) = vector4; + + // We load, process, and store the next four vectors + + vector1 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 4)), + *(Vector*)(yPtr + (uint)(Vector.Count * 4)), + *(Vector*)(zPtr + (uint)(Vector.Count * 4))); + vector2 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 5)), + *(Vector*)(yPtr + (uint)(Vector.Count * 5)), + *(Vector*)(zPtr + (uint)(Vector.Count * 5))); + vector3 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 6)), + *(Vector*)(yPtr + (uint)(Vector.Count * 6)), + *(Vector*)(zPtr + (uint)(Vector.Count * 6))); + vector4 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 7)), + *(Vector*)(yPtr + (uint)(Vector.Count * 7)), + *(Vector*)(zPtr + (uint)(Vector.Count * 7))); + + *(Vector*)(dPtr + (uint)(Vector.Count * 4)) = vector1; + *(Vector*)(dPtr + (uint)(Vector.Count * 5)) = vector2; + *(Vector*)(dPtr + (uint)(Vector.Count * 6)) = vector3; + *(Vector*)(dPtr + (uint)(Vector.Count * 7)) = vector4; + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector.Count * 8); + yPtr += (uint)(Vector.Count * 8); + zPtr += (uint)(Vector.Count * 8); + dPtr += (uint)(Vector.Count * 8); + + remainder -= (uint)(Vector.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + zRef = ref *zPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector.Count - 1)) & (nuint)(-Vector.Count); + + switch (remainder / (uint)(Vector.Count)) + { + case 8: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 8)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 8)), + AsVector(ref zRef, remainder - (uint)(Vector.Count * 8))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 8)) = vector; + goto case 7; + } + + case 7: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 7)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 7)), + AsVector(ref zRef, remainder - (uint)(Vector.Count * 7))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 7)) = vector; + goto case 6; + } + + case 6: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 6)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 6)), + AsVector(ref zRef, remainder - (uint)(Vector.Count * 6))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 6)) = vector; + goto case 5; + } + + case 5: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 5)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 5)), + AsVector(ref zRef, remainder - (uint)(Vector.Count * 5))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 5)) = vector; + goto case 4; + } + + case 4: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 4)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 4)), + AsVector(ref zRef, remainder - (uint)(Vector.Count * 4))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 4)) = vector; + goto case 3; + } + + case 3: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 3)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 3)), + AsVector(ref zRef, remainder - (uint)(Vector.Count * 3))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 3)) = vector; + goto case 2; + } + + case 2: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 2)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 2)), + AsVector(ref zRef, remainder - (uint)(Vector.Count * 2))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 2)) = vector; + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + AsVector(ref dRef, endIndex - (uint)Vector.Count) = end; + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + AsVector(ref dRefBeg) = beg; + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void VectorizedSmall(ref float xRef, ref float yRef, ref float zRef, ref float dRef, nuint remainder, TTernaryOperator op = default) + { + switch (remainder) + { + case 7: + { + Unsafe.Add(ref dRef, 6) = op.Invoke(Unsafe.Add(ref xRef, 6), + Unsafe.Add(ref yRef, 6), + Unsafe.Add(ref zRef, 6)); + goto case 6; + } + + case 6: + { + Unsafe.Add(ref dRef, 5) = op.Invoke(Unsafe.Add(ref xRef, 5), + Unsafe.Add(ref yRef, 5), + Unsafe.Add(ref zRef, 5)); + goto case 5; + } + + case 5: + { + Unsafe.Add(ref dRef, 4) = op.Invoke(Unsafe.Add(ref xRef, 4), + Unsafe.Add(ref yRef, 4), + Unsafe.Add(ref zRef, 4)); + goto case 4; + } + + case 4: + { + Unsafe.Add(ref dRef, 3) = op.Invoke(Unsafe.Add(ref xRef, 3), + Unsafe.Add(ref yRef, 3), + Unsafe.Add(ref zRef, 3)); + goto case 3; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = op.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2), + Unsafe.Add(ref zRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = op.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1), + Unsafe.Add(ref zRef, 1)); + goto case 1; + } + + case 1: + { + dRef = op.Invoke(xRef, yRef, zRef); + break; + } + + case 0: + { + break; + } + } + } + } + + /// + /// Performs an element-wise operation on , , and , + /// and writes the results to . + /// + /// + /// Specifies the operation to perform on the pair-wise elements loaded from and + /// with . + /// + private static unsafe void InvokeSpanSpanScalarIntoSpan( + ReadOnlySpan x, ReadOnlySpan y, float z, Span destination, TTernaryOperator op = default) + where TTernaryOperator : struct, ITernaryOperator + { + if (x.Length != y.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ValidateInputOutputSpanNonOverlapping(x, destination); + ValidateInputOutputSpanNonOverlapping(y, destination); + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + nuint remainder = (uint)(x.Length); + + if (Vector.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector.Count)) + { + Vectorized(ref xRef, ref yRef, z, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + VectorizedSmall(ref xRef, ref yRef, z, ref dRef, remainder); + } + + return; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + SoftwareFallback(ref xRef, ref yRef, z, ref dRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void SoftwareFallback(ref float xRef, ref float yRef, float z, ref float dRef, nuint length, TTernaryOperator op = default) + { + for (nuint i = 0; i < length; i++) + { + Unsafe.Add(ref dRef, (nint)(i)) = op.Invoke(Unsafe.Add(ref xRef, (nint)(i)), + Unsafe.Add(ref yRef, (nint)(i)), + z); + } + } + + static void Vectorized(ref float xRef, ref float yRef, float z, ref float dRef, nuint remainder, TTernaryOperator op = default) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector zVec = new Vector(z); + + Vector beg = op.Invoke(AsVector(ref xRef), + AsVector(ref yRef), + zVec); + Vector end = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count)), + AsVector(ref yRef, remainder - (uint)(Vector.Count)), + zVec); + + if (remainder > (uint)(Vector.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* py = &yRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* yPtr = py; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. THis is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector)) - ((nuint)(dPtr) % (uint)(sizeof(Vector)))) / sizeof(float); + + xPtr += misalignment; + yPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector))) == 0); + + remainder -= misalignment; + } + + Vector vector1; + Vector vector2; + Vector vector3; + Vector vector4; + + while (remainder >= (uint)(Vector.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 0)), + *(Vector*)(yPtr + (uint)(Vector.Count * 0)), + zVec); + vector2 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 1)), + *(Vector*)(yPtr + (uint)(Vector.Count * 1)), + zVec); + vector3 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 2)), + *(Vector*)(yPtr + (uint)(Vector.Count * 2)), + zVec); + vector4 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 3)), + *(Vector*)(yPtr + (uint)(Vector.Count * 3)), + zVec); + + *(Vector*)(dPtr + (uint)(Vector.Count * 0)) = vector1; + *(Vector*)(dPtr + (uint)(Vector.Count * 1)) = vector2; + *(Vector*)(dPtr + (uint)(Vector.Count * 2)) = vector3; + *(Vector*)(dPtr + (uint)(Vector.Count * 3)) = vector4; + + // We load, process, and store the next four vectors + + vector1 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 4)), + *(Vector*)(yPtr + (uint)(Vector.Count * 4)), + zVec); + vector2 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 5)), + *(Vector*)(yPtr + (uint)(Vector.Count * 5)), + zVec); + vector3 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 6)), + *(Vector*)(yPtr + (uint)(Vector.Count * 6)), + zVec); + vector4 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 7)), + *(Vector*)(yPtr + (uint)(Vector.Count * 7)), + zVec); + + *(Vector*)(dPtr + (uint)(Vector.Count * 4)) = vector1; + *(Vector*)(dPtr + (uint)(Vector.Count * 5)) = vector2; + *(Vector*)(dPtr + (uint)(Vector.Count * 6)) = vector3; + *(Vector*)(dPtr + (uint)(Vector.Count * 7)) = vector4; + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector.Count * 8); + yPtr += (uint)(Vector.Count * 8); + dPtr += (uint)(Vector.Count * 8); + + remainder -= (uint)(Vector.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + yRef = ref *yPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector.Count - 1)) & (nuint)(-Vector.Count); + + switch (remainder / (uint)(Vector.Count)) + { + case 8: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 8)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 8)), + zVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 8)) = vector; + goto case 7; + } + + case 7: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 7)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 7)), + zVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 7)) = vector; + goto case 6; + } + + case 6: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 6)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 6)), + zVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 6)) = vector; + goto case 5; + } + + case 5: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 5)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 5)), + zVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 5)) = vector; + goto case 4; + } + + case 4: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 4)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 4)), + zVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 4)) = vector; + goto case 3; + } + + case 3: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 3)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 3)), + zVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 3)) = vector; + goto case 2; + } + + case 2: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 2)), + AsVector(ref yRef, remainder - (uint)(Vector.Count * 2)), + zVec); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 2)) = vector; + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + AsVector(ref dRef, endIndex - (uint)Vector.Count) = end; + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + AsVector(ref dRefBeg) = beg; + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void VectorizedSmall(ref float xRef, ref float yRef, float z, ref float dRef, nuint remainder, TTernaryOperator op = default) + { + switch (remainder) + { + case 7: + { + Unsafe.Add(ref dRef, 6) = op.Invoke(Unsafe.Add(ref xRef, 6), + Unsafe.Add(ref yRef, 6), + z); + goto case 6; + } + + case 6: + { + Unsafe.Add(ref dRef, 5) = op.Invoke(Unsafe.Add(ref xRef, 5), + Unsafe.Add(ref yRef, 5), + z); + goto case 5; + } + + case 5: + { + Unsafe.Add(ref dRef, 4) = op.Invoke(Unsafe.Add(ref xRef, 4), + Unsafe.Add(ref yRef, 4), + z); + goto case 4; + } + + case 4: + { + Unsafe.Add(ref dRef, 3) = op.Invoke(Unsafe.Add(ref xRef, 3), + Unsafe.Add(ref yRef, 3), + z); + goto case 3; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = op.Invoke(Unsafe.Add(ref xRef, 2), + Unsafe.Add(ref yRef, 2), + z); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = op.Invoke(Unsafe.Add(ref xRef, 1), + Unsafe.Add(ref yRef, 1), + z); + goto case 1; + } + + case 1: + { + dRef = op.Invoke(xRef, yRef, z); + goto case 0; + } + + case 0: + { + break; + } + } + } + } + + /// + /// Performs an element-wise operation on , , and , + /// and writes the results to . + /// + /// + /// Specifies the operation to perform on the pair-wise element loaded from , with , + /// and the element loaded from . + /// + private static unsafe void InvokeSpanScalarSpanIntoSpan( + ReadOnlySpan x, float y, ReadOnlySpan z, Span destination, TTernaryOperator op = default) + where TTernaryOperator : struct, ITernaryOperator + { + if (x.Length != z.Length) + { + ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + } + + if (x.Length > destination.Length) + { + ThrowHelper.ThrowArgument_DestinationTooShort(); + } + + ValidateInputOutputSpanNonOverlapping(x, destination); + ValidateInputOutputSpanNonOverlapping(z, destination); + + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float zRef = ref MemoryMarshal.GetReference(z); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + nuint remainder = (uint)(x.Length); + + if (Vector.IsHardwareAccelerated) + { + if (remainder >= (uint)(Vector.Count)) + { + Vectorized(ref xRef, y, ref zRef, ref dRef, remainder); + } + else + { + // We have less than a vector and so we can only handle this as scalar. To do this + // efficiently, we simply have a small jump table and fallthrough. So we get a simple + // length check, single jump, and then linear execution. + + VectorizedSmall(ref xRef, y, ref zRef, ref dRef, remainder); + } + + return; + } + + // This is the software fallback when no acceleration is available + // It requires no branches to hit + + SoftwareFallback(ref xRef, y, ref zRef, ref dRef, remainder); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void SoftwareFallback(ref float xRef, float y, ref float zRef, ref float dRef, nuint length, TTernaryOperator op = default) + { + for (nuint i = 0; i < length; i++) + { + Unsafe.Add(ref dRef, (nint)(i)) = op.Invoke(Unsafe.Add(ref xRef, (nint)(i)), + y, + Unsafe.Add(ref zRef, (nint)(i))); + } + } + + static void Vectorized(ref float xRef, float y, ref float zRef, ref float dRef, nuint remainder, TTernaryOperator op = default) + { + ref float dRefBeg = ref dRef; + + // Preload the beginning and end so that overlapping accesses don't negatively impact the data + + Vector yVec = new Vector(y); + + Vector beg = op.Invoke(AsVector(ref xRef), + yVec, + AsVector(ref zRef)); + Vector end = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count)), + yVec, + AsVector(ref zRef, remainder - (uint)(Vector.Count))); + + if (remainder > (uint)(Vector.Count * 8)) + { + // Pinning is cheap and will be short lived for small inputs and unlikely to be impactful + // for large inputs (> 85KB) which are on the LOH and unlikely to be compacted. + + fixed (float* px = &xRef) + fixed (float* pz = &zRef) + fixed (float* pd = &dRef) + { + float* xPtr = px; + float* zPtr = pz; + float* dPtr = pd; + + // We need to the ensure the underlying data can be aligned and only align + // it if it can. It is possible we have an unaligned ref, in which case we + // can never achieve the required SIMD alignment. + + bool canAlign = ((nuint)(dPtr) % sizeof(float)) == 0; + + if (canAlign) + { + // Compute by how many elements we're misaligned and adjust the pointers accordingly + // + // Noting that we are only actually aligning dPtr. THis is because unaligned stores + // are more expensive than unaligned loads and aligning both is significantly more + // complex. + + nuint misalignment = ((uint)(sizeof(Vector)) - ((nuint)(dPtr) % (uint)(sizeof(Vector)))) / sizeof(float); + + xPtr += misalignment; + zPtr += misalignment; + dPtr += misalignment; + + Debug.Assert(((nuint)(dPtr) % (uint)(sizeof(Vector))) == 0); + + remainder -= misalignment; + } + + Vector vector1; + Vector vector2; + Vector vector3; + Vector vector4; + + while (remainder >= (uint)(Vector.Count * 8)) + { + // We load, process, and store the first four vectors + + vector1 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 0)), + yVec, + *(Vector*)(zPtr + (uint)(Vector.Count * 0))); + vector2 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 1)), + yVec, + *(Vector*)(zPtr + (uint)(Vector.Count * 1))); + vector3 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 2)), + yVec, + *(Vector*)(zPtr + (uint)(Vector.Count * 2))); + vector4 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 3)), + yVec, + *(Vector*)(zPtr + (uint)(Vector.Count * 3))); + + *(Vector*)(dPtr + (uint)(Vector.Count * 0)) = vector1; + *(Vector*)(dPtr + (uint)(Vector.Count * 1)) = vector2; + *(Vector*)(dPtr + (uint)(Vector.Count * 2)) = vector3; + *(Vector*)(dPtr + (uint)(Vector.Count * 3)) = vector4; + + // We load, process, and store the next four vectors + + vector1 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 4)), + yVec, + *(Vector*)(zPtr + (uint)(Vector.Count * 4))); + vector2 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 5)), + yVec, + *(Vector*)(zPtr + (uint)(Vector.Count * 5))); + vector3 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 6)), + yVec, + *(Vector*)(zPtr + (uint)(Vector.Count * 6))); + vector4 = op.Invoke(*(Vector*)(xPtr + (uint)(Vector.Count * 7)), + yVec, + *(Vector*)(zPtr + (uint)(Vector.Count * 7))); + + *(Vector*)(dPtr + (uint)(Vector.Count * 4)) = vector1; + *(Vector*)(dPtr + (uint)(Vector.Count * 5)) = vector2; + *(Vector*)(dPtr + (uint)(Vector.Count * 6)) = vector3; + *(Vector*)(dPtr + (uint)(Vector.Count * 7)) = vector4; + + // We adjust the source and destination references, then update + // the count of remaining elements to process. + + xPtr += (uint)(Vector.Count * 8); + zPtr += (uint)(Vector.Count * 8); + dPtr += (uint)(Vector.Count * 8); + + remainder -= (uint)(Vector.Count * 8); + } + + // Adjusting the refs here allows us to avoid pinning for very small inputs + + xRef = ref *xPtr; + zRef = ref *zPtr; + dRef = ref *dPtr; + } + } + + // Process the remaining [Count, Count * 8] elements via a jump table + // + // Unless the original length was an exact multiple of Count, then we'll + // end up reprocessing a couple elements in case 1 for end. We'll also + // potentially reprocess a few elements in case 0 for beg, to handle any + // data before the first aligned address. + + nuint endIndex = remainder; + remainder = (remainder + (uint)(Vector.Count - 1)) & (nuint)(-Vector.Count); + + switch (remainder / (uint)(Vector.Count)) + { + case 8: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 8)), + yVec, + AsVector(ref zRef, remainder - (uint)(Vector.Count * 8))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 8)) = vector; + goto case 7; + } + + case 7: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 7)), + yVec, + AsVector(ref zRef, remainder - (uint)(Vector.Count * 7))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 7)) = vector; + goto case 6; + } + + case 6: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 6)), + yVec, + AsVector(ref zRef, remainder - (uint)(Vector.Count * 6))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 6)) = vector; + goto case 5; + } + + case 5: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 5)), + yVec, + AsVector(ref zRef, remainder - (uint)(Vector.Count * 5))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 5)) = vector; + goto case 4; + } + + case 4: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 4)), + yVec, + AsVector(ref zRef, remainder - (uint)(Vector.Count * 4))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 4)) = vector; + goto case 3; + } + + case 3: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 3)), + yVec, + AsVector(ref zRef, remainder - (uint)(Vector.Count * 3))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 3)) = vector; + goto case 2; + } + + case 2: + { + Vector vector = op.Invoke(AsVector(ref xRef, remainder - (uint)(Vector.Count * 2)), + yVec, + AsVector(ref zRef, remainder - (uint)(Vector.Count * 2))); + AsVector(ref dRef, remainder - (uint)(Vector.Count * 2)) = vector; + goto case 1; + } + + case 1: + { + // Store the last block, which includes any elements that wouldn't fill a full vector + AsVector(ref dRef, endIndex - (uint)Vector.Count) = end; + goto case 0; + } + + case 0: + { + // Store the first block, which includes any elements preceding the first aligned block + AsVector(ref dRefBeg) = beg; + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void VectorizedSmall(ref float xRef, float y, ref float zRef, ref float dRef, nuint remainder, TTernaryOperator op = default) + { + switch (remainder) + { + case 7: + { + Unsafe.Add(ref dRef, 6) = op.Invoke(Unsafe.Add(ref xRef, 6), + y, + Unsafe.Add(ref zRef, 6)); + goto case 6; + } + + case 6: + { + Unsafe.Add(ref dRef, 5) = op.Invoke(Unsafe.Add(ref xRef, 5), + y, + Unsafe.Add(ref zRef, 5)); + goto case 5; + } + + case 5: + { + Unsafe.Add(ref dRef, 4) = op.Invoke(Unsafe.Add(ref xRef, 4), + y, + Unsafe.Add(ref zRef, 4)); + goto case 4; + } + + case 4: + { + Unsafe.Add(ref dRef, 3) = op.Invoke(Unsafe.Add(ref xRef, 3), + y, + Unsafe.Add(ref zRef, 3)); + goto case 3; + } + + case 3: + { + Unsafe.Add(ref dRef, 2) = op.Invoke(Unsafe.Add(ref xRef, 2), + y, + Unsafe.Add(ref zRef, 2)); + goto case 2; + } + + case 2: + { + Unsafe.Add(ref dRef, 1) = op.Invoke(Unsafe.Add(ref xRef, 1), + y, + Unsafe.Add(ref zRef, 1)); + goto case 1; + } + + case 1: + { + dRef = op.Invoke(xRef, y, zRef); + goto case 0; + } + + case 0: + { + break; + } + } + } + } + + /// Loads a from . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ref Vector AsVector(ref float start) => + ref Unsafe.As>(ref start); + + /// Loads a that begins at the specified from . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ref Vector AsVector(ref float start, int offset) => + ref Unsafe.As>( + ref Unsafe.Add(ref start, offset)); + + /// Loads a that begins at the specified from . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ref Vector AsVector(ref float start, nuint offset) => + ref Unsafe.As>( + ref Unsafe.Add(ref start, (nint)(offset))); + + /// Loads a that begins at the specified from . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ref Vector AsVector(ref int start, int offset) => + ref Unsafe.As>( + ref Unsafe.Add(ref start, offset)); + + /// Gets whether the specified is positive. + private static bool IsPositive(float f) => !IsNegative(f); + + /// Gets whether each specified is positive. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector IsPositive(Vector vector) => + ((Vector)Vector.GreaterThan(((Vector)vector), Vector.Zero)); + + /// Gets whether the specified is negative. + private static unsafe bool IsNegative(float f) => *(int*)&f < 0; + + /// Gets whether each specified is negative. + private static Vector IsNegative(Vector f) => + (Vector)Vector.LessThan((Vector)f, Vector.Zero); + + /// Gets the base 2 logarithm of . + private static float Log2(float x) => MathF.Log(x, 2); + + /// + /// Gets a vector mask that will be all-ones-set for the first elements + /// and zero for all other elements. + /// + private static Vector CreateAlignmentMaskSingleVector(int count) + { + Debug.Assert(Vector.Count is 4 or 8 or 16); + + return AsVector( + ref Unsafe.As(ref MemoryMarshal.GetReference(AlignmentUInt32Mask_16x16)), + (count * 16)); + } + + /// + /// Gets a vector mask that will be all-ones-set for the last elements + /// and zero for all other elements. + /// + private static Vector CreateRemainderMaskSingleVector(int count) + { + Debug.Assert(Vector.Count is 4 or 8 or 16); + + return AsVector( + ref Unsafe.As(ref MemoryMarshal.GetReference(RemainderUInt32Mask_16x16)), + (count * 16) + (16 - Vector.Count)); + } + + /// x + y + private readonly struct AddOperator : IAggregationOperator + { + public float Invoke(float x, float y) => x + y; + public Vector Invoke(Vector x, Vector y) => x + y; + public float IdentityValue => 0; + } + + /// x - y + private readonly struct SubtractOperator : IBinaryOperator + { + public float Invoke(float x, float y) => x - y; + public Vector Invoke(Vector x, Vector y) => x - y; + } + + /// (x - y) * (x - y) + private readonly struct SubtractSquaredOperator : IBinaryOperator + { + public float Invoke(float x, float y) + { + float tmp = x - y; + return tmp * tmp; + } + + public Vector Invoke(Vector x, Vector y) + { + Vector tmp = x - y; + return tmp * tmp; + } + } + + /// x * y + private readonly struct MultiplyOperator : IAggregationOperator + { + public float Invoke(float x, float y) => x * y; + public Vector Invoke(Vector x, Vector y) => x * y; + public float IdentityValue => 1; + } + + /// x / y + private readonly struct DivideOperator : IBinaryOperator + { + public float Invoke(float x, float y) => x / y; + public Vector Invoke(Vector x, Vector y) => x / y; + } + + private interface IIndexOfOperator + { + int Invoke(ref float result, float current, int resultIndex, int curIndex); + int Invoke(Vector result, Vector resultIndex); + void Invoke(ref Vector result, Vector current, ref Vector resultIndex, Vector curIndex); + } + + /// Returns the index of MathF.Max(x, y) + private readonly struct IndexOfMaxOperator : IIndexOfOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Invoke(Vector result, Vector resultIndex) + { + float curMax = result[0]; + int curIn = resultIndex[0]; + for (int i = 1; i < Vector.Count; i++) + { + if (result[i] == curMax && IsNegative(curMax) && !IsNegative(result[i])) + { + curMax = result[i]; + curIn = resultIndex[i]; + } + else if (result[i] > curMax) + { + curMax = result[i]; + curIn = resultIndex[i]; + } + } + + return curIn; + } - if (Vector.IsHardwareAccelerated && x.Length >= Vector.Count * 2) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Invoke(ref Vector result, Vector current, ref Vector resultIndex, Vector curIndex) { - ref float xRef = ref MemoryMarshal.GetReference(x); + Vector lessThanMask = Vector.GreaterThan(result, current); - // Load the first vector as the initial set of results - Vector resultVector = load.Invoke(AsVector(ref xRef, 0)); - int oneVectorFromEnd = x.Length - Vector.Count; + Vector equalMask = Vector.Equals(result, current); - // Aggregate additional vectors into the result as long as there's at - // least one full vector left to process. - i = Vector.Count; - do + if (equalMask != Vector.Zero) { - resultVector = aggregate.Invoke(resultVector, load.Invoke(AsVector(ref xRef, i))); - i += Vector.Count; - } - while (i <= oneVectorFromEnd); + Vector negativeMask = IsNegative(current); + Vector lessThanIndexMask = Vector.LessThan(resultIndex, curIndex); - // Aggregate the lanes in the vector back into the scalar result - for (int f = 0; f < Vector.Count; f++) - { - result = aggregate.Invoke(result, resultVector[f]); + lessThanMask |= ((Vector)~negativeMask & equalMask) | ((Vector)IsNegative(result) & equalMask & lessThanIndexMask); } - } - - // Aggregate the remaining items in the input span. - for (; (uint)i < (uint)x.Length; i++) - { - result = aggregate.Invoke(result, load.Invoke(x[i])); - } - return result; - } + result = Vector.ConditionalSelect(lessThanMask, result, current); - private static float Aggregate( - float identityValue, ReadOnlySpan x, ReadOnlySpan y, TBinary binary = default, TAggregate aggregate = default) - where TBinary : struct, IBinaryOperator - where TAggregate : struct, IBinaryOperator - { - // Initialize the result to the identity value - float result = identityValue; - int i = 0; + resultIndex = Vector.ConditionalSelect(lessThanMask, resultIndex, curIndex); + } - if (Vector.IsHardwareAccelerated && x.Length >= Vector.Count * 2) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Invoke(ref float result, float current, int resultIndex, int curIndex) { - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); - - // Load the first vector as the initial set of results - Vector resultVector = binary.Invoke(AsVector(ref xRef, 0), AsVector(ref yRef, 0)); - int oneVectorFromEnd = x.Length - Vector.Count; - - // Aggregate additional vectors into the result as long as there's at - // least one full vector left to process. - i = Vector.Count; - do + if (result == current) { - resultVector = aggregate.Invoke(resultVector, binary.Invoke(AsVector(ref xRef, i), AsVector(ref yRef, i))); - i += Vector.Count; + if (IsNegative(result) && !IsNegative(current)) + { + result = current; + return curIndex; + } } - while (i <= oneVectorFromEnd); - - // Aggregate the lanes in the vector back into the scalar result - for (int f = 0; f < Vector.Count; f++) + else if (current > result) { - result = aggregate.Invoke(result, resultVector[f]); + result = current; + return curIndex; } - } - // Aggregate the remaining items in the input span. - for (; (uint)i < (uint)x.Length; i++) - { - result = aggregate.Invoke(result, binary.Invoke(x[i], y[i])); + return resultIndex; } - - return result; } - private static void InvokeSpanIntoSpan( - ReadOnlySpan x, Span destination, TUnaryOperator op = default) - where TUnaryOperator : struct, IUnaryOperator + private readonly struct IndexOfMaxMagnitudeOperator : IIndexOfOperator { - if (x.Length > destination.Length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Invoke(ref float result, float current, int resultIndex, int curIndex) { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } + float curMaxAbs = MathF.Abs(result); + float currentAbs = MathF.Abs(current); - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float dRef = ref MemoryMarshal.GetReference(destination); - int i = 0, oneVectorFromEnd; + if (curMaxAbs == currentAbs) + { + if (IsNegative(result) && !IsNegative(current)) + { + result = current; + return curIndex; + } + } + else if (currentAbs > curMaxAbs) + { + result = current; + return curIndex; + } - if (Vector.IsHardwareAccelerated) + return resultIndex; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Invoke(Vector result, Vector maxIndex) { - oneVectorFromEnd = x.Length - Vector.Count; - if (oneVectorFromEnd >= 0) + float curMax = result[0]; + int curIn = maxIndex[0]; + for (int i = 1; i < Vector.Count; i++) { - // Loop handling one vector at a time. - do + if (MathF.Abs(result[i]) == MathF.Abs(curMax) && IsNegative(curMax) && !IsNegative(result[i])) { - AsVector(ref dRef, i) = op.Invoke(AsVector(ref xRef, i)); - - i += Vector.Count; + curMax = result[i]; + curIn = maxIndex[i]; } - while (i <= oneVectorFromEnd); - - // Handle any remaining elements with a final vector. - if (i != x.Length) + else if (MathF.Abs(result[i]) > MathF.Abs(curMax)) { - int lastVectorIndex = x.Length - Vector.Count; - AsVector(ref dRef, lastVectorIndex) = op.Invoke(AsVector(ref xRef, lastVectorIndex)); + curMax = result[i]; + curIn = maxIndex[i]; } - - return; } - } - - // Loop handling one element at a time. - while (i < x.Length) - { - Unsafe.Add(ref dRef, i) = op.Invoke(Unsafe.Add(ref xRef, i)); - i++; + return curIn; } - } - private static void InvokeSpanSpanIntoSpan( - ReadOnlySpan x, ReadOnlySpan y, Span destination, TBinaryOperator op = default) - where TBinaryOperator : struct, IBinaryOperator - { - if (x.Length != y.Length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Invoke(ref Vector result, Vector current, ref Vector resultIndex, Vector curIndex) { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); - } + Vector maxMag = Vector.Abs(result), currentMag = Vector.Abs(current); - if (x.Length > destination.Length) - { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } + Vector lessThanMask = Vector.GreaterThan(maxMag, currentMag); - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); - ref float dRef = ref MemoryMarshal.GetReference(destination); - int i = 0, oneVectorFromEnd; + Vector equalMask = Vector.Equals(result, current); - if (Vector.IsHardwareAccelerated) - { - oneVectorFromEnd = x.Length - Vector.Count; - if (oneVectorFromEnd >= 0) + if (equalMask != Vector.Zero) { - // Loop handling one vector at a time. - do - { - AsVector(ref dRef, i) = op.Invoke(AsVector(ref xRef, i), - AsVector(ref yRef, i)); - - i += Vector.Count; - } - while (i <= oneVectorFromEnd); + Vector negativeMask = IsNegative(current); + Vector lessThanIndexMask = Vector.LessThan(resultIndex, curIndex); - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - int lastVectorIndex = x.Length - Vector.Count; - AsVector(ref dRef, lastVectorIndex) = op.Invoke(AsVector(ref xRef, lastVectorIndex), - AsVector(ref yRef, lastVectorIndex)); - } - - return; + lessThanMask |= ((Vector)~negativeMask & equalMask) | ((Vector)IsNegative(result) & equalMask & lessThanIndexMask); } - } - while (i < x.Length) - { - Unsafe.Add(ref dRef, i) = op.Invoke(Unsafe.Add(ref xRef, i), - Unsafe.Add(ref yRef, i)); + result = Vector.ConditionalSelect(lessThanMask, result, current); - i++; + resultIndex = Vector.ConditionalSelect(lessThanMask, resultIndex, curIndex); } } - private static void InvokeSpanScalarIntoSpan( - ReadOnlySpan x, float y, Span destination, TBinaryOperator op = default) - where TBinaryOperator : struct, IBinaryOperator + private readonly struct IndexOfMinOperator : IIndexOfOperator { - if (x.Length > destination.Length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Invoke(ref float result, float current, int resultIndex, int curIndex) { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } + if (result == current) + { + if (IsPositive(result) && !IsPositive(current)) + { + result = current; + return curIndex; + } + } + else if (current < result) + { + result = current; + return curIndex; + } - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float dRef = ref MemoryMarshal.GetReference(destination); - int i = 0, oneVectorFromEnd; + return resultIndex; + } - if (Vector.IsHardwareAccelerated) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Invoke(Vector result, Vector resultIndex) { - oneVectorFromEnd = x.Length - Vector.Count; - if (oneVectorFromEnd >= 0) + float curMin = result[0]; + int curIn = resultIndex[0]; + for (int i = 1; i < Vector.Count; i++) { - // Loop handling one vector at a time. - Vector yVec = new(y); - do + if (result[i] == curMin && IsPositive(curMin) && !IsPositive(result[i])) { - AsVector(ref dRef, i) = op.Invoke(AsVector(ref xRef, i), - yVec); - - i += Vector.Count; + curMin = result[i]; + curIn = resultIndex[i]; } - while (i <= oneVectorFromEnd); - - // Handle any remaining elements with a final vector. - if (i != x.Length) + else if (result[i] < curMin) { - int lastVectorIndex = x.Length - Vector.Count; - AsVector(ref dRef, lastVectorIndex) = op.Invoke(AsVector(ref xRef, lastVectorIndex), - yVec); + curMin = result[i]; + curIn = resultIndex[i]; } - - return; } + + return curIn; } - // Loop handling one element at a time. - while (i < x.Length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Invoke(ref Vector result, Vector current, ref Vector resultIndex, Vector curIndex) { - Unsafe.Add(ref dRef, i) = op.Invoke(Unsafe.Add(ref xRef, i), - y); + Vector lessThanMask = Vector.LessThan(result, current); + + Vector equalMask = Vector.Equals(result, current); + + if (equalMask != Vector.Zero) + { + Vector negativeMask = IsNegative(current); + Vector lessThanIndexMask = Vector.LessThan(resultIndex, curIndex); + + lessThanMask |= ((Vector)negativeMask & equalMask) | (~(Vector)IsNegative(result) & equalMask & lessThanIndexMask); + } + + result = Vector.ConditionalSelect(lessThanMask, result, current); - i++; + resultIndex = Vector.ConditionalSelect(lessThanMask, resultIndex, curIndex); } } - private static void InvokeSpanSpanSpanIntoSpan( - ReadOnlySpan x, ReadOnlySpan y, ReadOnlySpan z, Span destination, TTernaryOperator op = default) - where TTernaryOperator : struct, ITernaryOperator + private readonly struct IndexOfMinMagnitudeOperator : IIndexOfOperator { - if (x.Length != y.Length || x.Length != z.Length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Invoke(ref float result, float current, int resultIndex, int curIndex) { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); - } + float curMinAbs = MathF.Abs(result); + float currentAbs = MathF.Abs(current); + if (curMinAbs == currentAbs) + { + if (IsPositive(result) && !IsPositive(current)) + { + result = current; + return curIndex; + } + } + else if (currentAbs < curMinAbs) + { + result = current; + return curIndex; + } - if (x.Length > destination.Length) - { - ThrowHelper.ThrowArgument_DestinationTooShort(); + return resultIndex; } - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); - ref float zRef = ref MemoryMarshal.GetReference(z); - ref float dRef = ref MemoryMarshal.GetReference(destination); - int i = 0, oneVectorFromEnd; - - if (Vector.IsHardwareAccelerated) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Invoke(Vector result, Vector resultIndex) { - oneVectorFromEnd = x.Length - Vector.Count; - if (oneVectorFromEnd >= 0) + float curMin = result[0]; + int curIn = resultIndex[0]; + for (int i = 1; i < Vector.Count; i++) { - // Loop handling one vector at a time. - do + if (MathF.Abs(result[i]) == MathF.Abs(curMin) && IsPositive(curMin) && !IsPositive(result[i])) { - AsVector(ref dRef, i) = op.Invoke(AsVector(ref xRef, i), - AsVector(ref yRef, i), - AsVector(ref zRef, i)); - - i += Vector.Count; + curMin = result[i]; + curIn = resultIndex[i]; } - while (i <= oneVectorFromEnd); - - // Handle any remaining elements with a final vector. - if (i != x.Length) + else if (MathF.Abs(result[i]) < MathF.Abs(curMin)) { - int lastVectorIndex = x.Length - Vector.Count; - AsVector(ref dRef, lastVectorIndex) = op.Invoke(AsVector(ref xRef, lastVectorIndex), - AsVector(ref yRef, lastVectorIndex), - AsVector(ref zRef, lastVectorIndex)); + curMin = result[i]; + curIn = resultIndex[i]; } - - return; } - } - // Loop handling one element at a time. - while (i < x.Length) - { - Unsafe.Add(ref dRef, i) = op.Invoke(Unsafe.Add(ref xRef, i), - Unsafe.Add(ref yRef, i), - Unsafe.Add(ref zRef, i)); - - i++; + return curIn; } - } - private static void InvokeSpanSpanScalarIntoSpan( - ReadOnlySpan x, ReadOnlySpan y, float z, Span destination, TTernaryOperator op = default) - where TTernaryOperator : struct, ITernaryOperator - { - if (x.Length != y.Length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Invoke(ref Vector result, Vector current, ref Vector resultIndex, Vector curIndex) { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); - } + Vector minMag = Vector.Abs(result), currentMag = Vector.Abs(current); - if (x.Length > destination.Length) - { - ThrowHelper.ThrowArgument_DestinationTooShort(); - } + Vector lessThanMask = Vector.LessThan(minMag, currentMag); - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); - ref float dRef = ref MemoryMarshal.GetReference(destination); - int i = 0, oneVectorFromEnd; + Vector equalMask = Vector.Equals(result, current); - if (Vector.IsHardwareAccelerated) - { - oneVectorFromEnd = x.Length - Vector.Count; - if (oneVectorFromEnd >= 0) + if (equalMask != Vector.Zero) { - Vector zVec = new(z); - - // Loop handling one vector at a time. - do - { - AsVector(ref dRef, i) = op.Invoke(AsVector(ref xRef, i), - AsVector(ref yRef, i), - zVec); + Vector negativeMask = IsNegative(current); + Vector lessThanIndexMask = Vector.LessThan(resultIndex, curIndex); - i += Vector.Count; - } - while (i <= oneVectorFromEnd); + lessThanMask |= ((Vector)negativeMask & equalMask) | (~(Vector)IsNegative(result) & equalMask & lessThanIndexMask); + } - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - int lastVectorIndex = x.Length - Vector.Count; - AsVector(ref dRef, lastVectorIndex) = op.Invoke(AsVector(ref xRef, lastVectorIndex), - AsVector(ref yRef, lastVectorIndex), - zVec); - } + result = Vector.ConditionalSelect(lessThanMask, result, current); - return; - } + resultIndex = Vector.ConditionalSelect(lessThanMask, resultIndex, curIndex); } + } - // Loop handling one element at a time. - while (i < x.Length) - { - Unsafe.Add(ref dRef, i) = op.Invoke(Unsafe.Add(ref xRef, i), - Unsafe.Add(ref yRef, i), - z); + /// MathF.Max(x, y) (but without guaranteed NaN propagation) + private readonly struct MaxOperator : IBinaryOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Invoke(float x, float y) => + x == y ? + (IsNegative(x) ? y : x) : + (y > x ? y : x); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector Invoke(Vector x, Vector y) => + Vector.ConditionalSelect(Vector.Equals(x, y), + Vector.ConditionalSelect(IsNegative(x), y, x), + Vector.Max(x, y)); + } - i++; - } + /// MathF.Max(x, y) + private readonly struct MaxPropagateNaNOperator : IBinaryOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Invoke(float x, float y) => MathF.Max(x, y); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector Invoke(Vector x, Vector y) => + Vector.ConditionalSelect(Vector.Equals(x, x), + Vector.ConditionalSelect(Vector.Equals(y, y), + Vector.ConditionalSelect(Vector.Equals(x, y), + Vector.ConditionalSelect(IsNegative(x), y, x), + Vector.Max(x, y)), + y), + x); } - private static void InvokeSpanScalarSpanIntoSpan( - ReadOnlySpan x, float y, ReadOnlySpan z, Span destination, TTernaryOperator op = default) - where TTernaryOperator : struct, ITernaryOperator + /// Operator to get x or y based on which has the larger MathF.Abs (but NaNs may not be propagated) + private readonly struct MaxMagnitudeOperator : IBinaryOperator { - if (x.Length != z.Length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Invoke(float x, float y) { - ThrowHelper.ThrowArgument_SpansMustHaveSameLength(); + float xMag = MathF.Abs(x), yMag = MathF.Abs(y); + return + yMag == xMag ? + (IsNegative(x) ? y : x) : + (xMag > yMag ? x : y); } - if (x.Length > destination.Length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector Invoke(Vector x, Vector y) { - ThrowHelper.ThrowArgument_DestinationTooShort(); + Vector xMag = Vector.Abs(x), yMag = Vector.Abs(y); + return + Vector.ConditionalSelect(Vector.Equals(xMag, yMag), + Vector.ConditionalSelect(IsNegative(x), y, x), + Vector.ConditionalSelect(Vector.GreaterThan(xMag, yMag), x, y)); } + } - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float zRef = ref MemoryMarshal.GetReference(z); - ref float dRef = ref MemoryMarshal.GetReference(destination); - int i = 0, oneVectorFromEnd; - - if (Vector.IsHardwareAccelerated) + /// Operator to get x or y based on which has the larger MathF.Abs + private readonly struct MaxMagnitudePropagateNaNOperator : IBinaryOperator + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Invoke(float x, float y) { - oneVectorFromEnd = x.Length - Vector.Count; - if (oneVectorFromEnd >= 0) - { - Vector yVec = new(y); - - // Loop handling one vector at a time. - do - { - AsVector(ref dRef, i) = op.Invoke(AsVector(ref xRef, i), - yVec, - AsVector(ref zRef, i)); - - i += Vector.Count; - } - while (i <= oneVectorFromEnd); - - // Handle any remaining elements with a final vector. - if (i != x.Length) - { - int lastVectorIndex = x.Length - Vector.Count; - AsVector(ref dRef, lastVectorIndex) = op.Invoke(AsVector(ref xRef, lastVectorIndex), - yVec, - AsVector(ref zRef, lastVectorIndex)); - } - - return; - } + float xMag = MathF.Abs(x), yMag = MathF.Abs(y); + return xMag > yMag || float.IsNaN(xMag) || (xMag == yMag && !IsNegative(x)) ? x : y; } - // Loop handling one element at a time. - while (i < x.Length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector Invoke(Vector x, Vector y) { - Unsafe.Add(ref dRef, i) = op.Invoke(Unsafe.Add(ref xRef, i), - y, - Unsafe.Add(ref zRef, i)); - - i++; + Vector xMag = Vector.Abs(x), yMag = Vector.Abs(y); + return + Vector.ConditionalSelect(Vector.Equals(x, x), + Vector.ConditionalSelect(Vector.Equals(y, y), + Vector.ConditionalSelect(Vector.Equals(xMag, yMag), + Vector.ConditionalSelect(IsNegative(x), y, x), + Vector.ConditionalSelect(Vector.GreaterThan(xMag, yMag), x, y)), + y), + x); } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ref Vector AsVector(ref float start, int offset) => - ref Unsafe.As>( - ref Unsafe.Add(ref start, offset)); - - private readonly struct AddOperator : IBinaryOperator + /// MathF.Min(x, y) (but NaNs may not be propagated) + private readonly struct MinOperator : IBinaryOperator { - public float Invoke(float x, float y) => x + y; - public Vector Invoke(Vector x, Vector y) => x + y; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Invoke(float x, float y) => + x == y ? + (IsNegative(y) ? y : x) : + (y < x ? y : x); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector Invoke(Vector x, Vector y) => + Vector.ConditionalSelect(Vector.Equals(x, y), + Vector.ConditionalSelect(IsNegative(y), y, x), + Vector.Min(x, y)); } - private readonly struct SubtractOperator : IBinaryOperator + /// MathF.Min(x, y) + private readonly struct MinPropagateNaNOperator : IBinaryOperator { - public float Invoke(float x, float y) => x - y; - public Vector Invoke(Vector x, Vector y) => x - y; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Invoke(float x, float y) => MathF.Min(x, y); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector Invoke(Vector x, Vector y) => + Vector.ConditionalSelect(Vector.Equals(x, x), + Vector.ConditionalSelect(Vector.Equals(y, y), + Vector.ConditionalSelect(Vector.Equals(x, y), + Vector.ConditionalSelect(IsNegative(x), x, y), + Vector.Min(x, y)), + y), + x); } - private readonly struct SubtractSquaredOperator : IBinaryOperator + /// Operator to get x or y based on which has the smaller MathF.Abs (but NaNs may not be propagated) + private readonly struct MinMagnitudeOperator : IBinaryOperator { + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Invoke(float x, float y) { - float tmp = x - y; - return tmp * tmp; + float xMag = MathF.Abs(x), yMag = MathF.Abs(y); + return + yMag == xMag ? + (IsNegative(y) ? y : x) : + (yMag < xMag ? y : x); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector Invoke(Vector x, Vector y) { - Vector tmp = x - y; - return tmp * tmp; + Vector xMag = Vector.Abs(x), yMag = Vector.Abs(y); + return + Vector.ConditionalSelect(Vector.Equals(yMag, xMag), + Vector.ConditionalSelect(IsNegative(y), y, x), + Vector.ConditionalSelect(Vector.LessThan(yMag, xMag), y, x)); } } - private readonly struct MultiplyOperator : IBinaryOperator + /// Operator to get x or y based on which has the smaller MathF.Abs + private readonly struct MinMagnitudePropagateNaNOperator : IBinaryOperator { - public float Invoke(float x, float y) => x * y; - public Vector Invoke(Vector x, Vector y) => x * y; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Invoke(float x, float y) + { + float xMag = MathF.Abs(x), yMag = MathF.Abs(y); + return xMag < yMag || float.IsNaN(xMag) || (xMag == yMag && IsNegative(x)) ? x : y; + } - private readonly struct DivideOperator : IBinaryOperator - { - public float Invoke(float x, float y) => x / y; - public Vector Invoke(Vector x, Vector y) => x / y; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector Invoke(Vector x, Vector y) + { + Vector xMag = Vector.Abs(x), yMag = Vector.Abs(y); + + return + Vector.ConditionalSelect(Vector.Equals(x, x), + Vector.ConditionalSelect(Vector.Equals(y, y), + Vector.ConditionalSelect(Vector.Equals(yMag, xMag), + Vector.ConditionalSelect(IsNegative(x), x, y), + Vector.ConditionalSelect(Vector.LessThan(xMag, yMag), x, y)), + y), + x); + } } + /// -x private readonly struct NegateOperator : IUnaryOperator { + public bool CanVectorize => true; public float Invoke(float x) => -x; public Vector Invoke(Vector x) => -x; } + /// (x + y) * z private readonly struct AddMultiplyOperator : ITernaryOperator { public float Invoke(float x, float y, float z) => (x + y) * z; public Vector Invoke(Vector x, Vector y, Vector z) => (x + y) * z; } + /// (x * y) + z private readonly struct MultiplyAddOperator : ITernaryOperator { public float Invoke(float x, float y, float z) => (x * y) + z; public Vector Invoke(Vector x, Vector y, Vector z) => (x * y) + z; } + /// x private readonly struct IdentityOperator : IUnaryOperator { + public bool CanVectorize => true; public float Invoke(float x) => x; public Vector Invoke(Vector x) => x; } + /// x * x private readonly struct SquaredOperator : IUnaryOperator { + public bool CanVectorize => true; public float Invoke(float x) => x * x; public Vector Invoke(Vector x) => x * x; } + /// MathF.Abs(x) private readonly struct AbsoluteOperator : IUnaryOperator { + public bool CanVectorize => true; public float Invoke(float x) => MathF.Abs(x); + public Vector Invoke(Vector x) => Vector.Abs(x); + } - public Vector Invoke(Vector x) - { - Vector raw = Vector.AsVectorUInt32(x); - Vector mask = new Vector(0x7FFFFFFF); - return Vector.AsVectorSingle(raw & mask); - } + /// MathF.Exp(x) + private readonly struct ExpOperator : IUnaryOperator + { + public bool CanVectorize => false; + public float Invoke(float x) => MathF.Exp(x); + public Vector Invoke(Vector x) => + // requires ShiftLeft (.NET 7+) + throw new NotImplementedException(); + } + + /// MathF.Sinh(x) + private readonly struct SinhOperator : IUnaryOperator + { + public bool CanVectorize => false; + public float Invoke(float x) => MathF.Sinh(x); + public Vector Invoke(Vector x) => + // requires ShiftLeft (.NET 7+) + throw new NotImplementedException(); + } + + /// MathF.Cosh(x) + private readonly struct CoshOperator : IUnaryOperator + { + public bool CanVectorize => false; + public float Invoke(float x) => MathF.Cosh(x); + public Vector Invoke(Vector x) => + // requires ShiftLeft (.NET 7+) + throw new NotImplementedException(); + } + + /// MathF.Tanh(x) + private readonly struct TanhOperator : IUnaryOperator + { + public bool CanVectorize => false; + public float Invoke(float x) => MathF.Tanh(x); + public Vector Invoke(Vector x) => + // requires ShiftLeft (.NET 7+) + throw new NotImplementedException(); + } + + /// MathF.Log(x) + private readonly struct LogOperator : IUnaryOperator + { + public bool CanVectorize => false; + public float Invoke(float x) => MathF.Log(x); + public Vector Invoke(Vector x) => + // requires ShiftRightArithmetic (.NET 7+) + throw new NotImplementedException(); + } + + /// MathF.Log2(x) + private readonly struct Log2Operator : IUnaryOperator + { + public bool CanVectorize => false; + public float Invoke(float x) => Log2(x); + public Vector Invoke(Vector x) => + // requires ShiftRightArithmetic (.NET 7+) + throw new NotImplementedException(); + } + + /// 1f / (1f + MathF.Exp(-x)) + private readonly struct SigmoidOperator : IUnaryOperator + { + public bool CanVectorize => false; + public float Invoke(float x) => 1.0f / (1.0f + MathF.Exp(-x)); + public Vector Invoke(Vector x) => + // requires ShiftRightArithmetic (.NET 7+) + throw new NotImplementedException(); } + /// Operator that takes one input value and returns a single value. private interface IUnaryOperator { + bool CanVectorize { get; } float Invoke(float x); Vector Invoke(Vector x); } + /// Operator that takes two input values and returns a single value. private interface IBinaryOperator { float Invoke(float x, float y); Vector Invoke(Vector x, Vector y); } + /// that specializes horizontal aggregation of all elements in a vector. + private interface IAggregationOperator : IBinaryOperator + { + float IdentityValue { get; } + } + + /// Operator that takes three input values and returns a single value. private interface ITernaryOperator { float Invoke(float x, float y, float z); diff --git a/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs b/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs index 902b27787e856c..272991aed44ab8 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs @@ -18,5 +18,9 @@ public static void ThrowArgument_SpansMustHaveSameLength() => [DoesNotReturn] public static void ThrowArgument_SpansMustBeNonEmpty() => throw new ArgumentException(SR.Argument_SpansMustBeNonEmpty); + + [DoesNotReturn] + public static void ThrowArgument_InputAndDestinationSpanMustNotOverlap() => + throw new ArgumentException(SR.Argument_InputAndDestinationSpanMustNotOverlap, "destination"); } } diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.cs index 777ab49609856e..09aa13ae35800f 100644 --- a/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.cs +++ b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Runtime.InteropServices; using Xunit; +using Xunit.Sdk; #pragma warning disable xUnit1025 // reporting duplicate test cases due to not distinguishing 0.0 from -0.0 @@ -13,15 +14,25 @@ namespace System.Numerics.Tensors.Tests { public static partial class TensorPrimitivesTests { - private const double Tolerance = 0.0001; - + #region Test Utilities public static IEnumerable TensorLengthsIncluding0 => TensorLengths.Concat(new object[][] { [0] }); public static IEnumerable TensorLengths => - from length in Enumerable.Range(1, 128) + from length in Enumerable.Range(1, 256) select new object[] { length }; + public static IEnumerable VectorLengthAndIteratedRange(float min, float max, float increment) + { + foreach (int length in new[] { 4, 8, 16 }) + { + for (float f = min; f <= max; f += increment) + { + yield return new object[] { length, f }; + } + } + } + private static readonly Random s_random = new Random(20230828); private static BoundedMemory CreateTensor(int size) => BoundedMemory.Allocate(size); @@ -41,300 +52,300 @@ private static void FillTensor(Span tensor) } } - private static float NextSingle() - { + private static float NextSingle() => // For testing purposes, get a mix of negative and positive values. - return (float)((s_random.NextDouble() * 2) - 1); - } + (float)((s_random.NextDouble() * 2) - 1); - [Theory] - [MemberData(nameof(TensorLengthsIncluding0))] - public static void AddTwoTensors(int tensorLength) + private static void AssertEqualTolerance(double expected, double actual, double tolerance = 0.00001f) { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength); - - TensorPrimitives.Add(x, y, destination); - - for (int i = 0; i < tensorLength; i++) + double diff = Math.Abs(expected - actual); + if (diff > tolerance && + diff > Math.Max(Math.Abs(expected), Math.Abs(actual)) * tolerance) { - Assert.Equal(x[i] + y[i], destination[i]); + throw new EqualException(expected, actual); } } - [Theory] - [MemberData(nameof(TensorLengths))] - public static void AddTwoTensors_ThrowsForMismatchedLengths(int tensorLength) + private static unsafe float MathFMaxMagnitude(float x, float y) { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); - using BoundedMemory destination = CreateTensor(tensorLength); - - Assert.Throws(() => TensorPrimitives.Add(x, y, destination)); + float ax = MathF.Abs(x), ay = MathF.Abs(y); + return (ax > ay) || float.IsNaN(ax) || (ax == ay && *(int*)&x >= 0) ? x : y; } - [Theory] - [MemberData(nameof(TensorLengths))] - public static void AddTwoTensors_ThrowsForTooShortDestination(int tensorLength) + private static unsafe float MathFMinMagnitude(float x, float y) { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); - - AssertExtensions.Throws("destination", () => TensorPrimitives.Add(x, y, destination)); + float ax = MathF.Abs(x), ay = MathF.Abs(y); + return (ax < ay) || float.IsNaN(ax) || (ax == ay && *(int*)&x < 0) ? x : y; } - [Theory] - [MemberData(nameof(TensorLengthsIncluding0))] - public static void AddTensorAndScalar(int tensorLength) + private static unsafe float UInt32ToSingle(uint i) => *(float*)&i; + + private static unsafe float SingleToUInt32(float f) => *(uint*)&f; + + /// Gets a variety of special values (e.g. NaN). + private static IEnumerable GetSpecialValues() { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - float y = NextSingle(); - using BoundedMemory destination = CreateTensor(tensorLength); + // NaN + yield return UInt32ToSingle(0xFFC0_0000); // -qNaN / float.NaN + yield return UInt32ToSingle(0xFFFF_FFFF); // -qNaN / all-bits-set + yield return UInt32ToSingle(0x7FC0_0000); // +qNaN + yield return UInt32ToSingle(0xFFA0_0000); // -sNaN + yield return UInt32ToSingle(0x7FA0_0000); // +sNaN - TensorPrimitives.Add(x, y, destination); + // +Infinity, -Infinity + yield return float.PositiveInfinity; + yield return float.NegativeInfinity; - for (int i = 0; i < tensorLength; i++) - { - Assert.Equal(x[i] + y, destination[i]); - } - } + // +Zero, -Zero + yield return +0.0f; + yield return -0.0f; - [Theory] - [MemberData(nameof(TensorLengths))] - public static void AddTensorAndScalar_ThrowsForTooShortDestination(int tensorLength) - { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - float y = NextSingle(); - using BoundedMemory destination = CreateTensor(tensorLength - 1); + // Subnormals + yield return +float.Epsilon; + yield return -float.Epsilon; + yield return UInt32ToSingle(0x007F_FFFF); + yield return UInt32ToSingle(0x807F_FFFF); - AssertExtensions.Throws("destination", () => TensorPrimitives.Add(x, y, destination)); + // Normals + yield return UInt32ToSingle(0x0080_0000); + yield return UInt32ToSingle(0x8080_0000); + yield return UInt32ToSingle(0x7F7F_FFFF); // MaxValue + yield return UInt32ToSingle(0xFF7F_FFFF); // MinValue } - [Theory] - [MemberData(nameof(TensorLengthsIncluding0))] - public static void SubtractTwoTensors(int tensorLength) + /// + /// Runs the specified action for each special value. Before the action is invoked, + /// the value is stored into a random position in , and the original + /// value is subsequently restored. + /// + private static void RunForEachSpecialValue(Action action, BoundedMemory x) { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength); + foreach (float value in GetSpecialValues()) + { + int pos = s_random.Next(x.Length); + float orig = x[pos]; + x[pos] = value; - TensorPrimitives.Subtract(x, y, destination); + action(); - for (int i = 0; i < tensorLength; i++) - { - Assert.Equal(x[i] - y[i], destination[i]); + x[pos] = orig; } } - [Theory] - [MemberData(nameof(TensorLengths))] - public static void SubtractTwoTensors_ThrowsForMismatchedLengths(int tensorLength) + /// + /// Loads a variety of special values (e.g. NaN) into random positions in + /// and related values into the corresponding positions in . + /// + private static void SetSpecialValues(Span x, Span y) { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); - using BoundedMemory destination = CreateTensor(tensorLength); + int pos; - Assert.Throws(() => TensorPrimitives.Subtract(x, y, destination)); - } + // NaNs + pos = s_random.Next(x.Length); + x[pos] = float.NaN; + y[pos] = UInt32ToSingle(0x7FC0_0000); - [Theory] - [MemberData(nameof(TensorLengths))] - public static void SubtractTwoTensors_ThrowsForTooShortDestination(int tensorLength) - { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); + // +Infinity, -Infinity + pos = s_random.Next(x.Length); + x[pos] = float.PositiveInfinity; + y[pos] = float.NegativeInfinity; - AssertExtensions.Throws("destination", () => TensorPrimitives.Subtract(x, y, destination)); + // +Zero, -Zero + pos = s_random.Next(x.Length); + x[pos] = +0.0f; + y[pos] = -0.0f; + + // +Epsilon, -Epsilon + pos = s_random.Next(x.Length); + x[pos] = +float.Epsilon; + y[pos] = -float.Epsilon; + + // Same magnitude, opposite sign + pos = s_random.Next(x.Length); + x[pos] = +5.0f; + y[pos] = -5.0f; } + #endregion + #region Abs [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void SubtractTensorAndScalar(int tensorLength) + public static void Abs(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - float y = NextSingle(); using BoundedMemory destination = CreateTensor(tensorLength); - TensorPrimitives.Subtract(x, y, destination); + TensorPrimitives.Abs(x, destination); - for (int i = 0; i < tensorLength; i++) + for (int i = 0; i < x.Length; i++) { - Assert.Equal(x[i] - y, destination[i]); + AssertEqualTolerance(MathF.Abs(x[i]), destination[i]); } } - [Theory] - [MemberData(nameof(TensorLengths))] - public static void SubtractTensorAndScalar_ThrowsForTooShortDestination(int tensorLength) - { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - float y = NextSingle(); - using BoundedMemory destination = CreateTensor(tensorLength - 1); - - AssertExtensions.Throws("destination", () => TensorPrimitives.Subtract(x, y, destination)); - } - [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void MultiplyTwoTensors(int tensorLength) + public static void Abs_InPlace(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); - TensorPrimitives.Multiply(x, y, destination); + TensorPrimitives.Abs(x, x); - for (int i = 0; i < tensorLength; i++) + for (int i = 0; i < x.Length; i++) { - Assert.Equal(x[i] * y[i], destination[i]); + AssertEqualTolerance(MathF.Abs(xOrig[i]), x[i]); } } [Theory] [MemberData(nameof(TensorLengths))] - public static void MultiplyTwoTensors_ThrowsForMismatchedLengths(int tensorLength) + public static void Abs_ThrowsForTooShortDestination(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); - using BoundedMemory destination = CreateTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); - Assert.Throws(() => TensorPrimitives.Multiply(x, y, destination)); + AssertExtensions.Throws("destination", () => TensorPrimitives.Abs(x, destination)); } - [Theory] - [MemberData(nameof(TensorLengths))] - public static void MultiplyTwoTensors_ThrowsForTooShortDestination(int tensorLength) + [Fact] + public static void Abs_ThrowsForOverlapppingInputsWithOutputs() { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); - - AssertExtensions.Throws("destination", () => TensorPrimitives.Multiply(x, y, destination)); + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Abs(array.AsSpan(1, 5), array.AsSpan(0, 5))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Abs(array.AsSpan(1, 5), array.AsSpan(2, 5))); } + #endregion + #region Add [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void MultiplyTensorAndScalar(int tensorLength) + public static void Add_TwoTensors(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - float y = NextSingle(); + using BoundedMemory y = CreateAndFillTensor(tensorLength); using BoundedMemory destination = CreateTensor(tensorLength); - TensorPrimitives.Multiply(x, y, destination); - + TensorPrimitives.Add(x, y, destination); for (int i = 0; i < tensorLength; i++) { - Assert.Equal(x[i] * y, destination[i]); + AssertEqualTolerance(x[i] + y[i], destination[i]); } - } - [Theory] - [MemberData(nameof(TensorLengths))] - public static void MultiplyTensorAndScalar_ThrowsForTooShortDestination(int tensorLength) - { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - float y = NextSingle(); - using BoundedMemory destination = CreateTensor(tensorLength - 1); + float[] xOrig = x.Span.ToArray(); - AssertExtensions.Throws("destination", () => TensorPrimitives.Multiply(x, y, destination)); + // Validate that the destination can be the same as an input. + TensorPrimitives.Add(x, x, x); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(xOrig[i] + xOrig[i], x[i]); + } } [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void DivideTwoTensors(int tensorLength) + public static void Add_TwoTensors_InPlace(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); - TensorPrimitives.Divide(x, y, destination); + TensorPrimitives.Add(x, x, x); for (int i = 0; i < tensorLength; i++) { - Assert.Equal(x[i] / y[i], destination[i]); + AssertEqualTolerance(xOrig[i] + xOrig[i], x[i]); } } [Theory] [MemberData(nameof(TensorLengths))] - public static void DivideTwoTensors_ThrowsForMismatchedLengths(int tensorLength) + public static void Add_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); using BoundedMemory destination = CreateTensor(tensorLength); - Assert.Throws(() => TensorPrimitives.Divide(x, y, destination)); + Assert.Throws(() => TensorPrimitives.Add(x, y, destination)); + Assert.Throws(() => TensorPrimitives.Add(y, x, destination)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void DivideTwoTensors_ThrowsForTooShortDestination(int tensorLength) + public static void Add_TwoTensors_ThrowsForTooShortDestination(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); using BoundedMemory y = CreateAndFillTensor(tensorLength); using BoundedMemory destination = CreateTensor(tensorLength - 1); - AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(x, y, destination)); + AssertExtensions.Throws("destination", () => TensorPrimitives.Add(x, y, destination)); + } + + [Fact] + public static void Add_TwoTensors_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Add(array.AsSpan(1, 2), array.AsSpan(5, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Add(array.AsSpan(1, 2), array.AsSpan(5, 2), array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Add(array.AsSpan(1, 2), array.AsSpan(5, 2), array.AsSpan(4, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Add(array.AsSpan(1, 2), array.AsSpan(5, 2), array.AsSpan(6, 2))); } [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void DivideTensorAndScalar(int tensorLength) + public static void Add_TensorScalar(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); float y = NextSingle(); using BoundedMemory destination = CreateTensor(tensorLength); - TensorPrimitives.Divide(x, y, destination); + TensorPrimitives.Add(x, y, destination); for (int i = 0; i < tensorLength; i++) { - Assert.Equal(x[i] / y, destination[i]); + AssertEqualTolerance(x[i] + y, destination[i]); } } - [Theory] - [MemberData(nameof(TensorLengths))] - public static void DivideTensorAndScalar_ThrowsForTooShortDestination(int tensorLength) - { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - float y = NextSingle(); - using BoundedMemory destination = CreateTensor(tensorLength - 1); - - AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(x, y, destination)); - } - [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void NegateTensor(int tensorLength) + public static void Add_TensorScalar_InPlace(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + float y = NextSingle(); - TensorPrimitives.Negate(x, destination); + TensorPrimitives.Add(x, y, x); for (int i = 0; i < tensorLength; i++) { - Assert.Equal(-x[i], destination[i]); + AssertEqualTolerance(xOrig[i] + y, x[i]); } } [Theory] [MemberData(nameof(TensorLengths))] - public static void NegateTensor_ThrowsForTooShortDestination(int tensorLength) + public static void Add_TensorScalar_ThrowsForTooShortDestination(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); using BoundedMemory destination = CreateTensor(tensorLength - 1); - AssertExtensions.Throws("destination", () => TensorPrimitives.Negate(x, destination)); + AssertExtensions.Throws("destination", () => TensorPrimitives.Add(x, y, destination)); + } + + [Fact] + public static void Add_TensorScalar_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Add(array.AsSpan(1, 2), 42, array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Add(array.AsSpan(1, 2), 42, array.AsSpan(2, 2))); } + #endregion + #region AddMultiply [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void AddTwoTensorsAndMultiplyWithThirdTensor(int tensorLength) + public static void AddMultiply_ThreeTensors(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); using BoundedMemory y = CreateAndFillTensor(tensorLength); @@ -345,37 +356,42 @@ public static void AddTwoTensorsAndMultiplyWithThirdTensor(int tensorLength) for (int i = 0; i < tensorLength; i++) { - Assert.Equal((x[i] + y[i]) * multiplier[i], destination[i]); + AssertEqualTolerance((x[i] + y[i]) * multiplier[i], destination[i]); } } [Theory] - [MemberData(nameof(TensorLengths))] - public static void AddTwoTensorsAndMultiplyWithThirdTensor_ThrowsForMismatchedLengths_x_y(int tensorLength) + [MemberData(nameof(TensorLengthsIncluding0))] + public static void AddMultiply_ThreeTensors_InPlace(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); - using BoundedMemory multiplier = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); - Assert.Throws(() => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); + TensorPrimitives.AddMultiply(x, x, x, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance((xOrig[i] + xOrig[i]) * xOrig[i], x[i]); + } } [Theory] [MemberData(nameof(TensorLengths))] - public static void AddTwoTensorsAndMultiplyWithThirdTensor_ThrowsForMismatchedLengths_x_multiplier(int tensorLength) + public static void AddMultiply_ThreeTensors_ThrowsForMismatchedLengths(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); using BoundedMemory y = CreateAndFillTensor(tensorLength); - using BoundedMemory multiplier = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory z = CreateAndFillTensor(tensorLength - 1); using BoundedMemory destination = CreateTensor(tensorLength); - Assert.Throws(() => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); + Assert.Throws(() => TensorPrimitives.AddMultiply(x, y, z, destination)); + Assert.Throws(() => TensorPrimitives.AddMultiply(x, z, y, destination)); + Assert.Throws(() => TensorPrimitives.AddMultiply(z, x, y, destination)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void AddTwoTensorsAndMultiplyWithThirdTensor_ThrowsForTooShortDestination(int tensorLength) + public static void AddMultiply_ThreeTensors_ThrowsForTooShortDestination(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); using BoundedMemory y = CreateAndFillTensor(tensorLength); @@ -385,9 +401,21 @@ public static void AddTwoTensorsAndMultiplyWithThirdTensor_ThrowsForTooShortDest AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); } + [Fact] + public static void AddMultiply_ThreeTensors_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(7, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(7, 2), array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(7, 2), array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(7, 2), array.AsSpan(5, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(7, 2), array.AsSpan(6, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(7, 2), array.AsSpan(8, 2))); + } + [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void AddTwoTensorsAndMultiplyWithScalar(int tensorLength) + public static void AddMultiply_TensorTensorScalar(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); using BoundedMemory y = CreateAndFillTensor(tensorLength); @@ -398,13 +426,29 @@ public static void AddTwoTensorsAndMultiplyWithScalar(int tensorLength) for (int i = 0; i < tensorLength; i++) { - Assert.Equal((x[i] + y[i]) * multiplier, destination[i]); + AssertEqualTolerance((x[i] + y[i]) * multiplier, destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void AddMultiply_TensorTensorScalar_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + float multiplier = NextSingle(); + + TensorPrimitives.AddMultiply(x, x, multiplier, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance((xOrig[i] + xOrig[i]) * multiplier, x[i]); } } [Theory] [MemberData(nameof(TensorLengths))] - public static void AddTwoTensorsAndMultiplyWithScalar_ThrowsForMismatchedLengths_x_y(int tensorLength) + public static void AddMultiply_TensorTensorScalar_ThrowsForMismatchedLengths_x_y(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); @@ -412,11 +456,12 @@ public static void AddTwoTensorsAndMultiplyWithScalar_ThrowsForMismatchedLengths using BoundedMemory destination = CreateTensor(tensorLength); Assert.Throws(() => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); + Assert.Throws(() => TensorPrimitives.AddMultiply(y, x, multiplier, destination)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void AddTwoTensorsAndMultiplyWithScalar_ThrowsForTooShortDestination(int tensorLength) + public static void AddMultiply_TensorTensorScalar_ThrowsForTooShortDestination(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); using BoundedMemory y = CreateAndFillTensor(tensorLength); @@ -426,9 +471,19 @@ public static void AddTwoTensorsAndMultiplyWithScalar_ThrowsForTooShortDestinati AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); } + [Fact] + public static void AddMultiply_TensorTensorScalar_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), array.AsSpan(4, 2), 42, array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), array.AsSpan(4, 2), 42, array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), array.AsSpan(4, 2), 42, array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), array.AsSpan(4, 2), 42, array.AsSpan(5, 2))); + } + [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void AddTensorAndScalarAndMultiplyWithTensor(int tensorLength) + public static void AddMultiply_TensorScalarTensor(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); float y = NextSingle(); @@ -439,25 +494,42 @@ public static void AddTensorAndScalarAndMultiplyWithTensor(int tensorLength) for (int i = 0; i < tensorLength; i++) { - Assert.Equal((x[i] + y) * multiplier[i], destination[i]); + AssertEqualTolerance((x[i] + y) * multiplier[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void AddMultiply_TensorScalarTensor_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + float y = NextSingle(); + + TensorPrimitives.AddMultiply(x, y, x, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance((xOrig[i] + y) * xOrig[i], x[i]); } } [Theory] [MemberData(nameof(TensorLengths))] - public static void AddTensorAndScalarAndMultiplyWithTensor_ThrowsForMismatchedLengths_x_z(int tensorLength) + public static void AddMultiply_TensorScalarTensor_ThrowsForMismatchedLengths_x_z(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); float y = NextSingle(); - using BoundedMemory multiplier = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory z = CreateAndFillTensor(tensorLength - 1); using BoundedMemory destination = CreateTensor(tensorLength); - Assert.Throws(() => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); + Assert.Throws(() => TensorPrimitives.AddMultiply(x, y, z, destination)); + Assert.Throws(() => TensorPrimitives.AddMultiply(z, y, x, destination)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void AddTensorAndScalarAndMultiplyWithTensor_ThrowsForTooShortDestination(int tensorLength) + public static void AddMultiply_TensorScalarTensor_ThrowsForTooShortDestination(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); float y = NextSingle(); @@ -467,355 +539,315 @@ public static void AddTensorAndScalarAndMultiplyWithTensor_ThrowsForTooShortDest AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(x, y, multiplier, destination)); } + [Fact] + public static void AddMultiply_TensorScalarTensor_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), 42, array.AsSpan(4, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), 42, array.AsSpan(4, 2), array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), 42, array.AsSpan(4, 2), array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.AddMultiply(array.AsSpan(1, 2), 42, array.AsSpan(4, 2), array.AsSpan(5, 2))); + } + #endregion + + #region Cosh [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void MultiplyTwoTensorsAndAddWithThirdTensor(int tensorLength) + public static void Cosh(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - using BoundedMemory addend = CreateAndFillTensor(tensorLength); using BoundedMemory destination = CreateTensor(tensorLength); - TensorPrimitives.MultiplyAdd(x, y, addend, destination); + TensorPrimitives.Cosh(x, destination); for (int i = 0; i < tensorLength; i++) { - Assert.Equal((x[i] * y[i]) + addend[i], destination[i]); + AssertEqualTolerance(MathF.Cosh(x[i]), destination[i]); } } [Theory] - [MemberData(nameof(TensorLengths))] - public static void MultiplyTwoTensorsAndAddWithThirdTensor_ThrowsForMismatchedLengths_x_y(int tensorLength) + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Cosh_InPlace(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); - using BoundedMemory addend = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength); - - Assert.Throws(() => TensorPrimitives.MultiplyAdd(x, y, addend, destination)); - } + float[] xOrig = x.Span.ToArray(); - [Theory] - [MemberData(nameof(TensorLengths))] - public static void MultiplyTwoTensorsAndAddWithThirdTensor_ThrowsForMismatchedLengths_x_multiplier(int tensorLength) - { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - using BoundedMemory addend = CreateAndFillTensor(tensorLength - 1); - using BoundedMemory destination = CreateTensor(tensorLength); + TensorPrimitives.Cosh(x, x); - Assert.Throws(() => TensorPrimitives.MultiplyAdd(x, y, addend, destination)); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Cosh(xOrig[i]), x[i]); + } } [Theory] [MemberData(nameof(TensorLengths))] - public static void MultiplyTwoTensorsAndAddWithThirdTensor_ThrowsForTooShortDestination(int tensorLength) + public static void Cosh_SpecialValues(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - using BoundedMemory addend = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); - AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(x, y, addend, destination)); + RunForEachSpecialValue(() => + { + TensorPrimitives.Cosh(x, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Cosh(x[i]), destination[i]); + } + }, x); } [Theory] - [MemberData(nameof(TensorLengthsIncluding0))] - public static void MultiplyTwoTensorsAndAddWithScalar(int tensorLength) + [MemberData(nameof(VectorLengthAndIteratedRange), new object[] { -100f, 100f, 3f })] + public static void Cosh_ValueRange(int vectorLength, float element) { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - float addend = NextSingle(); - using BoundedMemory destination = CreateTensor(tensorLength); + float[] x = new float[vectorLength]; + float[] dest = new float[vectorLength]; - TensorPrimitives.MultiplyAdd(x, y, addend, destination); + x.AsSpan().Fill(element); + TensorPrimitives.Cosh(x, dest); - for (int i = 0; i < tensorLength; i++) + float expected = MathF.Cosh(element); + foreach (float actual in dest) { - Assert.Equal((x[i] * y[i]) + addend, destination[i]); + AssertEqualTolerance(expected, actual); } } [Theory] [MemberData(nameof(TensorLengths))] - public static void MultiplyTwoTensorsAndAddWithScalar_ThrowsForTooShortDestination(int tensorLength) + public static void Cosh_ThrowsForTooShortDestination(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - float addend = NextSingle(); using BoundedMemory destination = CreateTensor(tensorLength - 1); - AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(x, y, addend, destination)); + AssertExtensions.Throws("destination", () => TensorPrimitives.Cosh(x, destination)); } + [Fact] + public static void Cosh_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Cosh(array.AsSpan(1, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Cosh(array.AsSpan(1, 2), array.AsSpan(2, 2))); + } + #endregion + + #region CosineSimilarity [Theory] - [MemberData(nameof(TensorLengthsIncluding0))] - public static void MultiplyTensorAndScalarAndAddWithTensor(int tensorLength) + [MemberData(nameof(TensorLengths))] + public static void CosineSimilarity_ThrowsForMismatchedLengths(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - float y = NextSingle(); - using BoundedMemory addend = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength); - - TensorPrimitives.MultiplyAdd(x, y, addend, destination); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); - for (int i = 0; i < tensorLength; i++) - { - Assert.Equal((x[i] * y) + addend[i], destination[i]); - } + Assert.Throws(() => TensorPrimitives.CosineSimilarity(x, y)); + Assert.Throws(() => TensorPrimitives.CosineSimilarity(y, x)); } - [Theory] - [MemberData(nameof(TensorLengths))] - public static void MultiplyTensorAndScalarAndAddWithTensor_ThrowsForTooShortDestination(int tensorLength) + [Fact] + public static void CosineSimilarity_ThrowsForEmpty() { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - float y = NextSingle(); - using BoundedMemory addend = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); - - AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(x, y, addend, destination)); + Assert.Throws(() => TensorPrimitives.CosineSimilarity(ReadOnlySpan.Empty, ReadOnlySpan.Empty)); + Assert.Throws(() => TensorPrimitives.CosineSimilarity(ReadOnlySpan.Empty, CreateTensor(1))); + Assert.Throws(() => TensorPrimitives.CosineSimilarity(CreateTensor(1), ReadOnlySpan.Empty)); } [Theory] - [MemberData(nameof(TensorLengthsIncluding0))] - public static void ExpTensor(int tensorLength) + [InlineData(new float[] { 3, 2, 0, 5 }, new float[] { 1, 0, 0, 0 }, 0.48666f)] + [InlineData(new float[] { 1, 1, 1, 1, 1, 0 }, new float[] { 1, 1, 1, 1, 0, 1 }, 0.80f)] + public static void CosineSimilarity_KnownValues(float[] x, float[] y, float expectedResult) { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength); - - TensorPrimitives.Exp(x, destination); - - for (int i = 0; i < tensorLength; i++) - { - Assert.Equal(MathF.Exp(x[i]), destination[i]); - } + AssertEqualTolerance(expectedResult, TensorPrimitives.CosineSimilarity(x, y)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void ExpTensor_ThrowsForTooShortDestination(int tensorLength) - { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); - - AssertExtensions.Throws("destination", () => TensorPrimitives.Exp(x, destination)); - } - - [Theory] - [MemberData(nameof(TensorLengthsIncluding0))] - public static void LogTensor(int tensorLength) + public static void CosineSimilarity(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength); - - TensorPrimitives.Log(x, destination); + using BoundedMemory y = CreateAndFillTensor(tensorLength); - for (int i = 0; i < tensorLength; i++) + float dot = 0f, squareX = 0f, squareY = 0f; + for (int i = 0; i < x.Length; i++) { - Assert.Equal(MathF.Log(x[i]), destination[i]); + dot += x[i] * y[i]; + squareX += x[i] * x[i]; + squareY += y[i] * y[i]; } - } - - [Theory] - [MemberData(nameof(TensorLengths))] - public static void LogTensor_ThrowsForTooShortDestination(int tensorLength) - { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); - AssertExtensions.Throws("destination", () => TensorPrimitives.Log(x, destination)); + AssertEqualTolerance(dot / (MathF.Sqrt(squareX) * MathF.Sqrt(squareY)), TensorPrimitives.CosineSimilarity(x, y)); } + #endregion - [Theory] - [MemberData(nameof(TensorLengthsIncluding0))] - public static void Log2(int tensorLength) + #region Distance + [Fact] + public static void Distance_ThrowsForEmpty() { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength); - - TensorPrimitives.Log2(x, destination); - - for (int i = 0; i < tensorLength; i++) - { - Assert.Equal(MathF.Log(x[i], 2), destination[i], Tolerance); - } + Assert.Throws(() => TensorPrimitives.Distance(ReadOnlySpan.Empty, ReadOnlySpan.Empty)); + Assert.Throws(() => TensorPrimitives.Distance(ReadOnlySpan.Empty, CreateTensor(1))); + Assert.Throws(() => TensorPrimitives.Distance(CreateTensor(1), ReadOnlySpan.Empty)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void Log2_ThrowsForTooShortDestination(int tensorLength) + public static void Distance_ThrowsForMismatchedLengths(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); - AssertExtensions.Throws("destination", () => TensorPrimitives.Log2(x, destination)); + Assert.Throws(() => TensorPrimitives.Distance(x, y)); + Assert.Throws(() => TensorPrimitives.Distance(y, x)); } [Theory] - [MemberData(nameof(TensorLengthsIncluding0))] - public static void CoshTensor(int tensorLength) + [InlineData(new float[] { 3, 2 }, new float[] { 4, 1 }, 1.4142f)] + [InlineData(new float[] { 0, 4 }, new float[] { 6, 2 }, 6.3245f)] + [InlineData(new float[] { 1, 2, 3 }, new float[] { 4, 5, 6 }, 5.19615f)] + [InlineData(new float[] { 5, 1, 6, 10 }, new float[] { 7, 2, 8, 4 }, 6.7082f)] + public static void Distance_KnownValues(float[] x, float[] y, float expectedResult) { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength); - - TensorPrimitives.Cosh(x, destination); - - for (int i = 0; i < tensorLength; i++) - { - Assert.Equal(MathF.Cosh(x[i]), destination[i]); - } + AssertEqualTolerance(expectedResult, TensorPrimitives.Distance(x, y)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void CoshTensor_ThrowsForTooShortDestination(int tensorLength) + public static void Distance(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); + using BoundedMemory y = CreateAndFillTensor(tensorLength); - AssertExtensions.Throws("destination", () => TensorPrimitives.Cosh(x, destination)); + float distance = 0f; + for (int i = 0; i < x.Length; i++) + { + distance += (x[i] - y[i]) * (x[i] - y[i]); + } + + AssertEqualTolerance(MathF.Sqrt(distance), TensorPrimitives.Distance(x, y)); } + #endregion + #region Divide [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void SinhTensor(int tensorLength) + public static void Divide_TwoTensors(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); using BoundedMemory destination = CreateTensor(tensorLength); - TensorPrimitives.Sinh(x, destination); + TensorPrimitives.Divide(x, y, destination); for (int i = 0; i < tensorLength; i++) { - Assert.Equal(MathF.Sinh(x[i]), destination[i]); + AssertEqualTolerance(x[i] / y[i], destination[i]); } } - [Theory] - [MemberData(nameof(TensorLengths))] - public static void SinhTensor_ThrowsForTooShortDestination(int tensorLength) - { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); - - AssertExtensions.Throws("destination", () => TensorPrimitives.Sinh(x, destination)); - } - [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void TanhTensor(int tensorLength) + public static void Divide_TwoTensors_InPlace(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); - TensorPrimitives.Tanh(x, destination); + TensorPrimitives.Divide(x, x, x); for (int i = 0; i < tensorLength; i++) { - Assert.Equal(MathF.Tanh(x[i]), destination[i]); + AssertEqualTolerance(xOrig[i] / xOrig[i], x[i]); } } [Theory] [MemberData(nameof(TensorLengths))] - public static void TanhTensor_ThrowsForTooShortDestination(int tensorLength) + public static void Divide_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); - AssertExtensions.Throws("destination", () => TensorPrimitives.Tanh(x, destination)); + Assert.Throws(() => TensorPrimitives.Divide(x, y, destination)); + Assert.Throws(() => TensorPrimitives.Divide(y, x, destination)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void CosineSimilarity_ThrowsForMismatchedLengths_x_y(int tensorLength) + public static void Divide_TwoTensors_ThrowsForTooShortDestination(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); - Assert.Throws(() => TensorPrimitives.CosineSimilarity(x, y)); + AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(x, y, destination)); } [Fact] - public static void CosineSimilarity_ThrowsForEmpty_x_y() - { - Assert.Throws(() => TensorPrimitives.CosineSimilarity(ReadOnlySpan.Empty, ReadOnlySpan.Empty)); - Assert.Throws(() => TensorPrimitives.CosineSimilarity(ReadOnlySpan.Empty, CreateTensor(1))); - Assert.Throws(() => TensorPrimitives.CosineSimilarity(CreateTensor(1), ReadOnlySpan.Empty)); - } - - [Theory] - [InlineData(new float[] { 3, 2, 0, 5 }, new float[] { 1, 0, 0, 0 }, 0.48666f)] - [InlineData(new float[] { 1, 1, 1, 1, 1, 0 }, new float[] { 1, 1, 1, 1, 0, 1 }, 0.80f)] - public static void CosineSimilarity_KnownValues(float[] x, float[] y, float expectedResult) + public static void Divide_TwoTensors_ThrowsForOverlapppingInputsWithOutputs() { - Assert.Equal(expectedResult, TensorPrimitives.CosineSimilarity(x, y), Tolerance); + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(5, 2))); } [Theory] - [MemberData(nameof(TensorLengths))] - public static void CosineSimilarity(int tensorLength) + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Divide_TensorScalar(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength); - float dot = 0f, squareX = 0f, squareY = 0f; - for (int i = 0; i < x.Length; i++) + TensorPrimitives.Divide(x, y, destination); + + for (int i = 0; i < tensorLength; i++) { - dot += x[i] * y[i]; - squareX += x[i] * x[i]; - squareY += y[i] * y[i]; + AssertEqualTolerance(x[i] / y, destination[i]); } - - Assert.Equal(dot / (Math.Sqrt(squareX) * Math.Sqrt(squareY)), TensorPrimitives.CosineSimilarity(x, y), Tolerance); - } - - [Fact] - public static void Distance_ThrowsForEmpty_x_y() - { - Assert.Throws(() => TensorPrimitives.Distance(ReadOnlySpan.Empty, ReadOnlySpan.Empty)); - Assert.Throws(() => TensorPrimitives.Distance(ReadOnlySpan.Empty, CreateTensor(1))); - Assert.Throws(() => TensorPrimitives.Distance(CreateTensor(1), ReadOnlySpan.Empty)); } [Theory] - [MemberData(nameof(TensorLengths))] - public static void Distance_ThrowsForMismatchedLengths_x_y(int tensorLength) + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Divide_TensorScalar_InPlace(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + float[] xOrig = x.Span.ToArray(); + float y = NextSingle(); - Assert.Throws(() => TensorPrimitives.Distance(x, y)); - } + TensorPrimitives.Divide(x, y, x); - [Theory] - [InlineData(new float[] { 3, 2 }, new float[] { 4, 1 }, 1.4142f)] - [InlineData(new float[] { 0, 4 }, new float[] { 6, 2 }, 6.3245f)] - [InlineData(new float[] { 1, 2, 3 }, new float[] { 4, 5, 6 }, 5.1961f)] - [InlineData(new float[] { 5, 1, 6, 10 }, new float[] { 7, 2, 8, 4 }, 6.7082f)] - public static void Distance_KnownValues(float[] x, float[] y, float expectedResult) - { - Assert.Equal(expectedResult, TensorPrimitives.Distance(x, y), Tolerance); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(xOrig[i] / y, x[i]); + } } [Theory] [MemberData(nameof(TensorLengths))] - public static void Distance(int tensorLength) + public static void Divide_TensorScalar_ThrowsForTooShortDestination(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength - 1); - float distance = 0f; - for (int i = 0; i < x.Length; i++) - { - distance += (x[i] - y[i]) * (x[i] - y[i]); - } + AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(x, y, destination)); + } - Assert.Equal(Math.Sqrt(distance), TensorPrimitives.Distance(x, y), Tolerance); + [Fact] + public static void Divide_TensorScalar_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Divide(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(5, 2))); } + #endregion + #region Dot [Theory] [MemberData(nameof(TensorLengths))] public static void Dot_ThrowsForMismatchedLengths_x_y(int tensorLength) @@ -824,6 +856,7 @@ public static void Dot_ThrowsForMismatchedLengths_x_y(int tensorLength) using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); Assert.Throws(() => TensorPrimitives.Dot(x, y)); + Assert.Throws(() => TensorPrimitives.Dot(y, x)); } [Theory] @@ -833,7 +866,7 @@ public static void Dot_ThrowsForMismatchedLengths_x_y(int tensorLength) [InlineData(new float[] { }, new float[] { }, 0)] public static void Dot_KnownValues(float[] x, float[] y, float expectedResult) { - Assert.Equal(expectedResult, TensorPrimitives.Dot(x, y), Tolerance); + AssertEqualTolerance(expectedResult, TensorPrimitives.Dot(x, y)); } [Theory] @@ -849,171 +882,166 @@ public static void Dot(int tensorLength) dot += x[i] * y[i]; } - Assert.Equal(dot, TensorPrimitives.Dot(x, y), Tolerance); + AssertEqualTolerance(dot, TensorPrimitives.Dot(x, y)); } + #endregion + #region Exp [Theory] - [InlineData(new float[] { 1, 2, 3 }, 3.7416575f)] - [InlineData(new float[] { 3, 4 }, 5)] - [InlineData(new float[] { 3 }, 3)] - [InlineData(new float[] { 3, 4, 1, 2 }, 5.477226)] - [InlineData(new float[] { }, 0f)] - public static void Norm_KnownValues(float[] x, float expectedResult) + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Exp(int tensorLength) { - Assert.Equal(expectedResult, TensorPrimitives.Norm(x), Tolerance); + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Exp(x, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Exp(x[i]), destination[i]); + } } [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void Norm(int tensorLength) + public static void Exp_InPlace(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); - float sumOfSquares = 0f; - for (int i = 0; i < x.Length; i++) + TensorPrimitives.Exp(x, x); + + for (int i = 0; i < tensorLength; i++) { - sumOfSquares += x[i] * x[i]; + AssertEqualTolerance(MathF.Exp(xOrig[i]), x[i]); } - - Assert.Equal(Math.Sqrt(sumOfSquares), TensorPrimitives.Norm(x), Tolerance); } [Theory] [MemberData(nameof(TensorLengths))] - public static void SoftMax_ThrowsForTooShortDestination(int tensorLength) + public static void Exp_SpecialValues(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); - AssertExtensions.Throws("destination", () => TensorPrimitives.SoftMax(x, destination)); + RunForEachSpecialValue(() => + { + TensorPrimitives.Exp(x, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Exp(x[i]), destination[i]); + } + }, x); } [Theory] - [InlineData(new float[] { 3, 1, .2f }, new float[] { 0.8360188f, 0.11314284f, 0.05083836f })] - [InlineData(new float[] { 3, 4, 1 }, new float[] { 0.2594f, 0.705384f, 0.0351f })] - [InlineData(new float[] { 5, 3 }, new float[] { 0.8807f, 0.1192f })] - [InlineData(new float[] { 4, 2, 1, 9 }, new float[] { 0.0066f, 9.04658e-4f, 3.32805e-4f, 0.9920f})] - public static void SoftMax(float[] x, float[] expectedResult) + [MemberData(nameof(TensorLengths))] + public static void Exp_ThrowsForTooShortDestination(int tensorLength) { - using BoundedMemory dest = CreateTensor(x.Length); - TensorPrimitives.SoftMax(x, dest); + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); - for (int i = 0; i < x.Length; i++) - { - Assert.Equal(expectedResult[i], dest[i], Tolerance); - } + AssertExtensions.Throws("destination", () => TensorPrimitives.Exp(x, destination)); } [Fact] - public static void SoftMax_DestinationLongerThanSource() + public static void Exp_ThrowsForOverlapppingInputsWithOutputs() { - float[] x = [3, 1, .2f]; - float[] expectedResult = [0.8360188f, 0.11314284f, 0.05083836f]; - using BoundedMemory dest = CreateTensor(x.Length + 1); - TensorPrimitives.SoftMax(x, dest); - - for (int i = 0; i < x.Length; i++) - { - Assert.Equal(expectedResult[i], dest[i], Tolerance); - } + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Exp(array.AsSpan(1, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Exp(array.AsSpan(1, 2), array.AsSpan(2, 2))); } + #endregion + #region IndexOfMax [Fact] - public static void SoftMax_ThrowsForEmptyInput() + public static void IndexOfMax_ReturnsNegative1OnEmpty() { - AssertExtensions.Throws(() => TensorPrimitives.SoftMax(ReadOnlySpan.Empty, CreateTensor(1))); + Assert.Equal(-1, TensorPrimitives.IndexOfMax(ReadOnlySpan.Empty)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void Sigmoid_ThrowsForTooShortDestination(int tensorLength) + public static void IndexOfMax(int tensorLength) { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); - - AssertExtensions.Throws("destination", () => TensorPrimitives.Sigmoid(x, destination)); + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + x[expected] = Enumerable.Max(MemoryMarshal.ToEnumerable(x.Memory)) + 1; + Assert.Equal(expected, TensorPrimitives.IndexOfMax(x)); + } } [Theory] - [InlineData(new float[] { -5, -4.5f, -4 }, new float[] { 0.0066f, 0.0109f, 0.0179f })] - [InlineData(new float[] { 4.5f, 5 }, new float[] { 0.9890f, 0.9933f })] - [InlineData(new float[] { 0, -3, 3, .5f }, new float[] { 0.5f, 0.0474f, 0.9525f, 0.6224f })] - public static void Sigmoid(float[] x, float[] expectedResult) - { - using BoundedMemory dest = CreateTensor(x.Length); - TensorPrimitives.Sigmoid(x, dest); - - for (int i = 0; i < x.Length; i++) - { - Assert.Equal(expectedResult[i], dest[i], Tolerance); - } - } - - [Fact] - public static void Sigmoid_DestinationLongerThanSource() + [MemberData(nameof(TensorLengths))] + public static void IndexOfMax_FirstNaNReturned(int tensorLength) { - float[] x = [-5, -4.5f, -4]; - float[] expectedResult = [0.0066f, 0.0109f, 0.0179f]; - using BoundedMemory dest = CreateTensor(x.Length + 1); - - TensorPrimitives.Sigmoid(x, dest); - - float originalLast = dest[dest.Length - 1]; - for (int i = 0; i < x.Length; i++) + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) { - Assert.Equal(expectedResult[i], dest[i], Tolerance); + using BoundedMemory x = CreateAndFillTensor(tensorLength); + x[expected] = float.NaN; + x[tensorLength - 1] = float.NaN; + Assert.Equal(expected, TensorPrimitives.IndexOfMax(x)); } - Assert.Equal(originalLast, dest[dest.Length - 1]); } [Fact] - public static void Sigmoid_ThrowsForEmptyInput() + public static void IndexOfMax_Negative0LesserThanPositive0() { - AssertExtensions.Throws(() => TensorPrimitives.Sigmoid(ReadOnlySpan.Empty, CreateTensor(1))); + Assert.Equal(1, TensorPrimitives.IndexOfMax([-0f, +0f])); + Assert.Equal(0, TensorPrimitives.IndexOfMax([-0f, -0f, -0f, -0f])); + Assert.Equal(4, TensorPrimitives.IndexOfMax([-0f, -0f, -0f, -0f, +0f, +0f, +0f])); + Assert.Equal(0, TensorPrimitives.IndexOfMax([+0f, -0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMax([-1, -0f])); + Assert.Equal(2, TensorPrimitives.IndexOfMax([-1, -0f, 1])); } + #endregion + #region IndexOfMaxMagnitude [Fact] - public static void IndexOfMax_ReturnsNegative1OnEmpty() + public static void IndexOfMaxMagnitude_ReturnsNegative1OnEmpty() { - Assert.Equal(-1, TensorPrimitives.IndexOfMax(ReadOnlySpan.Empty)); + Assert.Equal(-1, TensorPrimitives.IndexOfMaxMagnitude(ReadOnlySpan.Empty)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void IndexOfMax(int tensorLength) + public static void IndexOfMaxMagnitude(int tensorLength) { foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - x[expected] = Enumerable.Max(MemoryMarshal.ToEnumerable(x.Memory)) + 1; - Assert.Equal(expected, TensorPrimitives.IndexOfMax(x)); + x[expected] = Enumerable.Max(MemoryMarshal.ToEnumerable(x.Memory), Math.Abs) + 1; + Assert.Equal(expected, TensorPrimitives.IndexOfMaxMagnitude(x)); } } [Theory] [MemberData(nameof(TensorLengths))] - public static void IndexOfMax_FirstNaNReturned(int tensorLength) + public static void IndexOfMaxMagnitude_FirstNaNReturned(int tensorLength) { foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) { using BoundedMemory x = CreateAndFillTensor(tensorLength); x[expected] = float.NaN; x[tensorLength - 1] = float.NaN; - Assert.Equal(expected, TensorPrimitives.IndexOfMax(x)); + Assert.Equal(expected, TensorPrimitives.IndexOfMaxMagnitude(x)); } } [Fact] - public static void IndexOfMax_Negative0LesserThanPositive0() + public static void IndexOfMaxMagnitude_Negative0LesserThanPositive0() { - Assert.Equal(1, TensorPrimitives.IndexOfMax([-0f, +0f])); - Assert.Equal(0, TensorPrimitives.IndexOfMax([-0f, -0f, -0f, -0f])); - Assert.Equal(4, TensorPrimitives.IndexOfMax([-0f, -0f, -0f, -0f, +0f, +0f, +0f])); - Assert.Equal(0, TensorPrimitives.IndexOfMax([+0f, -0f])); - Assert.Equal(1, TensorPrimitives.IndexOfMax([-1, -0f])); - Assert.Equal(2, TensorPrimitives.IndexOfMax([-1, -0f, 1])); + Assert.Equal(0, TensorPrimitives.IndexOfMaxMagnitude([-0f, -0f, -0f, -0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMaxMagnitude([-0f, +0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMaxMagnitude([-0f, +0f, +0f, +0f])); + Assert.Equal(0, TensorPrimitives.IndexOfMaxMagnitude([+0f, -0f])); + Assert.Equal(0, TensorPrimitives.IndexOfMaxMagnitude([-1, -0f])); + Assert.Equal(2, TensorPrimitives.IndexOfMaxMagnitude([-1, -0f, 1])); } + #endregion + #region IndexOfMin [Fact] public static void IndexOfMin_ReturnsNegative1OnEmpty() { @@ -1054,106 +1082,202 @@ public static void IndexOfMin_Negative0LesserThanPositive0() Assert.Equal(0, TensorPrimitives.IndexOfMin([-1, -0f])); Assert.Equal(0, TensorPrimitives.IndexOfMin([-1, -0f, 1])); } + #endregion + #region IndexOfMinMagnitude [Fact] - public static void IndexOfMaxMagnitude_ReturnsNegative1OnEmpty() + public static void IndexOfMinMagnitude_ReturnsNegative1OnEmpty() { - Assert.Equal(-1, TensorPrimitives.IndexOfMaxMagnitude(ReadOnlySpan.Empty)); + Assert.Equal(-1, TensorPrimitives.IndexOfMinMagnitude(ReadOnlySpan.Empty)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void IndexOfMaxMagnitude(int tensorLength) + public static void IndexOfMinMagnitude(int tensorLength) { foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - x[expected] = Enumerable.Max(MemoryMarshal.ToEnumerable(x.Memory), Math.Abs) + 1; - Assert.Equal(expected, TensorPrimitives.IndexOfMaxMagnitude(x)); + using BoundedMemory x = CreateTensor(tensorLength); + for (int i = 0; i < x.Length; i++) + { + x[i] = i % 2 == 0 ? 42 : -42; + } + + x[expected] = -41; + + Assert.Equal(expected, TensorPrimitives.IndexOfMinMagnitude(x)); } } [Theory] [MemberData(nameof(TensorLengths))] - public static void IndexOfMaxMagnitude_FirstNaNReturned(int tensorLength) + public static void IndexOfMinMagnitude_FirstNaNReturned(int tensorLength) { foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) { using BoundedMemory x = CreateAndFillTensor(tensorLength); x[expected] = float.NaN; x[tensorLength - 1] = float.NaN; - Assert.Equal(expected, TensorPrimitives.IndexOfMaxMagnitude(x)); + Assert.Equal(expected, TensorPrimitives.IndexOfMinMagnitude(x)); } } [Fact] - public static void IndexOfMaxMagnitude_Negative0LesserThanPositive0() + public static void IndexOfMinMagnitude_Negative0LesserThanPositive0() { - Assert.Equal(0, TensorPrimitives.IndexOfMaxMagnitude([-0f, -0f, -0f, -0f])); - Assert.Equal(1, TensorPrimitives.IndexOfMaxMagnitude([-0f, +0f])); - Assert.Equal(1, TensorPrimitives.IndexOfMaxMagnitude([-0f, +0f, +0f, +0f])); - Assert.Equal(0, TensorPrimitives.IndexOfMaxMagnitude([+0f, -0f])); - Assert.Equal(0, TensorPrimitives.IndexOfMaxMagnitude([-1, -0f])); - Assert.Equal(2, TensorPrimitives.IndexOfMaxMagnitude([-1, -0f, 1])); + Assert.Equal(0, TensorPrimitives.IndexOfMinMagnitude([-0f, -0f, -0f, -0f])); + Assert.Equal(0, TensorPrimitives.IndexOfMinMagnitude([-0f, +0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMinMagnitude([+0f, -0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMinMagnitude([+0f, -0f, -0f, -0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMinMagnitude([-1, -0f])); + Assert.Equal(1, TensorPrimitives.IndexOfMinMagnitude([-1, -0f, 1])); } + #endregion - [Fact] - public static void IndexOfMinMagnitude_ReturnsNegative1OnEmpty() + #region Log + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Log(int tensorLength) { - Assert.Equal(-1, TensorPrimitives.IndexOfMinMagnitude(ReadOnlySpan.Empty)); + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Log(x, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Log(x[i]), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Log_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + + TensorPrimitives.Log(x, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Log(xOrig[i]), x[i]); + } } [Theory] [MemberData(nameof(TensorLengths))] - public static void IndexOfMinMagnitude(int tensorLength) + public static void Log_SpecialValues(int tensorLength) { - foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + RunForEachSpecialValue(() => { - using BoundedMemory x = CreateTensor(tensorLength); - for (int i = 0; i < x.Length; i++) + TensorPrimitives.Log(x, destination); + for (int i = 0; i < tensorLength; i++) { - x[i] = i % 2 == 0 ? 42 : -42; + AssertEqualTolerance(MathF.Log(x[i]), destination[i]); } + }, x); + } - x[expected] = -41; + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Log_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); - Assert.Equal(expected, TensorPrimitives.IndexOfMinMagnitude(x)); + AssertExtensions.Throws("destination", () => TensorPrimitives.Log(x, destination)); + } + + [Fact] + public static void Log_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Log(array.AsSpan(1, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Log(array.AsSpan(1, 2), array.AsSpan(2, 2))); + } + #endregion + + #region Log2 + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Log2(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Log2(x, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Log(x[i], 2), destination[i]); } } [Theory] - [MemberData(nameof(TensorLengths))] - public static void IndexOfMinMagnitude_FirstNaNReturned(int tensorLength) + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Log2_InPlace(int tensorLength) { - foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + + TensorPrimitives.Log2(x, x); + + for (int i = 0; i < tensorLength; i++) { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - x[expected] = float.NaN; - x[tensorLength - 1] = float.NaN; - Assert.Equal(expected, TensorPrimitives.IndexOfMinMagnitude(x)); + AssertEqualTolerance(MathF.Log(xOrig[i], 2), x[i]); } } + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Log2_SpecialValues(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + RunForEachSpecialValue(() => + { + TensorPrimitives.Log2(x, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Log(x[i], 2), destination[i]); + } + }, x); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Log2_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Log2(x, destination)); + } + [Fact] - public static void IndexOfMinMagnitude_Negative0LesserThanPositive0() + public static void Log2_ThrowsForOverlapppingInputsWithOutputs() { - Assert.Equal(0, TensorPrimitives.IndexOfMinMagnitude([-0f, -0f, -0f, -0f])); - Assert.Equal(0, TensorPrimitives.IndexOfMinMagnitude([-0f, +0f])); - Assert.Equal(1, TensorPrimitives.IndexOfMinMagnitude([+0f, -0f])); - Assert.Equal(1, TensorPrimitives.IndexOfMinMagnitude([+0f, -0f, -0f, -0f])); - Assert.Equal(1, TensorPrimitives.IndexOfMinMagnitude([-1, -0f])); - Assert.Equal(1, TensorPrimitives.IndexOfMinMagnitude([-1, -0f, 1])); + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Log2(array.AsSpan(1, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Log2(array.AsSpan(1, 2), array.AsSpan(2, 2))); } + #endregion + #region Max [Fact] - public static void Max_ThrowsForEmpty() + public static void Max_Tensor_ThrowsForEmpty() { Assert.Throws(() => TensorPrimitives.Max(ReadOnlySpan.Empty)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void Max(int tensorLength) + public static void Max_Tensor(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -1164,23 +1288,45 @@ public static void Max(int tensorLength) { max = Math.Max(max, f); } + Assert.Equal(max, TensorPrimitives.Max(x)); + Assert.Equal(SingleToUInt32(x[TensorPrimitives.IndexOfMax(x)]), SingleToUInt32(TensorPrimitives.Max(x))); } [Theory] [MemberData(nameof(TensorLengths))] - public static void Max_NanReturned(int tensorLength) + public static void Max_Tensor_SpecialValues(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); + + RunForEachSpecialValue(() => + { + float max = float.NegativeInfinity; + foreach (float f in x.Span) + { + max = Math.Max(max, f); + } + + Assert.Equal(max, TensorPrimitives.Max(x)); + Assert.Equal(SingleToUInt32(x[TensorPrimitives.IndexOfMax(x)]), SingleToUInt32(TensorPrimitives.Max(x))); + }, x); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Max_Tensor_NanReturned(int tensorLength) + { + using BoundedMemory x = CreateTensor(tensorLength); foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) { + FillTensor(x); x[expected] = float.NaN; Assert.Equal(float.NaN, TensorPrimitives.Max(x)); } } [Fact] - public static void Max_Negative0LesserThanPositive0() + public static void Max_Tensor_Negative0LesserThanPositive0() { Assert.Equal(+0f, TensorPrimitives.Max([-0f, +0f])); Assert.Equal(+0f, TensorPrimitives.Max([+0f, -0f])); @@ -1200,7 +1346,56 @@ public static void Max_TwoTensors(int tensorLength) for (int i = 0; i < tensorLength; i++) { - Assert.Equal(MathF.Max(x[i], y[i]), destination[i], Tolerance); + AssertEqualTolerance(MathF.Max(x[i], y[i]), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Max_TwoTensors_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(), yOrig = y.Span.ToArray(); + + TensorPrimitives.Max(x, y, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Max(xOrig[i], y[i]), x[i]); + } + + xOrig.AsSpan().CopyTo(x.Span); + yOrig.AsSpan().CopyTo(y.Span); + + TensorPrimitives.Max(x, y, y); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Max(x[i], yOrig[i]), y[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Max_TwoTensors_SpecialValues(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + SetSpecialValues(x, y); + + TensorPrimitives.Max(x, y, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Max(x[i], y[i]), destination[i]); + } + + TensorPrimitives.Max(y, x, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Max(y[i], x[i]), destination[i]); } } @@ -1213,6 +1408,7 @@ public static void Max_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) using BoundedMemory destination = CreateTensor(tensorLength); Assert.Throws(() => TensorPrimitives.Max(x, y, destination)); + Assert.Throws(() => TensorPrimitives.Max(y, x, destination)); } [Theory] @@ -1227,467 +1423,1570 @@ public static void Max_TwoTensors_ThrowsForTooShortDestination(int tensorLength) } [Fact] - public static void MaxMagnitude_ThrowsForEmpty() + public static void Max_TwoTensors_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Max(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Max(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Max(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Max(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(5, 2))); + } + #endregion + + #region MaxMagnitude + [Fact] + public static void MaxMagnitude_Tensor_ThrowsForEmpty() { Assert.Throws(() => TensorPrimitives.MaxMagnitude(ReadOnlySpan.Empty)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void MaxMagnitude(int tensorLength) + public static void MaxMagnitude_Tensor(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - int index = 0; - for (int i = 0; i < x.Length; i++) + float maxMagnitude = x[0]; + foreach (float f in x.Span) { - if (MathF.Abs(x[i]) >= MathF.Abs(x[index])) - { - index = i; - } + maxMagnitude = MathFMaxMagnitude(maxMagnitude, f); } - Assert.Equal(x[index], TensorPrimitives.MaxMagnitude(x), Tolerance); + Assert.Equal(maxMagnitude, TensorPrimitives.MaxMagnitude(x)); + Assert.Equal(SingleToUInt32(x[TensorPrimitives.IndexOfMaxMagnitude(x)]), SingleToUInt32(TensorPrimitives.MaxMagnitude(x))); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MaxMagnitude_Tensor_SpecialValues(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + RunForEachSpecialValue(() => + { + float maxMagnitude = x[0]; + foreach (float f in x.Span) + { + maxMagnitude = MathFMaxMagnitude(maxMagnitude, f); + } + + Assert.Equal(maxMagnitude, TensorPrimitives.MaxMagnitude(x)); + Assert.Equal(SingleToUInt32(x[TensorPrimitives.IndexOfMaxMagnitude(x)]), SingleToUInt32(TensorPrimitives.MaxMagnitude(x))); + }, x); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MaxMagnitude_Tensor_NanReturned(int tensorLength) + { + using BoundedMemory x = CreateTensor(tensorLength); + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + FillTensor(x); + x[expected] = float.NaN; + Assert.Equal(float.NaN, TensorPrimitives.MaxMagnitude(x)); + } + } + + [Fact] + public static void MaxMagnitude_Tensor_Negative0LesserThanPositive0() + { + Assert.Equal(+0f, TensorPrimitives.MaxMagnitude([-0f, +0f])); + Assert.Equal(+0f, TensorPrimitives.MaxMagnitude([+0f, -0f])); + Assert.Equal(-1, TensorPrimitives.MaxMagnitude([-1, -0f])); + Assert.Equal(1, TensorPrimitives.MaxMagnitude([-1, -0f, 1])); + Assert.Equal(0f, TensorPrimitives.MaxMagnitude([-0f, -0f, -0f, -0f, -0f, 0f])); + Assert.Equal(1, TensorPrimitives.MaxMagnitude([-0f, -0f, -0f, -0f, -1, -0f, 0f, 1])); + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void MaxMagnitude_TwoTensors(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.MaxMagnitude(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathFMaxMagnitude(x[i], y[i]), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void MaxMagnitude_TwoTensors_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(), yOrig = y.Span.ToArray(); + + TensorPrimitives.MaxMagnitude(x, y, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathFMaxMagnitude(xOrig[i], y[i]), x[i]); + } + + xOrig.AsSpan().CopyTo(x.Span); + yOrig.AsSpan().CopyTo(y.Span); + + TensorPrimitives.MaxMagnitude(x, y, y); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathFMaxMagnitude(x[i], yOrig[i]), y[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MaxMagnitude_TwoTensors_SpecialValues(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + SetSpecialValues(x, y); + + TensorPrimitives.MaxMagnitude(x, y, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathFMaxMagnitude(x[i], y[i]), destination[i]); + } + + TensorPrimitives.MaxMagnitude(y, x, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathFMaxMagnitude(y[i], x[i]), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MaxMagnitude_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.MaxMagnitude(x, y, destination)); + Assert.Throws(() => TensorPrimitives.MaxMagnitude(y, x, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MaxMagnitude_TwoTensors_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.MaxMagnitude(x, y, destination)); + } + + [Fact] + public static void MaxMagnitude_TwoTensors_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.MaxMagnitude(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MaxMagnitude(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MaxMagnitude(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MaxMagnitude(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(5, 2))); + } + #endregion + + #region Min + [Fact] + public static void Min_Tensor_ThrowsForEmpty() + { + Assert.Throws(() => TensorPrimitives.Min(ReadOnlySpan.Empty)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Min_Tensor(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + Assert.Equal(Enumerable.Min(MemoryMarshal.ToEnumerable(x.Memory)), TensorPrimitives.Min(x)); + + float min = float.PositiveInfinity; + foreach (float f in x.Span) + { + min = Math.Min(min, f); + } + + Assert.Equal(min, TensorPrimitives.Min(x)); + Assert.Equal(SingleToUInt32(x[TensorPrimitives.IndexOfMin(x)]), SingleToUInt32(TensorPrimitives.Min(x))); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Min_Tensor_SpecialValues(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + RunForEachSpecialValue(() => + { + float min = float.PositiveInfinity; + foreach (float f in x.Span) + { + min = Math.Min(min, f); + } + + Assert.Equal(min, TensorPrimitives.Min(x)); + Assert.Equal(SingleToUInt32(x[TensorPrimitives.IndexOfMin(x)]), SingleToUInt32(TensorPrimitives.Min(x))); + }, x); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Min_Tensor_NanReturned(int tensorLength) + { + using BoundedMemory x = CreateTensor(tensorLength); + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + FillTensor(x); + x[expected] = float.NaN; + Assert.Equal(float.NaN, TensorPrimitives.Min(x)); + } + } + + [Fact] + public static void Min_Tensor_Negative0LesserThanPositive0() + { + Assert.Equal(-0f, TensorPrimitives.Min([-0f, +0f])); + Assert.Equal(-0f, TensorPrimitives.Min([+0f, -0f])); + Assert.Equal(-1, TensorPrimitives.Min([-1, -0f])); + Assert.Equal(-1, TensorPrimitives.Min([-1, -0f, 1])); + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Min_TwoTensors(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Min(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Min(x[i], y[i]), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Min_TwoTensors_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(), yOrig = y.Span.ToArray(); + + TensorPrimitives.Min(x, y, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Min(xOrig[i], y[i]), x[i]); + } + + xOrig.AsSpan().CopyTo(x.Span); + yOrig.AsSpan().CopyTo(y.Span); + + TensorPrimitives.Min(x, y, y); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Min(x[i], yOrig[i]), y[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Min_TwoTensors_SpecialValues(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + SetSpecialValues(x, y); + + TensorPrimitives.Min(x, y, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Min(x[i], y[i]), destination[i]); + } + + TensorPrimitives.Min(y, x, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Min(y[i], x[i]), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Min_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.Min(x, y, destination)); + Assert.Throws(() => TensorPrimitives.Min(y, x, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Min_TwoTensors_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Min(x, y, destination)); + } + + [Fact] + public static void Min_TwoTensors_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Min(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Min(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Min(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Min(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(5, 2))); + } + #endregion + + #region MinMagnitude + [Fact] + public static void MinMagnitude_Tensor_ThrowsForEmpty() + { + Assert.Throws(() => TensorPrimitives.MinMagnitude(ReadOnlySpan.Empty)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MinMagnitude_Tensor(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + float minMagnitude = x[0]; + foreach (float f in x.Span) + { + minMagnitude = MathFMinMagnitude(minMagnitude, f); + } + + Assert.Equal(minMagnitude, TensorPrimitives.MinMagnitude(x)); + Assert.Equal(SingleToUInt32(x[TensorPrimitives.IndexOfMinMagnitude(x)]), SingleToUInt32(TensorPrimitives.MinMagnitude(x))); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MinMagnitude_Tensor_SpecialValues(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + RunForEachSpecialValue(() => + { + float minMagnitude = x[0]; + foreach (float f in x.Span) + { + minMagnitude = MathFMinMagnitude(minMagnitude, f); + } + + Assert.Equal(minMagnitude, TensorPrimitives.MinMagnitude(x)); + Assert.Equal(SingleToUInt32(x[TensorPrimitives.IndexOfMinMagnitude(x)]), SingleToUInt32(TensorPrimitives.MinMagnitude(x))); + }, x); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MinMagnitude_Tensor_NanReturned(int tensorLength) + { + using BoundedMemory x = CreateTensor(tensorLength); + foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) + { + FillTensor(x); + x[expected] = float.NaN; + Assert.Equal(float.NaN, TensorPrimitives.MinMagnitude(x)); + } + } + + [Fact] + public static void MinMagnitude_Tensor_Negative0LesserThanPositive0() + { + Assert.Equal(0, TensorPrimitives.MinMagnitude([-0f, +0f])); + Assert.Equal(0, TensorPrimitives.MinMagnitude([+0f, -0f])); + Assert.Equal(0, TensorPrimitives.MinMagnitude([-1, -0f])); + Assert.Equal(0, TensorPrimitives.MinMagnitude([-1, -0f, 1])); + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void MinMagnitude_TwoTensors(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.MinMagnitude(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathFMinMagnitude(x[i], y[i]), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void MinMagnitude_TwoTensors_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(), yOrig = y.Span.ToArray(); + + TensorPrimitives.MinMagnitude(x, y, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathFMinMagnitude(xOrig[i], y[i]), x[i]); + } + + xOrig.AsSpan().CopyTo(x.Span); + yOrig.AsSpan().CopyTo(y.Span); + + TensorPrimitives.MinMagnitude(x, y, y); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathFMinMagnitude(x[i], yOrig[i]), y[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MinMagnitude_TwoTensors_SpecialValues(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + SetSpecialValues(x, y); + + TensorPrimitives.MinMagnitude(x, y, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathFMinMagnitude(x[i], y[i]), destination[i]); + } + + TensorPrimitives.MinMagnitude(y, x, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathFMinMagnitude(y[i], x[i]), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MinMagnitude_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.MinMagnitude(x, y, destination)); + Assert.Throws(() => TensorPrimitives.MinMagnitude(y, x, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MinMagnitude_TwoTensors_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.MinMagnitude(x, y, destination)); + } + + [Fact] + public static void MinMagnitude_TwoTensors_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.MinMagnitude(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MinMagnitude(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MinMagnitude(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MinMagnitude(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(5, 2))); + } + #endregion + + #region Multiply + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Multiply_TwoTensors(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Multiply(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(x[i] * y[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Multiply_TwoTensors_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + + TensorPrimitives.Multiply(x, x, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(xOrig[i] * xOrig[i], x[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Multiply_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.Multiply(x, y, destination)); + Assert.Throws(() => TensorPrimitives.Multiply(y, x, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Multiply_TwoTensors_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Multiply(x, y, destination)); + } + + [Fact] + public static void Multiply_TwoTensors_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Multiply(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Multiply(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Multiply(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Multiply(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(5, 2))); + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Multiply_TensorScalar(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Multiply(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(x[i] * y, destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Multiply_TensorScalar_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + float y = NextSingle(); + + TensorPrimitives.Multiply(x, y, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(xOrig[i] * y, x[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Multiply_TensorScalar_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Multiply(x, y, destination)); + } + + [Fact] + public static void Multiply_TensorScalar_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Multiply(array.AsSpan(1, 2), 42, array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Multiply(array.AsSpan(1, 2), 42, array.AsSpan(2, 2))); + } + #endregion + + #region MultiplyAdd + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void MultiplyAdd_ThreeTensors(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory addend = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.MultiplyAdd(x, y, addend, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance((x[i] * y[i]) + addend[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void MultiplyAdd_ThreeTensors_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + + TensorPrimitives.MultiplyAdd(x, x, x, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance((xOrig[i] * xOrig[i]) + xOrig[i], x[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyAdd_ThreeTensors_ThrowsForMismatchedLengths_x_y(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory z = CreateAndFillTensor(tensorLength - 1); + using BoundedMemory destination = CreateTensor(tensorLength); + + Assert.Throws(() => TensorPrimitives.MultiplyAdd(x, y, z, destination)); + Assert.Throws(() => TensorPrimitives.MultiplyAdd(x, z, y, destination)); + Assert.Throws(() => TensorPrimitives.MultiplyAdd(z, x, y, destination)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyAdd_ThreeTensors_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + using BoundedMemory addend = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(x, y, addend, destination)); + } + + [Fact] + public static void MultiplyAdd_ThreeTensors_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(7, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(7, 2), array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(7, 2), array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(7, 2), array.AsSpan(5, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(7, 2), array.AsSpan(6, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(7, 2), array.AsSpan(8, 2))); + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void MultiplyAdd_TensorTensorScalar(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + float addend = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.MultiplyAdd(x, y, addend, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance((x[i] * y[i]) + addend, destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void MultiplyAdd_TensorTensorScalar_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + float addend = NextSingle(); + + TensorPrimitives.MultiplyAdd(x, x, addend, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance((xOrig[i] * xOrig[i]) + addend, x[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyAdd_TensorTensorScalar_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + float addend = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(x, y, addend, destination)); + } + + [Fact] + public static void MultiplyAdd_TensorTensorScalar_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), array.AsSpan(4, 2), 42, array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), array.AsSpan(4, 2), 42, array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), array.AsSpan(4, 2), 42, array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), array.AsSpan(4, 2), 42, array.AsSpan(5, 2))); + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void MultiplyAdd_TensorScalarTensor(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory addend = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.MultiplyAdd(x, y, addend, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance((x[i] * y) + addend[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void MultiplyAdd_TensorScalarTensor_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + float y = NextSingle(); + + TensorPrimitives.MultiplyAdd(x, y, x, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance((xOrig[i] * y) + xOrig[i], x[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void MultiplyAdd_TensorScalarTensor_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory addend = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(x, y, addend, destination)); + } + + [Fact] + public static void MultiplyAdd_TensorScalarTensor_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), 42, array.AsSpan(4, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), 42, array.AsSpan(4, 2), array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), 42, array.AsSpan(4, 2), array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.MultiplyAdd(array.AsSpan(1, 2), 42, array.AsSpan(4, 2), array.AsSpan(5, 2))); + } + #endregion + + #region Negate + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Negate(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Negate(x, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(-x[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Negate_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + + TensorPrimitives.Negate(x, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(-xOrig[i], x[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Negate_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Negate(x, destination)); + } + + [Fact] + public static void Negate_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Negate(array.AsSpan(1, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Negate(array.AsSpan(1, 2), array.AsSpan(2, 2))); + } + #endregion + + #region Norm + [Theory] + [InlineData(new float[] { 1, 2, 3 }, 3.7416575f)] + [InlineData(new float[] { 3, 4 }, 5)] + [InlineData(new float[] { 3 }, 3)] + [InlineData(new float[] { 3, 4, 1, 2 }, 5.477226)] + [InlineData(new float[] { }, 0f)] + public static void Norm_KnownValues(float[] x, float expectedResult) + { + AssertEqualTolerance(expectedResult, TensorPrimitives.Norm(x)); + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Norm(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + float sumOfSquares = 0f; + for (int i = 0; i < x.Length; i++) + { + sumOfSquares += x[i] * x[i]; + } + + AssertEqualTolerance(MathF.Sqrt(sumOfSquares), TensorPrimitives.Norm(x)); + } + #endregion + + #region Product + [Fact] + public static void Product_ThrowsForEmpty() + { + Assert.Throws(() => TensorPrimitives.Product(ReadOnlySpan.Empty)); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Product(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + + float f = x[0]; + for (int i = 1; i < x.Length; i++) + { + f *= x[i]; + } + + AssertEqualTolerance(f, TensorPrimitives.Product(x)); + } + + [Theory] + [InlineData(1, new float[] { 1 })] + [InlineData(-2, new float[] { 1, -2 })] + [InlineData(-6, new float[] { 1, -2, 3 })] + [InlineData(24, new float[] { 1, -2, 3, -4 })] + [InlineData(120, new float[] { 1, -2, 3, -4, 5 })] + [InlineData(-720, new float[] { 1, -2, 3, -4, 5, -6 })] + [InlineData(0, new float[] { 1, -2, 3, -4, 5, -6, 0 })] + [InlineData(0, new float[] { 0, 1, -2, 3, -4, 5, -6 })] + [InlineData(0, new float[] { 1, -2, 3, 0, -4, 5, -6 })] + [InlineData(float.NaN, new float[] { 1, -2, 3, float.NaN, -4, 5, -6 })] + public static void Product_KnownValues(float expected, float[] input) + { + Assert.Equal(expected, TensorPrimitives.Product(input)); + } + #endregion + + #region ProductOfDifferences + [Fact] + public static void ProductOfDifferences_ThrowsForEmptyAndMismatchedLengths() + { + Assert.Throws(() => TensorPrimitives.ProductOfDifferences(ReadOnlySpan.Empty, ReadOnlySpan.Empty)); + Assert.Throws(() => TensorPrimitives.ProductOfDifferences(ReadOnlySpan.Empty, CreateTensor(1))); + Assert.Throws(() => TensorPrimitives.ProductOfDifferences(CreateTensor(1), ReadOnlySpan.Empty)); + Assert.Throws(() => TensorPrimitives.ProductOfDifferences(CreateTensor(44), CreateTensor(43))); + Assert.Throws(() => TensorPrimitives.ProductOfDifferences(CreateTensor(43), CreateTensor(44))); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void ProductOfDifferences(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + + float f = x[0] - y[0]; + for (int i = 1; i < x.Length; i++) + { + f *= x[i] - y[i]; + } + AssertEqualTolerance(f, TensorPrimitives.ProductOfDifferences(x, y)); + } + + [Theory] + [InlineData(0, new float[] {0 }, new float[] {0})] + [InlineData(0, new float[] {1 }, new float[] {1})] + [InlineData(1, new float[] {1 }, new float[] {0})] + [InlineData(-1, new float[] {0 }, new float[] {1})] + [InlineData(-1, new float[] {1, 2, 3, 4, 5 }, new float[] {2, 3, 4, 5, 6})] + [InlineData(120, new float[] {1, 2, 3, 4, 5 }, new float[] {0, 0, 0, 0, 0})] + [InlineData(-120, new float[] {0, 0, 0, 0, 0 }, new float[] {1, 2, 3, 4, 5})] + [InlineData(float.NaN, new float[] {1, 2, float.NaN, 4, 5 }, new float[] {0, 0, 0, 0, 0})] + public static void ProductOfDifferences_KnownValues(float expected, float[] x, float[] y) + { + Assert.Equal(expected, TensorPrimitives.ProductOfDifferences(x, y)); + + } + #endregion + + #region ProductOfSums + [Fact] + public static void ProductOfSums_ThrowsForEmptyAndMismatchedLengths() + { + Assert.Throws(() => TensorPrimitives.ProductOfSums(ReadOnlySpan.Empty, ReadOnlySpan.Empty)); + Assert.Throws(() => TensorPrimitives.ProductOfSums(ReadOnlySpan.Empty, CreateTensor(1))); + Assert.Throws(() => TensorPrimitives.ProductOfSums(CreateTensor(1), ReadOnlySpan.Empty)); + Assert.Throws(() => TensorPrimitives.ProductOfSums(CreateTensor(44), CreateTensor(43))); + Assert.Throws(() => TensorPrimitives.ProductOfSums(CreateTensor(43), CreateTensor(44))); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void ProductOfSums(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory y = CreateAndFillTensor(tensorLength); + + float f = x[0] + y[0]; + for (int i = 1; i < x.Length; i++) + { + f *= x[i] + y[i]; + } + AssertEqualTolerance(f, TensorPrimitives.ProductOfSums(x, y)); + } + + [Theory] + [InlineData(0, new float[] {0 }, new float[] { 0 })] + [InlineData(1, new float[] {0 }, new float[] { 1 })] + [InlineData(1, new float[] {1 }, new float[] { 0 })] + [InlineData(2, new float[] {1 }, new float[] { 1 })] + [InlineData(10395, new float[] {1, 2, 3, 4, 5 }, new float[] { 2, 3, 4, 5, 6 })] + [InlineData(120, new float[] {1, 2, 3, 4, 5 }, new float[] { 0, 0, 0, 0, 0 })] + [InlineData(120, new float[] {0, 0, 0, 0, 0 }, new float[] { 1, 2, 3, 4, 5 })] + [InlineData(float.NaN, new float[] {1, 2, float.NaN, 4, 5 }, new float[] { 0, 0, 0, 0, 0 })] + public static void ProductOfSums_KnownValues(float expected, float[] x, float[] y) + { + Assert.Equal(expected, TensorPrimitives.ProductOfSums(x, y)); + } + #endregion + + #region Sigmoid + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Sigmoid(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + TensorPrimitives.Sigmoid(x, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(1f / (1f + MathF.Exp(-x[i])), destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Sigmoid_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + + TensorPrimitives.Sigmoid(x, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(1f / (1f + MathF.Exp(-xOrig[i])), x[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Sigmoid_SpecialValues(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); + + RunForEachSpecialValue(() => + { + TensorPrimitives.Sigmoid(x, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(1f / (1f + MathF.Exp(-x[i])), destination[i]); + } + }, x); + } + + [Theory] + [InlineData(new float[] { -5, -4.5f, -4 }, new float[] { 0.0066f, 0.0109f, 0.0179f })] + [InlineData(new float[] { 4.5f, 5 }, new float[] { 0.9890f, 0.9933f })] + [InlineData(new float[] { 0, -3, 3, .5f }, new float[] { 0.5f, 0.0474f, 0.9525f, 0.6224f })] + public static void Sigmoid_KnownValues(float[] x, float[] expectedResult) + { + using BoundedMemory dest = CreateTensor(x.Length); + TensorPrimitives.Sigmoid(x, dest); + + for (int i = 0; i < x.Length; i++) + { + AssertEqualTolerance(expectedResult[i], dest[i], 0.0001f); + } + } + + [Theory] + [InlineData(new float[] { -5, -4.5f, -4 }, new float[] { 0.0066f, 0.0109f, 0.0179f })] + public static void Sigmoid_DestinationLongerThanSource(float[] x, float[] expectedResult) + { + using BoundedMemory dest = CreateTensor(x.Length + 1); + + TensorPrimitives.Sigmoid(x, dest); + + float originalLast = dest[dest.Length - 1]; + for (int i = 0; i < x.Length; i++) + { + AssertEqualTolerance(expectedResult[i], dest[i], 0.0001f); + } + Assert.Equal(originalLast, dest[dest.Length - 1]); + } + + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Sigmoid_ThrowsForTooShortDestination(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Sigmoid(x, destination)); } - [Theory] - [MemberData(nameof(TensorLengths))] - public static void MaxMagnitude_NanReturned(int tensorLength) + [Fact] + public static void Sigmoid_ThrowsForEmptyInput() { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) - { - x[expected] = float.NaN; - Assert.Equal(float.NaN, TensorPrimitives.MaxMagnitude(x)); - } + AssertExtensions.Throws(() => TensorPrimitives.Sigmoid(ReadOnlySpan.Empty, CreateTensor(1))); } [Fact] - public static void MaxMagnitude_Negative0LesserThanPositive0() + public static void Sigmoid_ThrowsForOverlapppingInputsWithOutputs() { - Assert.Equal(+0f, TensorPrimitives.MaxMagnitude([-0f, +0f])); - Assert.Equal(+0f, TensorPrimitives.MaxMagnitude([+0f, -0f])); - Assert.Equal(-1, TensorPrimitives.MaxMagnitude([-1, -0f])); - Assert.Equal(1, TensorPrimitives.MaxMagnitude([-1, -0f, 1])); - Assert.Equal(0f, TensorPrimitives.MaxMagnitude([-0f, -0f, -0f, -0f, -0f, 0f])); - Assert.Equal(1, TensorPrimitives.MaxMagnitude([-0f, -0f, -0f, -0f, -1, -0f, 0f, 1])); + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Sigmoid(array.AsSpan(1, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Sigmoid(array.AsSpan(1, 2), array.AsSpan(2, 2))); } + #endregion + #region Sinh [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void MaxMagnitude_TwoTensors(int tensorLength) + public static void Sinh(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); using BoundedMemory destination = CreateTensor(tensorLength); - TensorPrimitives.MaxMagnitude(x, y, destination); + TensorPrimitives.Sinh(x, destination); for (int i = 0; i < tensorLength; i++) { - Assert.Equal(MathF.Abs(x[i]) >= MathF.Abs(y[i]) ? x[i] : y[i], destination[i], Tolerance); + AssertEqualTolerance(MathF.Sinh(x[i]), destination[i]); } } [Theory] - [MemberData(nameof(TensorLengths))] - public static void MaxMagnitude_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Sinh_InPlace(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); - using BoundedMemory destination = CreateTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); - Assert.Throws(() => TensorPrimitives.MaxMagnitude(x, y, destination)); + TensorPrimitives.Sinh(x, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Sinh(xOrig[i]), x[i]); + } } [Theory] [MemberData(nameof(TensorLengths))] - public static void MaxMagnitude_TwoTensors_ThrowsForTooShortDestination(int tensorLength) + public static void Sinh_SpecialValues(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); - - AssertExtensions.Throws("destination", () => TensorPrimitives.MaxMagnitude(x, y, destination)); - } + using BoundedMemory destination = CreateTensor(tensorLength); - [Fact] - public static void Min_ThrowsForEmpty() - { - Assert.Throws(() => TensorPrimitives.Min(ReadOnlySpan.Empty)); + RunForEachSpecialValue(() => + { + TensorPrimitives.Sinh(x, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Sinh(x[i]), destination[i]); + } + }, x); } [Theory] - [MemberData(nameof(TensorLengths))] - public static void Min(int tensorLength) + [MemberData(nameof(VectorLengthAndIteratedRange), new object[] { -100f, 100f, 3f })] + public static void Sinh_ValueRange(int vectorLengths, float element) { - using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] x = new float[vectorLengths]; + float[] dest = new float[vectorLengths]; - Assert.Equal(Enumerable.Min(MemoryMarshal.ToEnumerable(x.Memory)), TensorPrimitives.Min(x)); + x.AsSpan().Fill(element); + TensorPrimitives.Sinh(x, dest); - float min = float.PositiveInfinity; - foreach (float f in x.Span) + float expected = MathF.Sinh(element); + foreach (float actual in dest) { - min = Math.Min(min, f); + AssertEqualTolerance(expected, actual); } - Assert.Equal(min, TensorPrimitives.Min(x)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void Min_NanReturned(int tensorLength) + public static void Sinh_ThrowsForTooShortDestination(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) - { - x[expected] = float.NaN; - Assert.Equal(float.NaN, TensorPrimitives.Min(x)); - } + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Sinh(x, destination)); } [Fact] - public static void Min_Negative0LesserThanPositive0() + public static void Sinh_ThrowsForOverlapppingInputsWithOutputs() { - Assert.Equal(-0f, TensorPrimitives.Min([-0f, +0f])); - Assert.Equal(-0f, TensorPrimitives.Min([+0f, -0f])); - Assert.Equal(-1, TensorPrimitives.Min([-1, -0f])); - Assert.Equal(-1, TensorPrimitives.Min([-1, -0f, 1])); + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Sinh(array.AsSpan(1, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Sinh(array.AsSpan(1, 2), array.AsSpan(2, 2))); } + #endregion + #region SoftMax [Theory] - [MemberData(nameof(TensorLengthsIncluding0))] - public static void Min_TwoTensors(int tensorLength) + [MemberData(nameof(TensorLengths))] + public static void SoftMax(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); using BoundedMemory destination = CreateTensor(tensorLength); - TensorPrimitives.Min(x, y, destination); + TensorPrimitives.SoftMax(x, destination); + float expSum = MemoryMarshal.ToEnumerable(x.Memory).Sum(MathF.Exp); for (int i = 0; i < tensorLength; i++) { - Assert.Equal(MathF.Min(x[i], y[i]), destination[i], Tolerance); + AssertEqualTolerance(MathF.Exp(x[i]) / expSum, destination[i]); } } [Theory] [MemberData(nameof(TensorLengths))] - public static void Min_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) + public static void SoftMax_InPlace(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); - using BoundedMemory destination = CreateTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); - Assert.Throws(() => TensorPrimitives.Min(x, y, destination)); + TensorPrimitives.SoftMax(x, x); + + float expSum = xOrig.Sum(MathF.Exp); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Exp(xOrig[i]) / expSum, x[i]); + } } [Theory] - [MemberData(nameof(TensorLengths))] - public static void Min_TwoTensors_ThrowsForTooShortDestination(int tensorLength) + [InlineData(new float[] { 3, 1, .2f }, new float[] { 0.8360188f, 0.11314284f, 0.05083836f })] + [InlineData(new float[] { 3, 4, 1 }, new float[] { 0.2594f, 0.705384f, 0.0351f })] + [InlineData(new float[] { 5, 3 }, new float[] { 0.8807f, 0.1192f })] + [InlineData(new float[] { 4, 2, 1, 9 }, new float[] { 0.0066f, 9.04658e-4f, 3.32805e-4f, 0.9920f })] + public static void SoftMax_KnownValues(float[] x, float[] expectedResult) { - using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - using BoundedMemory destination = CreateTensor(tensorLength - 1); + using BoundedMemory dest = CreateTensor(x.Length); + TensorPrimitives.SoftMax(x, dest); - AssertExtensions.Throws("destination", () => TensorPrimitives.Min(x, y, destination)); + for (int i = 0; i < x.Length; i++) + { + AssertEqualTolerance(expectedResult[i], dest[i], 0.0001f); + } } [Fact] - public static void MinMagnitude_ThrowsForEmpty() - { - Assert.Throws(() => TensorPrimitives.MinMagnitude(ReadOnlySpan.Empty)); - } - - [Theory] - [MemberData(nameof(TensorLengths))] - public static void MinMagnitude(int tensorLength) + public static void SoftMax_DestinationLongerThanSource() { - using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] x = [3, 1, .2f]; + float[] expectedResult = [0.8360188f, 0.11314284f, 0.05083836f]; + using BoundedMemory dest = CreateTensor(x.Length + 1); + TensorPrimitives.SoftMax(x, dest); - int index = 0; for (int i = 0; i < x.Length; i++) { - if (MathF.Abs(x[i]) < MathF.Abs(x[index])) - { - index = i; - } + AssertEqualTolerance(expectedResult[i], dest[i]); } - - Assert.Equal(x[index], TensorPrimitives.MinMagnitude(x), Tolerance); } [Theory] [MemberData(nameof(TensorLengths))] - public static void MinMagnitude_NanReturned(int tensorLength) + public static void SoftMax_ThrowsForTooShortDestination(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - foreach (int expected in new[] { 0, tensorLength / 2, tensorLength - 1 }) - { - x[expected] = float.NaN; - Assert.Equal(float.NaN, TensorPrimitives.MinMagnitude(x)); - } + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.SoftMax(x, destination)); } [Fact] - public static void MinMagnitude_Negative0LesserThanPositive0() + public static void SoftMax_ThrowsForEmptyInput() { - Assert.Equal(0, TensorPrimitives.MinMagnitude([-0f, +0f])); - Assert.Equal(0, TensorPrimitives.MinMagnitude([+0f, -0f])); - Assert.Equal(0, TensorPrimitives.MinMagnitude([-1, -0f])); - Assert.Equal(0, TensorPrimitives.MinMagnitude([-1, -0f, 1])); + AssertExtensions.Throws(() => TensorPrimitives.SoftMax(ReadOnlySpan.Empty, CreateTensor(1))); + } + + [Fact] + public static void SoftMax_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.SoftMax(array.AsSpan(1, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.SoftMax(array.AsSpan(1, 2), array.AsSpan(2, 2))); } + #endregion + #region Subtract [Theory] [MemberData(nameof(TensorLengthsIncluding0))] - public static void MinMagnitude_TwoTensors(int tensorLength) + public static void Subtract_TwoTensors(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); using BoundedMemory y = CreateAndFillTensor(tensorLength); using BoundedMemory destination = CreateTensor(tensorLength); - TensorPrimitives.MinMagnitude(x, y, destination); + TensorPrimitives.Subtract(x, y, destination); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(x[i] - y[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Subtract_TwoTensors_InPlace(int tensorLength) + { + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + + TensorPrimitives.Subtract(x, x, x); for (int i = 0; i < tensorLength; i++) { - Assert.Equal(MathF.Abs(x[i]) < MathF.Abs(y[i]) ? x[i] : y[i], destination[i], Tolerance); + AssertEqualTolerance(xOrig[i] - xOrig[i], x[i]); } } [Theory] [MemberData(nameof(TensorLengths))] - public static void MinMagnitude_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) + public static void Subtract_TwoTensors_ThrowsForMismatchedLengths(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); using BoundedMemory y = CreateAndFillTensor(tensorLength - 1); using BoundedMemory destination = CreateTensor(tensorLength); - Assert.Throws(() => TensorPrimitives.MinMagnitude(x, y, destination)); + Assert.Throws(() => TensorPrimitives.Subtract(x, y, destination)); + Assert.Throws(() => TensorPrimitives.Subtract(y, x, destination)); } [Theory] [MemberData(nameof(TensorLengths))] - public static void MinMagnitude_TwoTensors_ThrowsForTooShortDestination(int tensorLength) + public static void Subtract_TwoTensors_ThrowsForTooShortDestination(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); using BoundedMemory y = CreateAndFillTensor(tensorLength); using BoundedMemory destination = CreateTensor(tensorLength - 1); - AssertExtensions.Throws("destination", () => TensorPrimitives.MinMagnitude(x, y, destination)); + AssertExtensions.Throws("destination", () => TensorPrimitives.Subtract(x, y, destination)); } [Fact] - public static void Product_ThrowsForEmpty() + public static void Subtract_TwoTensors_ThrowsForOverlapppingInputsWithOutputs() { - Assert.Throws(() => TensorPrimitives.Product(ReadOnlySpan.Empty)); + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Subtract(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Subtract(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(2, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Subtract(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(3, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Subtract(array.AsSpan(1, 2), array.AsSpan(4, 2), array.AsSpan(5, 2))); } [Theory] - [MemberData(nameof(TensorLengths))] - public static void Product(int tensorLength) + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Subtract_TensorScalar(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength); - float f = x[0]; - for (int i = 1; i < x.Length; i++) + TensorPrimitives.Subtract(x, y, destination); + + for (int i = 0; i < tensorLength; i++) { - f *= x[i]; + AssertEqualTolerance(x[i] - y, destination[i]); } - - Assert.Equal(f, TensorPrimitives.Product(x), Tolerance); - } - - [Fact] - public static void Product_KnownValues() - { - Assert.Equal(1, TensorPrimitives.Product([1])); - Assert.Equal(-2, TensorPrimitives.Product([1, -2])); - Assert.Equal(-6, TensorPrimitives.Product([1, -2, 3])); - Assert.Equal(24, TensorPrimitives.Product([1, -2, 3, -4])); - Assert.Equal(120, TensorPrimitives.Product([1, -2, 3, -4, 5])); - Assert.Equal(-720, TensorPrimitives.Product([1, -2, 3, -4, 5, -6])); - Assert.Equal(0, TensorPrimitives.Product([1, -2, 3, -4, 5, -6, 0])); - Assert.Equal(0, TensorPrimitives.Product([0, 1, -2, 3, -4, 5, -6])); - Assert.Equal(0, TensorPrimitives.Product([1, -2, 3, 0, -4, 5, -6])); - Assert.Equal(float.NaN, TensorPrimitives.Product([1, -2, 3, float.NaN, -4, 5, -6])); - } - - [Fact] - public static void ProductOfDifferences_ThrowsForEmptyAndMismatchedLengths() - { - Assert.Throws(() => TensorPrimitives.ProductOfDifferences(ReadOnlySpan.Empty, ReadOnlySpan.Empty)); - Assert.Throws(() => TensorPrimitives.ProductOfDifferences(ReadOnlySpan.Empty, CreateTensor(1))); - Assert.Throws(() => TensorPrimitives.ProductOfDifferences(CreateTensor(1), ReadOnlySpan.Empty)); - Assert.Throws(() => TensorPrimitives.ProductOfDifferences(CreateTensor(44), CreateTensor(43))); - Assert.Throws(() => TensorPrimitives.ProductOfDifferences(CreateTensor(43), CreateTensor(44))); } [Theory] - [MemberData(nameof(TensorLengths))] - public static void ProductOfDifferences(int tensorLength) + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Subtract_TensorScalar_InPlace(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + float y = NextSingle(); - float f = x[0] - y[0]; - for (int i = 1; i < x.Length; i++) + TensorPrimitives.Subtract(x, y, x); + + for (int i = 0; i < tensorLength; i++) { - f *= x[i] - y[i]; + AssertEqualTolerance(xOrig[i] - y, x[i]); } - Assert.Equal(f, TensorPrimitives.ProductOfDifferences(x, y), Tolerance); } - [Fact] - public static void ProductOfDifferences_KnownValues() + [Theory] + [MemberData(nameof(TensorLengths))] + public static void Subtract_TensorScalar_ThrowsForTooShortDestination(int tensorLength) { - Assert.Equal(0, TensorPrimitives.ProductOfDifferences([0], [0])); - Assert.Equal(0, TensorPrimitives.ProductOfDifferences([1], [1])); - Assert.Equal(1, TensorPrimitives.ProductOfDifferences([1], [0])); - Assert.Equal(-1, TensorPrimitives.ProductOfDifferences([0], [1])); - Assert.Equal(-1, TensorPrimitives.ProductOfDifferences([1, 2, 3, 4, 5], [2, 3, 4, 5, 6])); - Assert.Equal(120, TensorPrimitives.ProductOfDifferences([1, 2, 3, 4, 5], [0, 0, 0, 0, 0])); - Assert.Equal(-120, TensorPrimitives.ProductOfDifferences([0, 0, 0, 0, 0], [1, 2, 3, 4, 5])); - Assert.Equal(float.NaN, TensorPrimitives.ProductOfDifferences([1, 2, float.NaN, 4, 5], [0, 0, 0, 0, 0])); + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float y = NextSingle(); + using BoundedMemory destination = CreateTensor(tensorLength - 1); + + AssertExtensions.Throws("destination", () => TensorPrimitives.Subtract(x, y, destination)); } [Fact] - public static void ProductOfSums_ThrowsForEmptyAndMismatchedLengths() + public static void Subtract_TensorScalar_ThrowsForOverlapppingInputsWithOutputs() { - Assert.Throws(() => TensorPrimitives.ProductOfSums(ReadOnlySpan.Empty, ReadOnlySpan.Empty)); - Assert.Throws(() => TensorPrimitives.ProductOfSums(ReadOnlySpan.Empty, CreateTensor(1))); - Assert.Throws(() => TensorPrimitives.ProductOfSums(CreateTensor(1), ReadOnlySpan.Empty)); - Assert.Throws(() => TensorPrimitives.ProductOfSums(CreateTensor(44), CreateTensor(43))); - Assert.Throws(() => TensorPrimitives.ProductOfSums(CreateTensor(43), CreateTensor(44))); + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Subtract(array.AsSpan(1, 2), 42, array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Subtract(array.AsSpan(1, 2), 42, array.AsSpan(2, 2))); } + #endregion + #region Sum [Theory] [MemberData(nameof(TensorLengths))] - public static void ProductOfSums(int tensorLength) + public static void Sum(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - using BoundedMemory y = CreateAndFillTensor(tensorLength); - float f = x[0] + y[0]; - for (int i = 1; i < x.Length; i++) + AssertEqualTolerance(MemoryMarshal.ToEnumerable(x.Memory).Sum(), TensorPrimitives.Sum(x)); + + float sum = 0; + foreach (float f in x.Span) { - f *= x[i] + y[i]; + sum += f; } - Assert.Equal(f, TensorPrimitives.ProductOfSums(x, y), Tolerance); + AssertEqualTolerance(sum, TensorPrimitives.Sum(x)); } - [Fact] - public static void ProductOfSums_KnownValues() + [Theory] + [InlineData(0, new float[] { 0 })] + [InlineData(1, new float[] { 0, 1 })] + [InlineData(6, new float[] { 1, 2, 3 })] + [InlineData(0, new float[] { -3, 0, 3 })] + [InlineData(float.NaN, new float[] { -3, float.NaN, 3 })] + public static void Sum_KnownValues(float expected, float[] x) { - Assert.Equal(0, TensorPrimitives.ProductOfSums([0], [0])); - Assert.Equal(1, TensorPrimitives.ProductOfSums([0], [1])); - Assert.Equal(1, TensorPrimitives.ProductOfSums([1], [0])); - Assert.Equal(2, TensorPrimitives.ProductOfSums([1], [1])); - Assert.Equal(10395, TensorPrimitives.ProductOfSums([1, 2, 3, 4, 5], [2, 3, 4, 5, 6])); - Assert.Equal(120, TensorPrimitives.ProductOfSums([1, 2, 3, 4, 5], [0, 0, 0, 0, 0])); - Assert.Equal(120, TensorPrimitives.ProductOfSums([0, 0, 0, 0, 0], [1, 2, 3, 4, 5])); - Assert.Equal(float.NaN, TensorPrimitives.ProductOfSums([1, 2, float.NaN, 4, 5], [0, 0, 0, 0, 0])); + Assert.Equal(expected, TensorPrimitives.Sum(x)); } + #endregion + #region SumOfMagnitudes [Theory] [MemberData(nameof(TensorLengths))] - public static void Sum(int tensorLength) + public static void SumOfMagnitudes(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - Assert.Equal(Enumerable.Sum(MemoryMarshal.ToEnumerable(x.Memory)), TensorPrimitives.Sum(x), Tolerance); + AssertEqualTolerance(Enumerable.Sum(MemoryMarshal.ToEnumerable(x.Memory), MathF.Abs), TensorPrimitives.SumOfMagnitudes(x)); float sum = 0; foreach (float f in x.Span) { - sum += f; + sum += MathF.Abs(f); } - Assert.Equal(sum, TensorPrimitives.Sum(x), Tolerance); + AssertEqualTolerance(sum, TensorPrimitives.SumOfMagnitudes(x)); } - [Fact] - public static void Sum_KnownValues() + [Theory] + [InlineData(0, new float[] { 0 })] + [InlineData(1, new float[] { 0, 1 })] + [InlineData(6, new float[] { 1, 2, 3 })] + [InlineData(6, new float[] { -3, 0, 3 })] + [InlineData(float.NaN, new float[] { -3, float.NaN, 3 })] + public static void SumOfMagnitudes_KnownValues(float expected, float[] x) { - Assert.Equal(0, TensorPrimitives.Sum([0])); - Assert.Equal(1, TensorPrimitives.Sum([0, 1])); - Assert.Equal(6, TensorPrimitives.Sum([1, 2, 3])); - Assert.Equal(0, TensorPrimitives.Sum([-3, 0, 3])); - Assert.Equal(float.NaN, TensorPrimitives.Sum([-3, float.NaN, 3])); + Assert.Equal(expected, TensorPrimitives.SumOfMagnitudes(x)); } + #endregion + #region SumOfSquares [Theory] [MemberData(nameof(TensorLengths))] public static void SumOfSquares(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); - Assert.Equal(Enumerable.Sum(MemoryMarshal.ToEnumerable(x.Memory), v => v * v), TensorPrimitives.SumOfSquares(x), Tolerance); + AssertEqualTolerance(Enumerable.Sum(MemoryMarshal.ToEnumerable(x.Memory), v => v * v), TensorPrimitives.SumOfSquares(x)); float sum = 0; foreach (float f in x.Span) { sum += f * f; } - Assert.Equal(sum, TensorPrimitives.SumOfSquares(x), Tolerance); + AssertEqualTolerance(sum, TensorPrimitives.SumOfSquares(x)); } - [Fact] - public static void SumOfSquares_KnownValues() + [Theory] + [InlineData(0, new float[] { 0 })] + [InlineData(1, new float[] { 0, 1 })] + [InlineData(14, new float[] { 1, 2, 3 })] + [InlineData(18, new float[] { -3, 0, 3 })] + [InlineData(float.NaN, new float[] { -3, float.NaN, 3 })] + public static void SumOfSquares_KnownValues(float expected, float[] x) { - Assert.Equal(0, TensorPrimitives.SumOfSquares([0])); - Assert.Equal(1, TensorPrimitives.SumOfSquares([0, 1])); - Assert.Equal(14, TensorPrimitives.SumOfSquares([1, 2, 3])); - Assert.Equal(18, TensorPrimitives.SumOfSquares([-3, 0, 3])); - Assert.Equal(float.NaN, TensorPrimitives.SumOfSquares([-3, float.NaN, 3])); + Assert.Equal(expected, TensorPrimitives.SumOfSquares(x)); } + #endregion + #region Tanh [Theory] - [MemberData(nameof(TensorLengths))] - public static void SumOfMagnitudes(int tensorLength) + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Tanh(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = CreateTensor(tensorLength); - Assert.Equal(Enumerable.Sum(MemoryMarshal.ToEnumerable(x.Memory), MathF.Abs), TensorPrimitives.SumOfMagnitudes(x), Tolerance); + TensorPrimitives.Tanh(x, destination); - float sum = 0; - foreach (float f in x.Span) + for (int i = 0; i < tensorLength; i++) { - sum += MathF.Abs(f); + AssertEqualTolerance(MathF.Tanh(x[i]), destination[i]); } - Assert.Equal(sum, TensorPrimitives.SumOfMagnitudes(x), Tolerance); } - [Fact] - public static void SumOfMagnitudes_KnownValues() + [Theory] + [MemberData(nameof(TensorLengthsIncluding0))] + public static void Tanh_InPlace(int tensorLength) { - Assert.Equal(0, TensorPrimitives.SumOfMagnitudes([0])); - Assert.Equal(1, TensorPrimitives.SumOfMagnitudes([0, 1])); - Assert.Equal(6, TensorPrimitives.SumOfMagnitudes([1, 2, 3])); - Assert.Equal(6, TensorPrimitives.SumOfMagnitudes([-3, 0, 3])); - Assert.Equal(float.NaN, TensorPrimitives.SumOfMagnitudes([-3, float.NaN, 3])); + using BoundedMemory x = CreateAndFillTensor(tensorLength); + float[] xOrig = x.Span.ToArray(); + + TensorPrimitives.Tanh(x, x); + + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Tanh(xOrig[i]), x[i]); + } } [Theory] - [MemberData(nameof(TensorLengthsIncluding0))] - public static void Abs(int tensorLength) + [MemberData(nameof(TensorLengths))] + public static void Tanh_SpecialValues(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); using BoundedMemory destination = CreateTensor(tensorLength); - TensorPrimitives.Abs(x, destination); + RunForEachSpecialValue(() => + { + TensorPrimitives.Tanh(x, destination); + for (int i = 0; i < tensorLength; i++) + { + AssertEqualTolerance(MathF.Tanh(x[i]), destination[i]); + } + }, x); + } - for (int i = 0; i < x.Length; i++) + [Theory] + [MemberData(nameof(VectorLengthAndIteratedRange), new object[] { -11f, 11f, 0.2f })] + public static void Tanh_ValueRange(int vectorLengths, float element) + { + float[] x = new float[vectorLengths]; + float[] dest = new float[vectorLengths]; + + x.AsSpan().Fill(element); + TensorPrimitives.Tanh(x, dest); + + float expected = MathF.Tanh(element); + foreach (float actual in dest) { - Assert.Equal(MathF.Abs(x[i]), destination[i], Tolerance); + AssertEqualTolerance(expected, actual); } } [Theory] [MemberData(nameof(TensorLengths))] - public static void Abs_ThrowsForTooShortDestination(int tensorLength) + public static void Tanh_ThrowsForTooShortDestination(int tensorLength) { using BoundedMemory x = CreateAndFillTensor(tensorLength); using BoundedMemory destination = CreateTensor(tensorLength - 1); - AssertExtensions.Throws("destination", () => TensorPrimitives.Abs(x, destination)); + AssertExtensions.Throws("destination", () => TensorPrimitives.Tanh(x, destination)); + } + + [Fact] + public static void Tanh_ThrowsForOverlapppingInputsWithOutputs() + { + float[] array = new float[10]; + AssertExtensions.Throws("destination", () => TensorPrimitives.Tanh(array.AsSpan(1, 2), array.AsSpan(0, 2))); + AssertExtensions.Throws("destination", () => TensorPrimitives.Tanh(array.AsSpan(1, 2), array.AsSpan(2, 2))); } + #endregion } } diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.netcore.cs b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.netcore.cs index 113f26048d352c..06ab341db16242 100644 --- a/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.netcore.cs +++ b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitivesTests.netcore.cs @@ -8,15 +8,16 @@ namespace System.Numerics.Tensors.Tests { public static partial class TensorPrimitivesTests { + #region ConvertToHalf [Theory] - [InlineData(0)] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void ConvertToHalf(int tensorLength) { using BoundedMemory source = CreateAndFillTensor(tensorLength); foreach (int destLength in new[] { source.Length, source.Length + 1 }) { - Half[] destination = new Half[destLength]; + using BoundedMemory destination = BoundedMemory.Allocate(destLength); + destination.Span.Fill(Half.Zero); TensorPrimitives.ConvertToHalf(source, destination); @@ -35,6 +36,28 @@ public static void ConvertToHalf(int tensorLength) } } + [Theory] + [MemberData(nameof(TensorLengths))] + public static void ConvertToHalf_SpecialValues(int tensorLength) + { + using BoundedMemory source = CreateAndFillTensor(tensorLength); + using BoundedMemory destination = BoundedMemory.Allocate(tensorLength); + + // NaN, infinities, and 0s + source[s_random.Next(source.Length)] = float.NaN; + source[s_random.Next(source.Length)] = float.PositiveInfinity; + source[s_random.Next(source.Length)] = float.NegativeInfinity; + source[s_random.Next(source.Length)] = 0; + source[s_random.Next(source.Length)] = float.NegativeZero; + + TensorPrimitives.ConvertToHalf(source, destination); + + for (int i = 0; i < source.Length; i++) + { + Assert.Equal((Half)source[i], destination[i]); + } + } + [Theory] [MemberData(nameof(TensorLengths))] public static void ConvertToHalf_ThrowsForTooShortDestination(int tensorLength) @@ -44,13 +67,14 @@ public static void ConvertToHalf_ThrowsForTooShortDestination(int tensorLength) AssertExtensions.Throws("destination", () => TensorPrimitives.ConvertToHalf(source, destination)); } + #endregion + #region ConvertToSingle [Theory] - [InlineData(0)] - [MemberData(nameof(TensorLengths))] + [MemberData(nameof(TensorLengthsIncluding0))] public static void ConvertToSingle(int tensorLength) { - Half[] source = new Half[tensorLength]; + using BoundedMemory source = BoundedMemory.Allocate(tensorLength); for (int i = 0; i < source.Length; i++) { source[i] = (Half)s_random.NextSingle(); @@ -77,6 +101,32 @@ public static void ConvertToSingle(int tensorLength) } } } + [Theory] + [MemberData(nameof(TensorLengths))] + public static void ConvertToSingle_SpecialValues(int tensorLength) + { + using BoundedMemory source = BoundedMemory.Allocate(tensorLength); + for (int i = 0; i < source.Length; i++) + { + source[i] = (Half)s_random.NextSingle(); + } + + using BoundedMemory destination = CreateTensor(tensorLength); + + // NaN, infinities, and 0s + source[s_random.Next(source.Length)] = Half.NaN; + source[s_random.Next(source.Length)] = Half.PositiveInfinity; + source[s_random.Next(source.Length)] = Half.NegativeInfinity; + source[s_random.Next(source.Length)] = Half.Zero; + source[s_random.Next(source.Length)] = Half.NegativeZero; + + TensorPrimitives.ConvertToSingle(source, destination); + + for (int i = 0; i < source.Length; i++) + { + Assert.Equal((float)source[i], destination[i]); + } + } [Theory] [MemberData(nameof(TensorLengths))] @@ -87,5 +137,6 @@ public static void ConvertToSingle_ThrowsForTooShortDestination(int tensorLength AssertExtensions.Throws("destination", () => TensorPrimitives.ConvertToSingle(source, destination)); } + #endregion } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Half.cs b/src/libraries/System.Private.CoreLib/src/System/Half.cs index 8daa37bbab576b..cd3e6ab3ed73c3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Half.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Half.cs @@ -1044,7 +1044,7 @@ public static explicit operator float(Half value) // BitConverter.SingleToUInt32Bits(1.0f) - ((uint)BitConverter.HalfToUInt16Bits((Half)1.0f) << 13) const uint ExponentOffset = 0x3800_0000u; // Mask for sign bit in Single - const uint FloatSignMask = float.SignMask; + const uint SingleSignMask = float.SignMask; // Mask for exponent bits in Half const uint HalfExponentMask = BiasedExponentMask; // Mask for bits in Single converted from Half @@ -1052,7 +1052,7 @@ public static explicit operator float(Half value) // Extract the internal representation of value short valueInInt16Bits = BitConverter.HalfToInt16Bits(value); // Extract sign bit of value - uint sign = (uint)(int)valueInInt16Bits & FloatSignMask; + uint sign = (uint)(int)valueInInt16Bits & SingleSignMask; // Copy sign bit to upper bits uint bitValueInProcess = (uint)valueInInt16Bits; // Extract exponent bits of value (BiasedExponent is not for here as it performs unnecessary shift) From 53d99163de462dae9121e5edc925b98f19825665 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 16:07:05 -0700 Subject: [PATCH 417/783] [release/8.0] Add package readme to System.Numerics.Tensors (#93806) * Add package readme to System.Numerics.Tensors * Update src/libraries/System.Numerics.Tensors/src/PACKAGE.md * Update src/libraries/System.Numerics.Tensors/src/PACKAGE.md * Update src/libraries/System.Numerics.Tensors/src/PACKAGE.md Co-authored-by: Stephen Toub --------- Co-authored-by: Eric StJohn Co-authored-by: Stephen Toub --- .../System.Numerics.Tensors/src/PACKAGE.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/libraries/System.Numerics.Tensors/src/PACKAGE.md diff --git a/src/libraries/System.Numerics.Tensors/src/PACKAGE.md b/src/libraries/System.Numerics.Tensors/src/PACKAGE.md new file mode 100644 index 00000000000000..c5670c1c0f9893 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/PACKAGE.md @@ -0,0 +1,53 @@ +## About + +Provides methods for performing mathematical operations over _tensors_ represented as spans. These methods are accelerated to use SIMD (Single instruction, multiple data) operations supported by the CPU where available. + +## Key Features + +* Numerical operations on tensors represented as `ReadOnlySpan` +* Element-wise arithmetic: Add, Subtract, Multiply, Divide, Exp, Log, Cosh, Tanh, etc. +* Tensor arithmetic: CosineSimilarity, Distance, Dot, Normalize, Softmax, Sigmoid, etc. + +## How to Use + +```C# +using System.Numerics.Tensors; + +var movies = new[] { + new { Title="The Lion King", Embedding= new [] { 0.10022575f, -0.23998135f } }, + new { Title="Inception", Embedding= new [] { 0.10327095f, 0.2563685f } }, + new { Title="Toy Story", Embedding= new [] { 0.095857024f, -0.201278f } }, + new { Title="Pulp Function", Embedding= new [] { 0.106827796f, 0.21676421f } }, + new { Title="Shrek", Embedding= new [] { 0.09568083f, -0.21177962f } } +}; +var queryEmbedding = new[] { 0.12217915f, -0.034832448f }; + +var top3MoviesTensorPrimitives = + movies + .Select(movie => + ( + movie.Title, + Similarity: TensorPrimitives.CosineSimilarity(queryEmbedding, movie.Embedding) + )) + .OrderByDescending(movies => movies.Similarity) + .Take(3); + +foreach (var movie in top3MoviesTensorPrimitives) +{ + Console.WriteLine(movie); +} +``` + +## Main Types + +The main types provided by this library are: + +* `System.Numerics.Tensors.TensorPrimitives` + +## Additional Documentation + +* [API documentation](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.tensors) + +## Feedback & Contributing + +System.Numerics.Tensors is released as open source under the [MIT license](https://licenses.nuget.org/MIT). Bug reports and contributions are welcome at [the GitHub repository](https://github.com/dotnet/runtime). From 11ad607efb2b31c5e1b906303fcd70341e9d5206 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 16:16:14 -0700 Subject: [PATCH 418/783] Add runtime base address to Native AOT crash info JSON (#93791) The Native AOT Watson and SOS support needs to the module's base address containing the runtime for adequate performance. Add the module base address in the crash info as "runtime_base". Changed the "runtime" to the clearer "runtime_version" property. Verified the address in local testing. Modified the !crashinfo command in SOS to display this new base address. Very low. Native AOT unhandled exception crash info. Co-authored-by: Mike McLaughlin --- .../System.Private.CoreLib/src/System/CrashInfo.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs index 8a2f33c93f1f8c..c2421fc6b4ceb9 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs @@ -103,12 +103,17 @@ private bool WriteHeader(RhFailFastReason reason, ulong crashingThreadId, string if (!WriteValue("version"u8, "1.0.0"u8)) return false; - if (!WriteValue("runtime"u8, new ReadOnlySpan(RuntimeImports.RhGetRuntimeVersion(out int cbLength), cbLength))) + static void Dummy() { } + + if (!WriteHexValue("runtime_base"u8, (ulong)RuntimeImports.RhGetOSModuleFromPointer((nint)(void*)(delegate*)&Dummy))) return false; if (!WriteIntValue("runtime_type"u8, (int)RuntimeType.NativeAOT)) return false; + if (!WriteValue("runtime_version"u8, new ReadOnlySpan(RuntimeImports.RhGetRuntimeVersion(out int cbLength), cbLength))) + return false; + CrashReason crashReason = reason switch { RhFailFastReason.EnvironmentFailFast => CrashReason.EnvironmentFailFast, From 3eca894deca3d72a5b0f8139caa624c7376301f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Fri, 20 Oct 2023 16:22:43 -0700 Subject: [PATCH 419/783] [release/8.0] Stable branding for .NET 8 GA --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 189fb6671d44b9..bb58d6b88e9e7c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -13,7 +13,7 @@ - false + true release -$(PreReleaseVersionLabel) -$(PreReleaseVersionLabel).$(PreReleaseVersionIteration) From d14b1e81e19d44b6ab1ec7f672478a91607d0886 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Fri, 20 Oct 2023 21:40:23 -0500 Subject: [PATCH 420/783] Handle an empty bandPreleaseVersion --- src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs index 62817719af0a14..21170ea2152843 100644 --- a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs +++ b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs @@ -301,8 +301,8 @@ private bool InstallWorkloadManifest(ITaskItem workloadId, string name, string v string packagePreleaseVersion = bandVersionRegex().Match(version).Groups[1].Value; string bandPreleaseVersion = bandVersionRegex().Match(bandVersion).Groups[1].Value; - if (packagePreleaseVersion != bandPreleaseVersion && packagePreleaseVersion != "-dev" && packagePreleaseVersion != "-ci") - bandVersion = bandVersion.Replace (bandPreleaseVersion, packagePreleaseVersion); + if (packagePreleaseVersion != bandPreleaseVersion && packagePreleaseVersion != "-dev" && packagePreleaseVersion != "-ci" && bandPreleaseVersion != "") + bandVersion = bandVersion.Replace(bandPreleaseVersion, packagePreleaseVersion); PackageReference pkgRef = new(Name: $"{name}.Manifest-{bandVersion}", Version: version, From 14a0bbcdedf2440fbeb67c670e9c30d1e22cccef Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 06:26:29 -0500 Subject: [PATCH 421/783] [release/8.0] Update dependencies from dotnet/emsdk (#93801) * Update dependencies from https://github.com/dotnet/emsdk build 20231020.2 Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rtm.23511.3 -> To Version 8.0.0-rtm.23520.2 * switch to the stable version now * Update dependencies * Also fix the trigger * pin the wbt sdk to avoid the latest analizer nonsense * Use source generation for the serializer * Try to make sourcebuild happy * Try again to make sourcebuild happy * Use reflection and suppress trim analysis instead This reverts commit 768b65bab585f303bca6e0e9a36cf06d59e90387. * Fix reverting too much --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Larry Ewing --- NuGet.config | 5 ++ eng/Version.Details.xml | 68 ++++++++++--------- eng/Versions.props | 6 +- eng/pipelines/common/xplat-setup.yml | 2 +- .../WasmBasicTestApp/WasmBasicTestApp.csproj | 1 + 5 files changed, 46 insertions(+), 36 deletions(-) diff --git a/NuGet.config b/NuGet.config index 80dd215a4bf01b..423372ca9017d9 100644 --- a/NuGet.config +++ b/NuGet.config @@ -7,6 +7,11 @@ + + + + + - 8.0.0-rtm.23511.3 - $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) + 8.0.0 + $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda 1.0.0-v3.14.0.5722 @@ -258,7 +258,7 @@ 3.1.7 1.0.406601 - 8.0.100-rtm.23478.7 + 8.0.100-rtm.23506.1 diff --git a/eng/pipelines/common/xplat-setup.yml b/eng/pipelines/common/xplat-setup.yml index 28257b05265ba0..eb19570aeecac2 100644 --- a/eng/pipelines/common/xplat-setup.yml +++ b/eng/pipelines/common/xplat-setup.yml @@ -108,7 +108,7 @@ jobs: - ${{ if eq(parameters.archType, 'wasm') }}: - name: wasmDarcDependenciesChanged value: $[ or( - eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport'], true), + eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100'], true), eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_DotNet_Build_Tasks_Workloads'], true), eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.System_Runtime_TimeZoneData'], true), eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_Net_Compilers_Toolset'], true), diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj b/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj index 33858b9a6a755f..761ac6354ce861 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj +++ b/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj @@ -4,6 +4,7 @@ browser-wasm Exe true + true From e1da68dcd2ac0df0f861e2b3443de0539e34ea48 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 17:22:57 +0200 Subject: [PATCH 422/783] [release/8.0] Update APICompat settings under source build (#93865) * Update APICompat settings under source build * Update resolveContract.targets --------- Co-authored-by: Viktor Hofer --- eng/resolveContract.targets | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/eng/resolveContract.targets b/eng/resolveContract.targets index 6d414f46f93e6b..3454d7064739a8 100644 --- a/eng/resolveContract.targets +++ b/eng/resolveContract.targets @@ -73,8 +73,9 @@ That is necessary as APICompat is invoked twice, once for the ref <-> src comparision and then again for the package validation (which doesn't include reference assemblies). As both operations don't have all the inputs available, some suppressions might only apply to one or the other and hence unnecessary - suppressions can't be determined. --> - + suppressions can't be determined. + Disable the validation under source build as that might use an out-of-date SDK and not the ApiCompat.Task package. --> + true true From 1c9b5ee4cb7a45affb2b47bff7f9c2d7be26ac15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Mon, 23 Oct 2023 19:48:04 +0200 Subject: [PATCH 423/783] Override InformationalVersion for NativeAOT corelib too --- src/coreclr/nativeaot/Directory.Build.props | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/nativeaot/Directory.Build.props b/src/coreclr/nativeaot/Directory.Build.props index ebfa725e4efd2c..005d6ae997adab 100644 --- a/src/coreclr/nativeaot/Directory.Build.props +++ b/src/coreclr/nativeaot/Directory.Build.props @@ -25,6 +25,9 @@ false v4.0.30319 + + $(ProductVersion) + $(ProductVersion) $(NoWarn),0419,0649,CA2249,CA1830 From d8d69276650adcc2549804d053a0145763d39765 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 13:34:35 -0700 Subject: [PATCH 424/783] [release/8.0] Improve performance of UnmanagedMemoryStream (#93812) * Improve performance of UnmanagedMemoryStream UnmanagedMemoryStream used Interlocked operations to update its state to prevent tearing of 64-bit values on 32-bit platforms. This pattern is expensive in general and it was found to be prohibitively expensive on recent hardware.. This change removes the expensive Interlocked operations and addresses the tearing issues in alternative way: - The _length field is converted to nuint that is guaranteed to be updated atomically. - Writes to _length field are volatile to guaranteed the unininitialized memory cannot be read. - The _position field remains long and it has a risk of tearing. It is not a problem since tearing of this field cannot lead to buffer overruns. Fixes #93624 * Add comment --------- Co-authored-by: Jan Kotas --- .../src/System/IO/UnmanagedMemoryStream.cs | 126 +++++++++--------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs index 5f049e69445381..b2a3134ae7501a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs @@ -23,14 +23,9 @@ namespace System.IO * of the UnmanagedMemoryStream. * 3) You clean up the memory when appropriate. The UnmanagedMemoryStream * currently will do NOTHING to free this memory. - * 4) All calls to Write and WriteByte may not be threadsafe currently. - * - * It may become necessary to add in some sort of - * DeallocationMode enum, specifying whether we unmap a section of memory, - * call free, run a user-provided delegate to free the memory, etc. - * We'll suggest user write a subclass of UnmanagedMemoryStream that uses - * a SafeHandle subclass to hold onto the memory. - * + * 4) This type is not thread safe. However, the implementation should prevent buffer + * overruns or returning uninitialized memory when Reads and Writes are called + * concurrently in thread unsafe manner. */ /// @@ -40,10 +35,10 @@ public class UnmanagedMemoryStream : Stream { private SafeBuffer? _buffer; private unsafe byte* _mem; - private long _length; - private long _capacity; - private long _position; - private long _offset; + private nuint _capacity; + private nuint _offset; + private nuint _length; // nuint to guarantee atomic access on 32-bit platforms + private long _position; // long to allow seeking to any location beyond the length of the stream. private FileAccess _access; private bool _isOpen; private CachedCompletedInt32Task _lastReadTask; // The last successful task returned from ReadAsync @@ -123,10 +118,10 @@ protected void Initialize(SafeBuffer buffer, long offset, long length, FileAcces } } - _offset = offset; + _offset = (nuint)offset; _buffer = buffer; - _length = length; - _capacity = length; + _length = (nuint)length; + _capacity = (nuint)length; _access = access; _isOpen = true; } @@ -171,8 +166,8 @@ protected unsafe void Initialize(byte* pointer, long length, long capacity, File _mem = pointer; _offset = 0; - _length = length; - _capacity = capacity; + _length = (nuint)length; + _capacity = (nuint)capacity; _access = access; _isOpen = true; } @@ -259,7 +254,7 @@ public override long Length get { EnsureNotClosed(); - return Interlocked.Read(ref _length); + return (long)_length; } } @@ -271,7 +266,7 @@ public long Capacity get { EnsureNotClosed(); - return _capacity; + return (long)_capacity; } } @@ -283,14 +278,14 @@ public override long Position get { if (!CanSeek) ThrowHelper.ThrowObjectDisposedException_StreamClosed(null); - return Interlocked.Read(ref _position); + return _position; } set { ArgumentOutOfRangeException.ThrowIfNegative(value); if (!CanSeek) ThrowHelper.ThrowObjectDisposedException_StreamClosed(null); - Interlocked.Exchange(ref _position, value); + _position = value; } } @@ -308,11 +303,10 @@ public unsafe byte* PositionPointer EnsureNotClosed(); // Use a temp to avoid a race - long pos = Interlocked.Read(ref _position); - if (pos > _capacity) + long pos = _position; + if (pos > (long)_capacity) throw new IndexOutOfRangeException(SR.IndexOutOfRange_UMSPosition); - byte* ptr = _mem + pos; - return ptr; + return _mem + pos; } set { @@ -327,7 +321,7 @@ public unsafe byte* PositionPointer if (newPosition < 0) throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_UnmanagedMemStreamLength); - Interlocked.Exchange(ref _position, newPosition); + _position = newPosition; } } @@ -367,8 +361,13 @@ internal int ReadCore(Span buffer) // Use a local variable to avoid a race where another thread // changes our position after we decide we can read some bytes. - long pos = Interlocked.Read(ref _position); - long len = Interlocked.Read(ref _length); + long pos = _position; + + // Use a volatile read to prevent reading of the uninitialized memory. This volatile read + // and matching volatile write that set _length avoids reordering of NativeMemory.Clear + // operations with reading of the buffer below. + long len = (long)Volatile.Read(ref _length); + long n = Math.Min(len - pos, buffer.Length); if (n <= 0) { @@ -407,7 +406,7 @@ internal int ReadCore(Span buffer) } } - Interlocked.Exchange(ref _position, pos + n); + _position = pos + n; return nInt; } @@ -484,11 +483,16 @@ public override int ReadByte() EnsureNotClosed(); EnsureReadable(); - long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition - long len = Interlocked.Read(ref _length); + long pos = _position; // Use a local to avoid a race condition + + // Use a volatile read to prevent reading of the uninitialized memory. This volatile read + // and matching volatile write that set _length avoids reordering of NativeMemory.Clear + // operations with reading of the buffer below. + long len = (long)Volatile.Read(ref _length); + if (pos >= len) return -1; - Interlocked.Exchange(ref _position, pos + 1); + _position = pos + 1; int result; if (_buffer != null) { @@ -529,35 +533,33 @@ public override long Seek(long offset, SeekOrigin loc) { EnsureNotClosed(); + long newPosition; switch (loc) { case SeekOrigin.Begin: - if (offset < 0) + newPosition = offset; + if (newPosition < 0) throw new IOException(SR.IO_SeekBeforeBegin); - Interlocked.Exchange(ref _position, offset); break; case SeekOrigin.Current: - long pos = Interlocked.Read(ref _position); - if (offset + pos < 0) + newPosition = _position + offset; + if (newPosition < 0) throw new IOException(SR.IO_SeekBeforeBegin); - Interlocked.Exchange(ref _position, offset + pos); break; case SeekOrigin.End: - long len = Interlocked.Read(ref _length); - if (len + offset < 0) + newPosition = (long)_length + offset; + if (newPosition < 0) throw new IOException(SR.IO_SeekBeforeBegin); - Interlocked.Exchange(ref _position, len + offset); break; default: throw new ArgumentException(SR.Argument_InvalidSeekOrigin); } - long finalPos = Interlocked.Read(ref _position); - Debug.Assert(finalPos >= 0, "_position >= 0"); - return finalPos; + _position = newPosition; + return newPosition; } /// @@ -573,11 +575,10 @@ public override void SetLength(long value) EnsureNotClosed(); EnsureWriteable(); - if (value > _capacity) + if (value > (long)_capacity) throw new IOException(SR.IO_FixedCapacity); - long pos = Interlocked.Read(ref _position); - long len = Interlocked.Read(ref _length); + long len = (long)_length; if (value > len) { unsafe @@ -585,10 +586,11 @@ public override void SetLength(long value) NativeMemory.Clear(_mem + len, (nuint)(value - len)); } } - Interlocked.Exchange(ref _length, value); - if (pos > value) + Volatile.Write(ref _length, (nuint)value); // volatile to prevent reading of uninitialized memory + + if (_position > value) { - Interlocked.Exchange(ref _position, value); + _position = value; } } @@ -625,8 +627,8 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) EnsureNotClosed(); EnsureWriteable(); - long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition - long len = Interlocked.Read(ref _length); + long pos = _position; // Use a local to avoid a race condition + long len = (long)_length; long n = pos + buffer.Length; // Check for overflow if (n < 0) @@ -634,7 +636,7 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) throw new IOException(SR.IO_StreamTooLong); } - if (n > _capacity) + if (n > (long)_capacity) { throw new NotSupportedException(SR.IO_FixedCapacity); } @@ -648,16 +650,16 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) NativeMemory.Clear(_mem + len, (nuint)(pos - len)); } - // set length after zeroing memory to avoid race condition of accessing unzeroed memory + // set length after zeroing memory to avoid race condition of accessing uninitialized memory if (n > len) { - Interlocked.Exchange(ref _length, n); + Volatile.Write(ref _length, (nuint)n); // volatile to prevent reading of uninitialized memory } } if (_buffer != null) { - long bytesLeft = _capacity - pos; + long bytesLeft = (long)_capacity - pos; if (bytesLeft < buffer.Length) { throw new ArgumentException(SR.Arg_BufferTooSmall); @@ -682,8 +684,7 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) Buffer.Memmove(ref *(_mem + pos), ref MemoryMarshal.GetReference(buffer), (nuint)buffer.Length); } - Interlocked.Exchange(ref _position, n); - return; + _position = n; } /// @@ -754,8 +755,8 @@ public override void WriteByte(byte value) EnsureNotClosed(); EnsureWriteable(); - long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition - long len = Interlocked.Read(ref _length); + long pos = _position; // Use a local to avoid a race condition + long len = (long)_length; long n = pos + 1; if (pos >= len) { @@ -763,7 +764,7 @@ public override void WriteByte(byte value) if (n < 0) throw new IOException(SR.IO_StreamTooLong); - if (n > _capacity) + if (n > (long)_capacity) throw new NotSupportedException(SR.IO_FixedCapacity); // Check to see whether we are now expanding the stream and must @@ -779,8 +780,7 @@ public override void WriteByte(byte value) } } - // set length after zeroing memory to avoid race condition of accessing unzeroed memory - Interlocked.Exchange(ref _length, n); + Volatile.Write(ref _length, (nuint)n); // volatile to prevent reading of uninitialized memory } } @@ -810,7 +810,7 @@ public override void WriteByte(byte value) _mem[pos] = value; } } - Interlocked.Exchange(ref _position, n); + _position = n; } } } From b1abc322c7be91f14aaa27e992511c3e22a51c3c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 13:36:15 -0700 Subject: [PATCH 425/783] Update dependencies from https://github.com/dotnet/emsdk build 20231023.2 (#93881) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.0-rtm.23520.2 -> To Version 8.0.0-rtm.23523.2 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 423372ca9017d9..29f8225aac34fb 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Versions.props b/eng/Versions.props index 7bca669addc848..6fef84713ea81c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From 488a8a3521610422e8fbe22d5cc66127f3dce3dc Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 23 Oct 2023 22:26:57 -0400 Subject: [PATCH 427/783] [release/8.0][wasm] Fix perf pipeline runs (#93888) * Remove --experimental-wasm-eh argument from the wasm_args used for wasm performance runs. (#93357) (cherry picked from commit a770017fea3549e0bf88f7c619b79a731271e305) * performance-setup.sh: Use `release/8.0` as the default channel * performance-setup.ps1: use release/8.0 as the default channel * Fix passing wasmArgs for bdn --------- Co-authored-by: Parker Bibus --- eng/testing/performance/performance-setup.ps1 | 2 +- eng/testing/performance/performance-setup.sh | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/eng/testing/performance/performance-setup.ps1 b/eng/testing/performance/performance-setup.ps1 index 8caea345a893dc..8a8cd269dbe454 100644 --- a/eng/testing/performance/performance-setup.ps1 +++ b/eng/testing/performance/performance-setup.ps1 @@ -101,7 +101,7 @@ if ($iOSNativeAOT) { } # FIX ME: This is a workaround until we get this from the actual pipeline -$CleanedBranchName = "main" +$CleanedBranchName = "release/8.0" if($Branch.Contains("refs/heads/release")) { $CleanedBranchName = $Branch.replace('refs/heads/', '') diff --git a/eng/testing/performance/performance-setup.sh b/eng/testing/performance/performance-setup.sh index 9a1c95ec730820..c53ca6924b97b4 100755 --- a/eng/testing/performance/performance-setup.sh +++ b/eng/testing/performance/performance-setup.sh @@ -358,9 +358,7 @@ if [[ "$physicalpromotion" == "true" ]]; then configurations="$configurations PhysicalPromotionType=physicalpromotion" fi - - -cleaned_branch_name="main" +cleaned_branch_name="release/8.0" if [[ $branch == *"refs/heads/release"* ]]; then cleaned_branch_name=${branch/refs\/heads\//} fi @@ -404,15 +402,14 @@ if [[ -n "$wasm_bundle_directory" ]]; then using_wasm=true wasm_bundle_directory_path=$payload_directory mv $wasm_bundle_directory/* $wasm_bundle_directory_path - find $wasm_bundle_directory_path -type d - wasm_args="--experimental-wasm-eh --expose_wasm" + wasm_args="--expose_wasm" if [ "$javascript_engine" == "v8" ]; then # for es6 module support wasm_args="$wasm_args --module" fi # Workaround: escaping the quotes around `--wasmArgs=..` so they get retained for the actual command line - extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --wasmEngine /home/helixbot/.jsvu/bin/$javascript_engine --wasmArgs \\\"$wasm_args\\\" --cli \$HELIX_CORRELATION_PAYLOAD/dotnet/dotnet --wasmDataDir \$HELIX_CORRELATION_PAYLOAD/wasm-data" + extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --wasmEngine /home/helixbot/.jsvu/bin/$javascript_engine \\\"--wasmArgs=$wasm_args\\\" --cli \$HELIX_CORRELATION_PAYLOAD/dotnet/dotnet --wasmDataDir \$HELIX_CORRELATION_PAYLOAD/wasm-data" if [[ "$wasmaot" == "true" ]]; then extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --aotcompilermode wasm --buildTimeout 3600" fi From 59edaad404d1b8e47080015ae8d0787f94c970df Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 13:21:59 -0700 Subject: [PATCH 428/783] [release/8.0] Honor JsonSerializerOptions.PropertyNameCaseInsensitive in property name conflict resolution. (#93935) * Honor JsonSerializerOptions.PropertyNameCaseInsensitive in property name conflict resolution. * Update src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs Co-authored-by: Jeff Handley * Address feedback --------- Co-authored-by: Eirik Tsarpalis Co-authored-by: Jeff Handley --- .../gen/JsonSourceGenerator.Parser.cs | 7 ++--- .../DefaultJsonTypeInfoResolver.Helpers.cs | 2 +- .../Metadata/JsonMetadataServices.Helpers.cs | 2 +- .../Serialization/Metadata/JsonTypeInfo.cs | 5 ++-- .../tests/Common/PropertyNameTests.cs | 29 +++++++++++++++++++ .../Serialization/PropertyNameTests.cs | 2 ++ 6 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs index e0dac6a9ad82ce..594f7ad9770c3c 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs @@ -863,7 +863,7 @@ private List ParsePropertyGenerationSpecs( { Location? typeLocation = typeToGenerate.Location; List properties = new(); - PropertyHierarchyResolutionState state = new(); + PropertyHierarchyResolutionState state = new(options); hasExtensionDataProperty = false; // Walk the type hierarchy starting from the current type up to the base type(s) @@ -970,11 +970,10 @@ bool PropertyIsOverriddenAndIgnored(IPropertySymbol property, Dictionary Properties = new(); - public Dictionary AddedProperties = new(); + public Dictionary AddedProperties = new(options?.PropertyNameCaseInsensitive == true ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal); public Dictionary? IgnoredMembers; public bool IsPropertyOrderSpecified; public bool HasInvalidConfigurationForFastPath; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs index c654a920f8ff6e..3f929d87378485 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs @@ -88,7 +88,7 @@ private static void PopulateProperties(JsonTypeInfo typeInfo) bool constructorHasSetsRequiredMembersAttribute = typeInfo.Converter.ConstructorInfo?.HasSetsRequiredMembersAttribute() ?? false; - JsonTypeInfo.PropertyHierarchyResolutionState state = new(); + JsonTypeInfo.PropertyHierarchyResolutionState state = new(typeInfo.Options); // Walk the type hierarchy starting from the current type up to the base type(s) foreach (Type currentType in typeInfo.Type.GetSortedTypeHierarchy()) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs index 1b7113f9dd758a..965b4cea39570a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs @@ -137,7 +137,7 @@ internal static void PopulateProperties(JsonTypeInfo typeInfo, JsonTypeInfo.Json // Regardless of the source generator we need to re-run the naming conflict resolution algorithm // at run time since it is possible that the naming policy or other configs can be different then. - JsonTypeInfo.PropertyHierarchyResolutionState state = new(); + JsonTypeInfo.PropertyHierarchyResolutionState state = new(typeInfo.Options); foreach (JsonPropertyInfo jsonPropertyInfo in properties) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs index a1a184f6059d2b..668e0c7b15e1a1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs @@ -992,10 +992,9 @@ public JsonPropertyInfo CreateJsonPropertyInfo(Type propertyType, string name) internal abstract ValueTask DeserializeAsObjectAsync(Stream utf8Json, CancellationToken cancellationToken); internal abstract object? DeserializeAsObject(Stream utf8Json); - internal ref struct PropertyHierarchyResolutionState + internal ref struct PropertyHierarchyResolutionState(JsonSerializerOptions options) { - public PropertyHierarchyResolutionState() { } - public Dictionary AddedProperties = new(); + public Dictionary AddedProperties = new(options.PropertyNameCaseInsensitive ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal); public Dictionary? IgnoredProperties; public bool IsPropertyOrderSpecified; } diff --git a/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs b/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs index 4295359c6f0380..021481ae5a1362 100644 --- a/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs +++ b/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs @@ -494,5 +494,34 @@ public class ClassWithSpecialCharacters [JsonPropertyName("\uA000_2")] // Valid C# property name: \uA000_2 public int YiIt_2 { get; set; } } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task ClassWithIgnoredCaseInsensitiveConflict_RespectsIgnoredMember(bool propertyNameCaseInsensitive) + { + // Regression test for https://github.com/dotnet/runtime/issues/93903 + // specifically for propertyNameCaseInsensitive := true + + JsonSerializerOptions options = Serializer.CreateOptions(makeReadOnly: false); + options.PropertyNameCaseInsensitive = propertyNameCaseInsensitive; + + var value = new ClassWithIgnoredCaseInsensitiveConflict { name = "lowercase", Name = "uppercase" }; + string json = await Serializer.SerializeWrapper(value, options); + + Assert.Equal("""{"name":"lowercase"}""", json); + + value = await Serializer.DeserializeWrapper(json, options); + Assert.Equal("lowercase", value.name); + Assert.Null(value.Name); + } + + public class ClassWithIgnoredCaseInsensitiveConflict + { + public string name { get; set; } + + [JsonIgnore] + public string Name { get; set; } + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs index 82566bf7123ce7..e512451eed72bc 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs @@ -28,6 +28,7 @@ public PropertyNameTests_Metadata() [JsonSerializable(typeof(ObjectPropertyNamesDifferentByCaseOnly_TestClass))] [JsonSerializable(typeof(OverridePropertyNameDesignTime_TestClass))] [JsonSerializable(typeof(SimpleTestClass))] + [JsonSerializable(typeof(ClassWithIgnoredCaseInsensitiveConflict))] internal sealed partial class PropertyNameTestsContext_Metadata : JsonSerializerContext { } @@ -53,6 +54,7 @@ public PropertyNameTests_Default() [JsonSerializable(typeof(ObjectPropertyNamesDifferentByCaseOnly_TestClass))] [JsonSerializable(typeof(OverridePropertyNameDesignTime_TestClass))] [JsonSerializable(typeof(SimpleTestClass))] + [JsonSerializable(typeof(ClassWithIgnoredCaseInsensitiveConflict))] internal sealed partial class PropertyNameTestsContext_Default : JsonSerializerContext { } From 01d208d45c49f8300d25ea748fe2734dc546ac70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Wed, 25 Oct 2023 16:44:24 +0200 Subject: [PATCH 429/783] [release/8.0] Don't use File.OpenWrite when trying to overwrite a file (#93854) --- .../MonoTargetsTasks/RuntimeConfigParser/RuntimeConfigParser.cs | 2 +- src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs | 2 +- src/tools/illink/src/linker/Linker/DgmlDependencyRecorder.cs | 2 +- src/tools/illink/src/linker/Linker/XmlDependencyRecorder.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tasks/MonoTargetsTasks/RuntimeConfigParser/RuntimeConfigParser.cs b/src/tasks/MonoTargetsTasks/RuntimeConfigParser/RuntimeConfigParser.cs index 612df3cc9f0fef..2188e4250b3cbf 100644 --- a/src/tasks/MonoTargetsTasks/RuntimeConfigParser/RuntimeConfigParser.cs +++ b/src/tasks/MonoTargetsTasks/RuntimeConfigParser/RuntimeConfigParser.cs @@ -61,7 +61,7 @@ public override bool Execute() ConvertDictionaryToBlob(configProperties, blobBuilder); Directory.CreateDirectory(Path.GetDirectoryName(OutputFile!)!); - using var stream = File.OpenWrite(OutputFile); + using var stream = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None); blobBuilder.WriteContentTo(stream); return !Log.HasLoggedErrors; diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs b/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs index b5a6539e2cb87b..c533e404c41739 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs @@ -152,7 +152,7 @@ protected virtual void UpdateRuntimeConfigJson() AddToRuntimeConfig(wasmHostProperties: wasmHostProperties, runtimeArgsArray: runtimeArgsArray, perHostConfigs: perHostConfigs); string dstPath = Path.Combine(AppDir!, Path.GetFileName(runtimeConfigPath)); - using FileStream? fs = File.OpenWrite(dstPath); + using FileStream? fs = new FileStream(dstPath, FileMode.Create, FileAccess.Write, FileShare.None); using var writer = new Utf8JsonWriter(fs, new JsonWriterOptions { Indented = true }); rootObject.WriteTo(writer); _fileWrites.Add(dstPath); diff --git a/src/tools/illink/src/linker/Linker/DgmlDependencyRecorder.cs b/src/tools/illink/src/linker/Linker/DgmlDependencyRecorder.cs index eed05fc7108484..0e862b62b73cd7 100644 --- a/src/tools/illink/src/linker/Linker/DgmlDependencyRecorder.cs +++ b/src/tools/illink/src/linker/Linker/DgmlDependencyRecorder.cs @@ -38,7 +38,7 @@ public DgmlDependencyRecorder (LinkContext context, string? fileName = null) Directory.CreateDirectory (context.OutputDirectory); } - var depsFile = File.OpenWrite (fileName); + var depsFile = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None); stream = depsFile; writer = XmlWriter.Create (stream, settings); diff --git a/src/tools/illink/src/linker/Linker/XmlDependencyRecorder.cs b/src/tools/illink/src/linker/Linker/XmlDependencyRecorder.cs index 6c386ac367c9bf..189e6fa274efa4 100644 --- a/src/tools/illink/src/linker/Linker/XmlDependencyRecorder.cs +++ b/src/tools/illink/src/linker/Linker/XmlDependencyRecorder.cs @@ -61,7 +61,7 @@ public XmlDependencyRecorder (LinkContext context, string? fileName = null) Directory.CreateDirectory (context.OutputDirectory); } - var depsFile = File.OpenWrite (fileName); + var depsFile = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None); stream = depsFile; writer = XmlWriter.Create (stream, settings); From 2066e8f214a187fb7d039a519808ca67a11b0368 Mon Sep 17 00:00:00 2001 From: Matt Mitchell Date: Wed, 25 Oct 2023 17:13:10 +0000 Subject: [PATCH 430/783] Apply suggestions from code review --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 4d15f289d8eba8..ed16dbfe0a219a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -219,7 +219,7 @@ 8.0.0-rtm.23511.1 - 2.2.2 + 2.2.3 8.0.0-alpha.1.23468.1 16.0.5-alpha.1.23478.1 From 7331dcb60e0fd7c74a6f7216d61819c9f57a1ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Wed, 25 Oct 2023 14:34:17 -0600 Subject: [PATCH 431/783] [8.0] Update MsQuic (#93979) --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 4d15f289d8eba8..ed16dbfe0a219a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -219,7 +219,7 @@ 8.0.0-rtm.23511.1 - 2.2.2 + 2.2.3 8.0.0-alpha.1.23468.1 16.0.5-alpha.1.23478.1 From 4e7c8ab228943fbc0bd6ef57df2c88428d5c239f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 17:58:48 -0600 Subject: [PATCH 432/783] Update library-servicing doc to mention 8.0 (#94002) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- docs/project/library-servicing.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/project/library-servicing.md b/docs/project/library-servicing.md index dd5f4b3a766a81..bea41e65265b46 100644 --- a/docs/project/library-servicing.md +++ b/docs/project/library-servicing.md @@ -4,6 +4,7 @@ This document provides the steps that need to be followed after modifying a libr Servicing branches represent shipped versions of .NET, and their name is in the format `release/X.0-staging`. Examples: +- `release/8.0-staging` - `release/7.0-staging` - `release/6.0-staging` @@ -32,11 +33,12 @@ All the servicing change must go through an approval process. You have two ways - By manually creating your PR using [this template](https://raw.githubusercontent.com/dotnet/runtime/main/.github/PULL_REQUEST_TEMPLATE/servicing_pull_request_template.md). - Or by asking the bot to automatically create the servicing PR for you using a merged `main` PR as source. This method requires typing an AzDO backport command as a comment of your merged PR using the format `/backport to release/X.0-staging`. Examples: -- + + - `/backport to release/8.0-staging` - `/backport to release/7.0-staging` - `/backport to release/6.0-staging` -For both cases, you must: +For all cases, you must: - Fill out the template of the PR description. - Bring it to the attention of the [engineering lead responsible for the area](~/docs/area-owners.md). From 0f65b75d2512cd51e599604c271b86c43d7c2820 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Fri, 27 Oct 2023 13:02:50 -0500 Subject: [PATCH 433/783] Try pinning the installer version to a 8.01xx sdk --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index ed16dbfe0a219a..788b7c1ab4ea96 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -258,7 +258,7 @@ 3.1.7 1.0.406601 - 8.0.100-rtm.23506.1 - + 8.0.100-rtm.23527.6 + $(MicrosoftDotnetSdkInternalVersion) From b261d029f6306e6169ac69584b1937e62fc4f2b8 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Fri, 27 Oct 2023 15:41:17 -0500 Subject: [PATCH 434/783] [release/8.0][wasm] WBT Stop taking latest sdk in release/8.0 (#94097) * Pin the SdkVersionForWorkloadTesting to 1.xx for now * Work around illink 8.0.0 not being locally built for now * Disable downlevel tests targetting unreleased versions --- eng/Versions.props | 4 ++-- src/mono/wasi/Wasi.Build.Tests/data/nuget8.config | 5 +++++ src/mono/wasm/Wasm.Build.Tests/NonWasmTemplateBuildTests.cs | 3 +++ src/mono/wasm/Wasm.Build.Tests/data/nuget8.config | 5 +++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index c9ccb7ba58fc5a..5ca3d1b92ac3e1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -258,7 +258,7 @@ 3.1.7 1.0.406601 - 8.0.100-rtm.23478.7 - + 8.0.100-rtm.23527.6 + $(MicrosoftDotnetSdkInternalVersion) diff --git a/src/mono/wasi/Wasi.Build.Tests/data/nuget8.config b/src/mono/wasi/Wasi.Build.Tests/data/nuget8.config index dfdc8009c6a5d5..4c33988a4365b8 100644 --- a/src/mono/wasi/Wasi.Build.Tests/data/nuget8.config +++ b/src/mono/wasi/Wasi.Build.Tests/data/nuget8.config @@ -9,6 +9,11 @@ + + + + + diff --git a/src/mono/wasm/Wasm.Build.Tests/NonWasmTemplateBuildTests.cs b/src/mono/wasm/Wasm.Build.Tests/NonWasmTemplateBuildTests.cs index 579debf24502d9..d4b5800b89ad36 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NonWasmTemplateBuildTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NonWasmTemplateBuildTests.cs @@ -67,8 +67,11 @@ public NonWasmTemplateBuildTests(ITestOutputHelper output, SharedBuildPerTestCla ) .MultiplyWithSingleArgs ( + // Disable net6 and net7 tests for now, as the latest versions aren't in the feeds yet + /* "net6.0", s_previousTargetFramework, + */ s_latestTargetFramework ) .UnwrapItemsAsArrays().ToList(); diff --git a/src/mono/wasm/Wasm.Build.Tests/data/nuget8.config b/src/mono/wasm/Wasm.Build.Tests/data/nuget8.config index dfdc8009c6a5d5..4c33988a4365b8 100644 --- a/src/mono/wasm/Wasm.Build.Tests/data/nuget8.config +++ b/src/mono/wasm/Wasm.Build.Tests/data/nuget8.config @@ -9,6 +9,11 @@ + + + + + From b8263b8bced91ed994d6f1a4a51a09bf7ce715f1 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Fri, 27 Oct 2023 18:47:40 -0500 Subject: [PATCH 435/783] Target net8.0 in SatelliteAssemblyFromProjectRef --- .../LibraryWithResources/LibraryWithResources.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj b/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj index c6c44c64130006..ec2cce14320ca5 100644 --- a/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj +++ b/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj @@ -1,5 +1,5 @@ - net7.0 + net8.0 From 72b787fb27c27b030356059bee5b4df27e1b3055 Mon Sep 17 00:00:00 2001 From: dotnet-maestro-bot Date: Sat, 28 Oct 2023 03:52:31 +0200 Subject: [PATCH 436/783] [automated] Merge branch 'release/8.0' => 'release/8.0-staging' (#93874) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [release/8.0] Stable branding for .NET 8 GA * Handle an empty bandPreleaseVersion * [release/8.0] Update dependencies from dotnet/emsdk (#93801) * Update dependencies from https://github.com/dotnet/emsdk build 20231020.2 Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rtm.23511.3 -> To Version 8.0.0-rtm.23520.2 * switch to the stable version now * Update dependencies * Also fix the trigger * pin the wbt sdk to avoid the latest analizer nonsense * Use source generation for the serializer * Try to make sourcebuild happy * Try again to make sourcebuild happy * Use reflection and suppress trim analysis instead This reverts commit 768b65bab585f303bca6e0e9a36cf06d59e90387. * Fix reverting too much --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Larry Ewing * [release/8.0] Update APICompat settings under source build (#93865) * Update APICompat settings under source build * Update resolveContract.targets --------- Co-authored-by: Viktor Hofer * Override InformationalVersion for NativeAOT corelib too * [release/8.0] Improve performance of UnmanagedMemoryStream (#93812) * Improve performance of UnmanagedMemoryStream UnmanagedMemoryStream used Interlocked operations to update its state to prevent tearing of 64-bit values on 32-bit platforms. This pattern is expensive in general and it was found to be prohibitively expensive on recent hardware.. This change removes the expensive Interlocked operations and addresses the tearing issues in alternative way: - The _length field is converted to nuint that is guaranteed to be updated atomically. - Writes to _length field are volatile to guaranteed the unininitialized memory cannot be read. - The _position field remains long and it has a risk of tearing. It is not a problem since tearing of this field cannot lead to buffer overruns. Fixes #93624 * Add comment --------- Co-authored-by: Jan Kotas * Update dependencies from https://github.com/dotnet/emsdk build 20231023.2 (#93881) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.0-rtm.23520.2 -> To Version 8.0.0-rtm.23523.2 Co-authored-by: dotnet-maestro[bot] * [release/8.0] Update dependencies from dnceng/internal/dotnet-optimization (#93827) * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231021.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23519.5 -> To Version 1.0.0-prerelease.23521.3 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231021.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23519.5 -> To Version 1.0.0-prerelease.23521.3 --------- Co-authored-by: dotnet-maestro[bot] * [release/8.0][wasm] Fix perf pipeline runs (#93888) * Remove --experimental-wasm-eh argument from the wasm_args used for wasm performance runs. (#93357) (cherry picked from commit a770017fea3549e0bf88f7c619b79a731271e305) * performance-setup.sh: Use `release/8.0` as the default channel * performance-setup.ps1: use release/8.0 as the default channel * Fix passing wasmArgs for bdn --------- Co-authored-by: Parker Bibus * [release/8.0] Honor JsonSerializerOptions.PropertyNameCaseInsensitive in property name conflict resolution. (#93935) * Honor JsonSerializerOptions.PropertyNameCaseInsensitive in property name conflict resolution. * Update src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs Co-authored-by: Jeff Handley * Address feedback --------- Co-authored-by: Eirik Tsarpalis Co-authored-by: Jeff Handley * [8.0] Update MsQuic (#93979) * Try pinning the installer version to a 8.01xx sdk * Target net8.0 in SatelliteAssemblyFromProjectRef --------- Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> Co-authored-by: Larry Ewing Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: dotnet-maestro[bot] Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Viktor Hofer Co-authored-by: Alexander Köplinger Co-authored-by: Jan Kotas Co-authored-by: Ankit Jain Co-authored-by: Parker Bibus Co-authored-by: Eirik Tsarpalis Co-authored-by: Jeff Handley --- NuGet.config | 5 + eng/Version.Details.xml | 92 +++++++------ eng/Versions.props | 20 +-- eng/pipelines/common/xplat-setup.yml | 2 +- eng/resolveContract.targets | 5 +- eng/testing/performance/performance-setup.ps1 | 2 +- eng/testing/performance/performance-setup.sh | 9 +- src/coreclr/nativeaot/Directory.Build.props | 3 + .../src/System/IO/UnmanagedMemoryStream.cs | 126 +++++++++--------- .../gen/JsonSourceGenerator.Parser.cs | 7 +- .../DefaultJsonTypeInfoResolver.Helpers.cs | 2 +- .../Metadata/JsonMetadataServices.Helpers.cs | 2 +- .../Serialization/Metadata/JsonTypeInfo.cs | 5 +- .../tests/Common/PropertyNameTests.cs | 29 ++++ .../Serialization/PropertyNameTests.cs | 2 + .../LibraryWithResources.csproj | 2 +- .../WasmBasicTestApp/WasmBasicTestApp.csproj | 1 + .../InstallWorkloadFromArtifacts.cs | 4 +- 18 files changed, 179 insertions(+), 139 deletions(-) diff --git a/NuGet.config b/NuGet.config index 80dd215a4bf01b..29f8225aac34fb 100644 --- a/NuGet.config +++ b/NuGet.config @@ -7,6 +7,11 @@ + + + + + diff --git a/eng/Versions.props b/eng/Versions.props index 5ca3d1b92ac3e1..788b7c1ab4ea96 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -13,7 +13,7 @@ - false + true release -$(PreReleaseVersionLabel) -$(PreReleaseVersionLabel).$(PreReleaseVersionIteration) @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 @@ -219,7 +219,7 @@ 8.0.0-rtm.23511.1 - 2.2.2 + 2.2.3 8.0.0-alpha.1.23468.1 16.0.5-alpha.1.23478.1 @@ -240,8 +240,8 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.0-rtm.23511.3 - $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) + 8.0.0 + $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda 1.0.0-v3.14.0.5722 diff --git a/eng/pipelines/common/xplat-setup.yml b/eng/pipelines/common/xplat-setup.yml index 28257b05265ba0..eb19570aeecac2 100644 --- a/eng/pipelines/common/xplat-setup.yml +++ b/eng/pipelines/common/xplat-setup.yml @@ -108,7 +108,7 @@ jobs: - ${{ if eq(parameters.archType, 'wasm') }}: - name: wasmDarcDependenciesChanged value: $[ or( - eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport'], true), + eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100'], true), eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_DotNet_Build_Tasks_Workloads'], true), eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.System_Runtime_TimeZoneData'], true), eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_Net_Compilers_Toolset'], true), diff --git a/eng/resolveContract.targets b/eng/resolveContract.targets index 6d414f46f93e6b..3454d7064739a8 100644 --- a/eng/resolveContract.targets +++ b/eng/resolveContract.targets @@ -73,8 +73,9 @@ That is necessary as APICompat is invoked twice, once for the ref <-> src comparision and then again for the package validation (which doesn't include reference assemblies). As both operations don't have all the inputs available, some suppressions might only apply to one or the other and hence unnecessary - suppressions can't be determined. --> - + suppressions can't be determined. + Disable the validation under source build as that might use an out-of-date SDK and not the ApiCompat.Task package. --> + true true diff --git a/eng/testing/performance/performance-setup.ps1 b/eng/testing/performance/performance-setup.ps1 index 8caea345a893dc..8a8cd269dbe454 100644 --- a/eng/testing/performance/performance-setup.ps1 +++ b/eng/testing/performance/performance-setup.ps1 @@ -101,7 +101,7 @@ if ($iOSNativeAOT) { } # FIX ME: This is a workaround until we get this from the actual pipeline -$CleanedBranchName = "main" +$CleanedBranchName = "release/8.0" if($Branch.Contains("refs/heads/release")) { $CleanedBranchName = $Branch.replace('refs/heads/', '') diff --git a/eng/testing/performance/performance-setup.sh b/eng/testing/performance/performance-setup.sh index 9a1c95ec730820..c53ca6924b97b4 100755 --- a/eng/testing/performance/performance-setup.sh +++ b/eng/testing/performance/performance-setup.sh @@ -358,9 +358,7 @@ if [[ "$physicalpromotion" == "true" ]]; then configurations="$configurations PhysicalPromotionType=physicalpromotion" fi - - -cleaned_branch_name="main" +cleaned_branch_name="release/8.0" if [[ $branch == *"refs/heads/release"* ]]; then cleaned_branch_name=${branch/refs\/heads\//} fi @@ -404,15 +402,14 @@ if [[ -n "$wasm_bundle_directory" ]]; then using_wasm=true wasm_bundle_directory_path=$payload_directory mv $wasm_bundle_directory/* $wasm_bundle_directory_path - find $wasm_bundle_directory_path -type d - wasm_args="--experimental-wasm-eh --expose_wasm" + wasm_args="--expose_wasm" if [ "$javascript_engine" == "v8" ]; then # for es6 module support wasm_args="$wasm_args --module" fi # Workaround: escaping the quotes around `--wasmArgs=..` so they get retained for the actual command line - extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --wasmEngine /home/helixbot/.jsvu/bin/$javascript_engine --wasmArgs \\\"$wasm_args\\\" --cli \$HELIX_CORRELATION_PAYLOAD/dotnet/dotnet --wasmDataDir \$HELIX_CORRELATION_PAYLOAD/wasm-data" + extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --wasmEngine /home/helixbot/.jsvu/bin/$javascript_engine \\\"--wasmArgs=$wasm_args\\\" --cli \$HELIX_CORRELATION_PAYLOAD/dotnet/dotnet --wasmDataDir \$HELIX_CORRELATION_PAYLOAD/wasm-data" if [[ "$wasmaot" == "true" ]]; then extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --aotcompilermode wasm --buildTimeout 3600" fi diff --git a/src/coreclr/nativeaot/Directory.Build.props b/src/coreclr/nativeaot/Directory.Build.props index ebfa725e4efd2c..005d6ae997adab 100644 --- a/src/coreclr/nativeaot/Directory.Build.props +++ b/src/coreclr/nativeaot/Directory.Build.props @@ -25,6 +25,9 @@ false v4.0.30319 + + $(ProductVersion) + $(ProductVersion) $(NoWarn),0419,0649,CA2249,CA1830 diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs index 5f049e69445381..b2a3134ae7501a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs @@ -23,14 +23,9 @@ namespace System.IO * of the UnmanagedMemoryStream. * 3) You clean up the memory when appropriate. The UnmanagedMemoryStream * currently will do NOTHING to free this memory. - * 4) All calls to Write and WriteByte may not be threadsafe currently. - * - * It may become necessary to add in some sort of - * DeallocationMode enum, specifying whether we unmap a section of memory, - * call free, run a user-provided delegate to free the memory, etc. - * We'll suggest user write a subclass of UnmanagedMemoryStream that uses - * a SafeHandle subclass to hold onto the memory. - * + * 4) This type is not thread safe. However, the implementation should prevent buffer + * overruns or returning uninitialized memory when Reads and Writes are called + * concurrently in thread unsafe manner. */ /// @@ -40,10 +35,10 @@ public class UnmanagedMemoryStream : Stream { private SafeBuffer? _buffer; private unsafe byte* _mem; - private long _length; - private long _capacity; - private long _position; - private long _offset; + private nuint _capacity; + private nuint _offset; + private nuint _length; // nuint to guarantee atomic access on 32-bit platforms + private long _position; // long to allow seeking to any location beyond the length of the stream. private FileAccess _access; private bool _isOpen; private CachedCompletedInt32Task _lastReadTask; // The last successful task returned from ReadAsync @@ -123,10 +118,10 @@ protected void Initialize(SafeBuffer buffer, long offset, long length, FileAcces } } - _offset = offset; + _offset = (nuint)offset; _buffer = buffer; - _length = length; - _capacity = length; + _length = (nuint)length; + _capacity = (nuint)length; _access = access; _isOpen = true; } @@ -171,8 +166,8 @@ protected unsafe void Initialize(byte* pointer, long length, long capacity, File _mem = pointer; _offset = 0; - _length = length; - _capacity = capacity; + _length = (nuint)length; + _capacity = (nuint)capacity; _access = access; _isOpen = true; } @@ -259,7 +254,7 @@ public override long Length get { EnsureNotClosed(); - return Interlocked.Read(ref _length); + return (long)_length; } } @@ -271,7 +266,7 @@ public long Capacity get { EnsureNotClosed(); - return _capacity; + return (long)_capacity; } } @@ -283,14 +278,14 @@ public override long Position get { if (!CanSeek) ThrowHelper.ThrowObjectDisposedException_StreamClosed(null); - return Interlocked.Read(ref _position); + return _position; } set { ArgumentOutOfRangeException.ThrowIfNegative(value); if (!CanSeek) ThrowHelper.ThrowObjectDisposedException_StreamClosed(null); - Interlocked.Exchange(ref _position, value); + _position = value; } } @@ -308,11 +303,10 @@ public unsafe byte* PositionPointer EnsureNotClosed(); // Use a temp to avoid a race - long pos = Interlocked.Read(ref _position); - if (pos > _capacity) + long pos = _position; + if (pos > (long)_capacity) throw new IndexOutOfRangeException(SR.IndexOutOfRange_UMSPosition); - byte* ptr = _mem + pos; - return ptr; + return _mem + pos; } set { @@ -327,7 +321,7 @@ public unsafe byte* PositionPointer if (newPosition < 0) throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_UnmanagedMemStreamLength); - Interlocked.Exchange(ref _position, newPosition); + _position = newPosition; } } @@ -367,8 +361,13 @@ internal int ReadCore(Span buffer) // Use a local variable to avoid a race where another thread // changes our position after we decide we can read some bytes. - long pos = Interlocked.Read(ref _position); - long len = Interlocked.Read(ref _length); + long pos = _position; + + // Use a volatile read to prevent reading of the uninitialized memory. This volatile read + // and matching volatile write that set _length avoids reordering of NativeMemory.Clear + // operations with reading of the buffer below. + long len = (long)Volatile.Read(ref _length); + long n = Math.Min(len - pos, buffer.Length); if (n <= 0) { @@ -407,7 +406,7 @@ internal int ReadCore(Span buffer) } } - Interlocked.Exchange(ref _position, pos + n); + _position = pos + n; return nInt; } @@ -484,11 +483,16 @@ public override int ReadByte() EnsureNotClosed(); EnsureReadable(); - long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition - long len = Interlocked.Read(ref _length); + long pos = _position; // Use a local to avoid a race condition + + // Use a volatile read to prevent reading of the uninitialized memory. This volatile read + // and matching volatile write that set _length avoids reordering of NativeMemory.Clear + // operations with reading of the buffer below. + long len = (long)Volatile.Read(ref _length); + if (pos >= len) return -1; - Interlocked.Exchange(ref _position, pos + 1); + _position = pos + 1; int result; if (_buffer != null) { @@ -529,35 +533,33 @@ public override long Seek(long offset, SeekOrigin loc) { EnsureNotClosed(); + long newPosition; switch (loc) { case SeekOrigin.Begin: - if (offset < 0) + newPosition = offset; + if (newPosition < 0) throw new IOException(SR.IO_SeekBeforeBegin); - Interlocked.Exchange(ref _position, offset); break; case SeekOrigin.Current: - long pos = Interlocked.Read(ref _position); - if (offset + pos < 0) + newPosition = _position + offset; + if (newPosition < 0) throw new IOException(SR.IO_SeekBeforeBegin); - Interlocked.Exchange(ref _position, offset + pos); break; case SeekOrigin.End: - long len = Interlocked.Read(ref _length); - if (len + offset < 0) + newPosition = (long)_length + offset; + if (newPosition < 0) throw new IOException(SR.IO_SeekBeforeBegin); - Interlocked.Exchange(ref _position, len + offset); break; default: throw new ArgumentException(SR.Argument_InvalidSeekOrigin); } - long finalPos = Interlocked.Read(ref _position); - Debug.Assert(finalPos >= 0, "_position >= 0"); - return finalPos; + _position = newPosition; + return newPosition; } /// @@ -573,11 +575,10 @@ public override void SetLength(long value) EnsureNotClosed(); EnsureWriteable(); - if (value > _capacity) + if (value > (long)_capacity) throw new IOException(SR.IO_FixedCapacity); - long pos = Interlocked.Read(ref _position); - long len = Interlocked.Read(ref _length); + long len = (long)_length; if (value > len) { unsafe @@ -585,10 +586,11 @@ public override void SetLength(long value) NativeMemory.Clear(_mem + len, (nuint)(value - len)); } } - Interlocked.Exchange(ref _length, value); - if (pos > value) + Volatile.Write(ref _length, (nuint)value); // volatile to prevent reading of uninitialized memory + + if (_position > value) { - Interlocked.Exchange(ref _position, value); + _position = value; } } @@ -625,8 +627,8 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) EnsureNotClosed(); EnsureWriteable(); - long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition - long len = Interlocked.Read(ref _length); + long pos = _position; // Use a local to avoid a race condition + long len = (long)_length; long n = pos + buffer.Length; // Check for overflow if (n < 0) @@ -634,7 +636,7 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) throw new IOException(SR.IO_StreamTooLong); } - if (n > _capacity) + if (n > (long)_capacity) { throw new NotSupportedException(SR.IO_FixedCapacity); } @@ -648,16 +650,16 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) NativeMemory.Clear(_mem + len, (nuint)(pos - len)); } - // set length after zeroing memory to avoid race condition of accessing unzeroed memory + // set length after zeroing memory to avoid race condition of accessing uninitialized memory if (n > len) { - Interlocked.Exchange(ref _length, n); + Volatile.Write(ref _length, (nuint)n); // volatile to prevent reading of uninitialized memory } } if (_buffer != null) { - long bytesLeft = _capacity - pos; + long bytesLeft = (long)_capacity - pos; if (bytesLeft < buffer.Length) { throw new ArgumentException(SR.Arg_BufferTooSmall); @@ -682,8 +684,7 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) Buffer.Memmove(ref *(_mem + pos), ref MemoryMarshal.GetReference(buffer), (nuint)buffer.Length); } - Interlocked.Exchange(ref _position, n); - return; + _position = n; } /// @@ -754,8 +755,8 @@ public override void WriteByte(byte value) EnsureNotClosed(); EnsureWriteable(); - long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition - long len = Interlocked.Read(ref _length); + long pos = _position; // Use a local to avoid a race condition + long len = (long)_length; long n = pos + 1; if (pos >= len) { @@ -763,7 +764,7 @@ public override void WriteByte(byte value) if (n < 0) throw new IOException(SR.IO_StreamTooLong); - if (n > _capacity) + if (n > (long)_capacity) throw new NotSupportedException(SR.IO_FixedCapacity); // Check to see whether we are now expanding the stream and must @@ -779,8 +780,7 @@ public override void WriteByte(byte value) } } - // set length after zeroing memory to avoid race condition of accessing unzeroed memory - Interlocked.Exchange(ref _length, n); + Volatile.Write(ref _length, (nuint)n); // volatile to prevent reading of uninitialized memory } } @@ -810,7 +810,7 @@ public override void WriteByte(byte value) _mem[pos] = value; } } - Interlocked.Exchange(ref _position, n); + _position = n; } } } diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs index e0dac6a9ad82ce..594f7ad9770c3c 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs @@ -863,7 +863,7 @@ private List ParsePropertyGenerationSpecs( { Location? typeLocation = typeToGenerate.Location; List properties = new(); - PropertyHierarchyResolutionState state = new(); + PropertyHierarchyResolutionState state = new(options); hasExtensionDataProperty = false; // Walk the type hierarchy starting from the current type up to the base type(s) @@ -970,11 +970,10 @@ bool PropertyIsOverriddenAndIgnored(IPropertySymbol property, Dictionary Properties = new(); - public Dictionary AddedProperties = new(); + public Dictionary AddedProperties = new(options?.PropertyNameCaseInsensitive == true ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal); public Dictionary? IgnoredMembers; public bool IsPropertyOrderSpecified; public bool HasInvalidConfigurationForFastPath; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs index c654a920f8ff6e..3f929d87378485 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs @@ -88,7 +88,7 @@ private static void PopulateProperties(JsonTypeInfo typeInfo) bool constructorHasSetsRequiredMembersAttribute = typeInfo.Converter.ConstructorInfo?.HasSetsRequiredMembersAttribute() ?? false; - JsonTypeInfo.PropertyHierarchyResolutionState state = new(); + JsonTypeInfo.PropertyHierarchyResolutionState state = new(typeInfo.Options); // Walk the type hierarchy starting from the current type up to the base type(s) foreach (Type currentType in typeInfo.Type.GetSortedTypeHierarchy()) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs index 1b7113f9dd758a..965b4cea39570a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs @@ -137,7 +137,7 @@ internal static void PopulateProperties(JsonTypeInfo typeInfo, JsonTypeInfo.Json // Regardless of the source generator we need to re-run the naming conflict resolution algorithm // at run time since it is possible that the naming policy or other configs can be different then. - JsonTypeInfo.PropertyHierarchyResolutionState state = new(); + JsonTypeInfo.PropertyHierarchyResolutionState state = new(typeInfo.Options); foreach (JsonPropertyInfo jsonPropertyInfo in properties) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs index a1a184f6059d2b..668e0c7b15e1a1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs @@ -992,10 +992,9 @@ public JsonPropertyInfo CreateJsonPropertyInfo(Type propertyType, string name) internal abstract ValueTask DeserializeAsObjectAsync(Stream utf8Json, CancellationToken cancellationToken); internal abstract object? DeserializeAsObject(Stream utf8Json); - internal ref struct PropertyHierarchyResolutionState + internal ref struct PropertyHierarchyResolutionState(JsonSerializerOptions options) { - public PropertyHierarchyResolutionState() { } - public Dictionary AddedProperties = new(); + public Dictionary AddedProperties = new(options.PropertyNameCaseInsensitive ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal); public Dictionary? IgnoredProperties; public bool IsPropertyOrderSpecified; } diff --git a/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs b/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs index 4295359c6f0380..021481ae5a1362 100644 --- a/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs +++ b/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs @@ -494,5 +494,34 @@ public class ClassWithSpecialCharacters [JsonPropertyName("\uA000_2")] // Valid C# property name: \uA000_2 public int YiIt_2 { get; set; } } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task ClassWithIgnoredCaseInsensitiveConflict_RespectsIgnoredMember(bool propertyNameCaseInsensitive) + { + // Regression test for https://github.com/dotnet/runtime/issues/93903 + // specifically for propertyNameCaseInsensitive := true + + JsonSerializerOptions options = Serializer.CreateOptions(makeReadOnly: false); + options.PropertyNameCaseInsensitive = propertyNameCaseInsensitive; + + var value = new ClassWithIgnoredCaseInsensitiveConflict { name = "lowercase", Name = "uppercase" }; + string json = await Serializer.SerializeWrapper(value, options); + + Assert.Equal("""{"name":"lowercase"}""", json); + + value = await Serializer.DeserializeWrapper(json, options); + Assert.Equal("lowercase", value.name); + Assert.Null(value.Name); + } + + public class ClassWithIgnoredCaseInsensitiveConflict + { + public string name { get; set; } + + [JsonIgnore] + public string Name { get; set; } + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs index 82566bf7123ce7..e512451eed72bc 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs @@ -28,6 +28,7 @@ public PropertyNameTests_Metadata() [JsonSerializable(typeof(ObjectPropertyNamesDifferentByCaseOnly_TestClass))] [JsonSerializable(typeof(OverridePropertyNameDesignTime_TestClass))] [JsonSerializable(typeof(SimpleTestClass))] + [JsonSerializable(typeof(ClassWithIgnoredCaseInsensitiveConflict))] internal sealed partial class PropertyNameTestsContext_Metadata : JsonSerializerContext { } @@ -53,6 +54,7 @@ public PropertyNameTests_Default() [JsonSerializable(typeof(ObjectPropertyNamesDifferentByCaseOnly_TestClass))] [JsonSerializable(typeof(OverridePropertyNameDesignTime_TestClass))] [JsonSerializable(typeof(SimpleTestClass))] + [JsonSerializable(typeof(ClassWithIgnoredCaseInsensitiveConflict))] internal sealed partial class PropertyNameTestsContext_Default : JsonSerializerContext { } diff --git a/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj b/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj index c6c44c64130006..ec2cce14320ca5 100644 --- a/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj +++ b/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj @@ -1,5 +1,5 @@ - net7.0 + net8.0 diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj b/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj index 33858b9a6a755f..761ac6354ce861 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj +++ b/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj @@ -4,6 +4,7 @@ browser-wasm Exe true + true diff --git a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs index 62817719af0a14..21170ea2152843 100644 --- a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs +++ b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs @@ -301,8 +301,8 @@ private bool InstallWorkloadManifest(ITaskItem workloadId, string name, string v string packagePreleaseVersion = bandVersionRegex().Match(version).Groups[1].Value; string bandPreleaseVersion = bandVersionRegex().Match(bandVersion).Groups[1].Value; - if (packagePreleaseVersion != bandPreleaseVersion && packagePreleaseVersion != "-dev" && packagePreleaseVersion != "-ci") - bandVersion = bandVersion.Replace (bandPreleaseVersion, packagePreleaseVersion); + if (packagePreleaseVersion != bandPreleaseVersion && packagePreleaseVersion != "-dev" && packagePreleaseVersion != "-ci" && bandPreleaseVersion != "") + bandVersion = bandVersion.Replace(bandPreleaseVersion, packagePreleaseVersion); PackageReference pkgRef = new(Name: $"{name}.Manifest-{bandVersion}", Version: version, From 78af8648a983594ca94d8e405672457bf1f98cf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Mon, 30 Oct 2023 10:57:28 -0600 Subject: [PATCH 437/783] Revert "[automated] Merge branch 'release/8.0' => 'release/8.0-staging' (#93874)" (#94179) This reverts commit 72b787fb27c27b030356059bee5b4df27e1b3055. --- NuGet.config | 5 - eng/Version.Details.xml | 92 ++++++------- eng/Versions.props | 20 +-- eng/pipelines/common/xplat-setup.yml | 2 +- eng/resolveContract.targets | 5 +- eng/testing/performance/performance-setup.ps1 | 2 +- eng/testing/performance/performance-setup.sh | 9 +- src/coreclr/nativeaot/Directory.Build.props | 3 - .../src/System/IO/UnmanagedMemoryStream.cs | 126 +++++++++--------- .../gen/JsonSourceGenerator.Parser.cs | 7 +- .../DefaultJsonTypeInfoResolver.Helpers.cs | 2 +- .../Metadata/JsonMetadataServices.Helpers.cs | 2 +- .../Serialization/Metadata/JsonTypeInfo.cs | 5 +- .../tests/Common/PropertyNameTests.cs | 29 ---- .../Serialization/PropertyNameTests.cs | 2 - .../LibraryWithResources.csproj | 2 +- .../WasmBasicTestApp/WasmBasicTestApp.csproj | 1 - .../InstallWorkloadFromArtifacts.cs | 4 +- 18 files changed, 139 insertions(+), 179 deletions(-) diff --git a/NuGet.config b/NuGet.config index 29f8225aac34fb..80dd215a4bf01b 100644 --- a/NuGet.config +++ b/NuGet.config @@ -7,11 +7,6 @@ - - - - - diff --git a/eng/Versions.props b/eng/Versions.props index 788b7c1ab4ea96..5ca3d1b92ac3e1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -13,7 +13,7 @@ - true + false release -$(PreReleaseVersionLabel) -$(PreReleaseVersionLabel).$(PreReleaseVersionIteration) @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23521.3 - 1.0.0-prerelease.23521.3 - 1.0.0-prerelease.23521.3 - 1.0.0-prerelease.23521.3 - 1.0.0-prerelease.23521.3 - 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23519.5 + 1.0.0-prerelease.23519.5 + 1.0.0-prerelease.23519.5 + 1.0.0-prerelease.23519.5 + 1.0.0-prerelease.23519.5 + 1.0.0-prerelease.23519.5 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 @@ -219,7 +219,7 @@ 8.0.0-rtm.23511.1 - 2.2.3 + 2.2.2 8.0.0-alpha.1.23468.1 16.0.5-alpha.1.23478.1 @@ -240,8 +240,8 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.0 - $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) + 8.0.0-rtm.23511.3 + $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 1.1.87-gba258badda 1.0.0-v3.14.0.5722 diff --git a/eng/pipelines/common/xplat-setup.yml b/eng/pipelines/common/xplat-setup.yml index eb19570aeecac2..28257b05265ba0 100644 --- a/eng/pipelines/common/xplat-setup.yml +++ b/eng/pipelines/common/xplat-setup.yml @@ -108,7 +108,7 @@ jobs: - ${{ if eq(parameters.archType, 'wasm') }}: - name: wasmDarcDependenciesChanged value: $[ or( - eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100'], true), + eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport'], true), eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_DotNet_Build_Tasks_Workloads'], true), eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.System_Runtime_TimeZoneData'], true), eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_Net_Compilers_Toolset'], true), diff --git a/eng/resolveContract.targets b/eng/resolveContract.targets index 3454d7064739a8..6d414f46f93e6b 100644 --- a/eng/resolveContract.targets +++ b/eng/resolveContract.targets @@ -73,9 +73,8 @@ That is necessary as APICompat is invoked twice, once for the ref <-> src comparision and then again for the package validation (which doesn't include reference assemblies). As both operations don't have all the inputs available, some suppressions might only apply to one or the other and hence unnecessary - suppressions can't be determined. - Disable the validation under source build as that might use an out-of-date SDK and not the ApiCompat.Task package. --> - + suppressions can't be determined. --> + true true diff --git a/eng/testing/performance/performance-setup.ps1 b/eng/testing/performance/performance-setup.ps1 index 8a8cd269dbe454..8caea345a893dc 100644 --- a/eng/testing/performance/performance-setup.ps1 +++ b/eng/testing/performance/performance-setup.ps1 @@ -101,7 +101,7 @@ if ($iOSNativeAOT) { } # FIX ME: This is a workaround until we get this from the actual pipeline -$CleanedBranchName = "release/8.0" +$CleanedBranchName = "main" if($Branch.Contains("refs/heads/release")) { $CleanedBranchName = $Branch.replace('refs/heads/', '') diff --git a/eng/testing/performance/performance-setup.sh b/eng/testing/performance/performance-setup.sh index c53ca6924b97b4..9a1c95ec730820 100755 --- a/eng/testing/performance/performance-setup.sh +++ b/eng/testing/performance/performance-setup.sh @@ -358,7 +358,9 @@ if [[ "$physicalpromotion" == "true" ]]; then configurations="$configurations PhysicalPromotionType=physicalpromotion" fi -cleaned_branch_name="release/8.0" + + +cleaned_branch_name="main" if [[ $branch == *"refs/heads/release"* ]]; then cleaned_branch_name=${branch/refs\/heads\//} fi @@ -402,14 +404,15 @@ if [[ -n "$wasm_bundle_directory" ]]; then using_wasm=true wasm_bundle_directory_path=$payload_directory mv $wasm_bundle_directory/* $wasm_bundle_directory_path - wasm_args="--expose_wasm" + find $wasm_bundle_directory_path -type d + wasm_args="--experimental-wasm-eh --expose_wasm" if [ "$javascript_engine" == "v8" ]; then # for es6 module support wasm_args="$wasm_args --module" fi # Workaround: escaping the quotes around `--wasmArgs=..` so they get retained for the actual command line - extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --wasmEngine /home/helixbot/.jsvu/bin/$javascript_engine \\\"--wasmArgs=$wasm_args\\\" --cli \$HELIX_CORRELATION_PAYLOAD/dotnet/dotnet --wasmDataDir \$HELIX_CORRELATION_PAYLOAD/wasm-data" + extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --wasmEngine /home/helixbot/.jsvu/bin/$javascript_engine --wasmArgs \\\"$wasm_args\\\" --cli \$HELIX_CORRELATION_PAYLOAD/dotnet/dotnet --wasmDataDir \$HELIX_CORRELATION_PAYLOAD/wasm-data" if [[ "$wasmaot" == "true" ]]; then extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --aotcompilermode wasm --buildTimeout 3600" fi diff --git a/src/coreclr/nativeaot/Directory.Build.props b/src/coreclr/nativeaot/Directory.Build.props index 005d6ae997adab..ebfa725e4efd2c 100644 --- a/src/coreclr/nativeaot/Directory.Build.props +++ b/src/coreclr/nativeaot/Directory.Build.props @@ -25,9 +25,6 @@ false v4.0.30319 - - $(ProductVersion) - $(ProductVersion) $(NoWarn),0419,0649,CA2249,CA1830 diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs index b2a3134ae7501a..5f049e69445381 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs @@ -23,9 +23,14 @@ namespace System.IO * of the UnmanagedMemoryStream. * 3) You clean up the memory when appropriate. The UnmanagedMemoryStream * currently will do NOTHING to free this memory. - * 4) This type is not thread safe. However, the implementation should prevent buffer - * overruns or returning uninitialized memory when Reads and Writes are called - * concurrently in thread unsafe manner. + * 4) All calls to Write and WriteByte may not be threadsafe currently. + * + * It may become necessary to add in some sort of + * DeallocationMode enum, specifying whether we unmap a section of memory, + * call free, run a user-provided delegate to free the memory, etc. + * We'll suggest user write a subclass of UnmanagedMemoryStream that uses + * a SafeHandle subclass to hold onto the memory. + * */ /// @@ -35,10 +40,10 @@ public class UnmanagedMemoryStream : Stream { private SafeBuffer? _buffer; private unsafe byte* _mem; - private nuint _capacity; - private nuint _offset; - private nuint _length; // nuint to guarantee atomic access on 32-bit platforms - private long _position; // long to allow seeking to any location beyond the length of the stream. + private long _length; + private long _capacity; + private long _position; + private long _offset; private FileAccess _access; private bool _isOpen; private CachedCompletedInt32Task _lastReadTask; // The last successful task returned from ReadAsync @@ -118,10 +123,10 @@ protected void Initialize(SafeBuffer buffer, long offset, long length, FileAcces } } - _offset = (nuint)offset; + _offset = offset; _buffer = buffer; - _length = (nuint)length; - _capacity = (nuint)length; + _length = length; + _capacity = length; _access = access; _isOpen = true; } @@ -166,8 +171,8 @@ protected unsafe void Initialize(byte* pointer, long length, long capacity, File _mem = pointer; _offset = 0; - _length = (nuint)length; - _capacity = (nuint)capacity; + _length = length; + _capacity = capacity; _access = access; _isOpen = true; } @@ -254,7 +259,7 @@ public override long Length get { EnsureNotClosed(); - return (long)_length; + return Interlocked.Read(ref _length); } } @@ -266,7 +271,7 @@ public long Capacity get { EnsureNotClosed(); - return (long)_capacity; + return _capacity; } } @@ -278,14 +283,14 @@ public override long Position get { if (!CanSeek) ThrowHelper.ThrowObjectDisposedException_StreamClosed(null); - return _position; + return Interlocked.Read(ref _position); } set { ArgumentOutOfRangeException.ThrowIfNegative(value); if (!CanSeek) ThrowHelper.ThrowObjectDisposedException_StreamClosed(null); - _position = value; + Interlocked.Exchange(ref _position, value); } } @@ -303,10 +308,11 @@ public unsafe byte* PositionPointer EnsureNotClosed(); // Use a temp to avoid a race - long pos = _position; - if (pos > (long)_capacity) + long pos = Interlocked.Read(ref _position); + if (pos > _capacity) throw new IndexOutOfRangeException(SR.IndexOutOfRange_UMSPosition); - return _mem + pos; + byte* ptr = _mem + pos; + return ptr; } set { @@ -321,7 +327,7 @@ public unsafe byte* PositionPointer if (newPosition < 0) throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_UnmanagedMemStreamLength); - _position = newPosition; + Interlocked.Exchange(ref _position, newPosition); } } @@ -361,13 +367,8 @@ internal int ReadCore(Span buffer) // Use a local variable to avoid a race where another thread // changes our position after we decide we can read some bytes. - long pos = _position; - - // Use a volatile read to prevent reading of the uninitialized memory. This volatile read - // and matching volatile write that set _length avoids reordering of NativeMemory.Clear - // operations with reading of the buffer below. - long len = (long)Volatile.Read(ref _length); - + long pos = Interlocked.Read(ref _position); + long len = Interlocked.Read(ref _length); long n = Math.Min(len - pos, buffer.Length); if (n <= 0) { @@ -406,7 +407,7 @@ internal int ReadCore(Span buffer) } } - _position = pos + n; + Interlocked.Exchange(ref _position, pos + n); return nInt; } @@ -483,16 +484,11 @@ public override int ReadByte() EnsureNotClosed(); EnsureReadable(); - long pos = _position; // Use a local to avoid a race condition - - // Use a volatile read to prevent reading of the uninitialized memory. This volatile read - // and matching volatile write that set _length avoids reordering of NativeMemory.Clear - // operations with reading of the buffer below. - long len = (long)Volatile.Read(ref _length); - + long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition + long len = Interlocked.Read(ref _length); if (pos >= len) return -1; - _position = pos + 1; + Interlocked.Exchange(ref _position, pos + 1); int result; if (_buffer != null) { @@ -533,33 +529,35 @@ public override long Seek(long offset, SeekOrigin loc) { EnsureNotClosed(); - long newPosition; switch (loc) { case SeekOrigin.Begin: - newPosition = offset; - if (newPosition < 0) + if (offset < 0) throw new IOException(SR.IO_SeekBeforeBegin); + Interlocked.Exchange(ref _position, offset); break; case SeekOrigin.Current: - newPosition = _position + offset; - if (newPosition < 0) + long pos = Interlocked.Read(ref _position); + if (offset + pos < 0) throw new IOException(SR.IO_SeekBeforeBegin); + Interlocked.Exchange(ref _position, offset + pos); break; case SeekOrigin.End: - newPosition = (long)_length + offset; - if (newPosition < 0) + long len = Interlocked.Read(ref _length); + if (len + offset < 0) throw new IOException(SR.IO_SeekBeforeBegin); + Interlocked.Exchange(ref _position, len + offset); break; default: throw new ArgumentException(SR.Argument_InvalidSeekOrigin); } - _position = newPosition; - return newPosition; + long finalPos = Interlocked.Read(ref _position); + Debug.Assert(finalPos >= 0, "_position >= 0"); + return finalPos; } /// @@ -575,10 +573,11 @@ public override void SetLength(long value) EnsureNotClosed(); EnsureWriteable(); - if (value > (long)_capacity) + if (value > _capacity) throw new IOException(SR.IO_FixedCapacity); - long len = (long)_length; + long pos = Interlocked.Read(ref _position); + long len = Interlocked.Read(ref _length); if (value > len) { unsafe @@ -586,11 +585,10 @@ public override void SetLength(long value) NativeMemory.Clear(_mem + len, (nuint)(value - len)); } } - Volatile.Write(ref _length, (nuint)value); // volatile to prevent reading of uninitialized memory - - if (_position > value) + Interlocked.Exchange(ref _length, value); + if (pos > value) { - _position = value; + Interlocked.Exchange(ref _position, value); } } @@ -627,8 +625,8 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) EnsureNotClosed(); EnsureWriteable(); - long pos = _position; // Use a local to avoid a race condition - long len = (long)_length; + long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition + long len = Interlocked.Read(ref _length); long n = pos + buffer.Length; // Check for overflow if (n < 0) @@ -636,7 +634,7 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) throw new IOException(SR.IO_StreamTooLong); } - if (n > (long)_capacity) + if (n > _capacity) { throw new NotSupportedException(SR.IO_FixedCapacity); } @@ -650,16 +648,16 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) NativeMemory.Clear(_mem + len, (nuint)(pos - len)); } - // set length after zeroing memory to avoid race condition of accessing uninitialized memory + // set length after zeroing memory to avoid race condition of accessing unzeroed memory if (n > len) { - Volatile.Write(ref _length, (nuint)n); // volatile to prevent reading of uninitialized memory + Interlocked.Exchange(ref _length, n); } } if (_buffer != null) { - long bytesLeft = (long)_capacity - pos; + long bytesLeft = _capacity - pos; if (bytesLeft < buffer.Length) { throw new ArgumentException(SR.Arg_BufferTooSmall); @@ -684,7 +682,8 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) Buffer.Memmove(ref *(_mem + pos), ref MemoryMarshal.GetReference(buffer), (nuint)buffer.Length); } - _position = n; + Interlocked.Exchange(ref _position, n); + return; } /// @@ -755,8 +754,8 @@ public override void WriteByte(byte value) EnsureNotClosed(); EnsureWriteable(); - long pos = _position; // Use a local to avoid a race condition - long len = (long)_length; + long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition + long len = Interlocked.Read(ref _length); long n = pos + 1; if (pos >= len) { @@ -764,7 +763,7 @@ public override void WriteByte(byte value) if (n < 0) throw new IOException(SR.IO_StreamTooLong); - if (n > (long)_capacity) + if (n > _capacity) throw new NotSupportedException(SR.IO_FixedCapacity); // Check to see whether we are now expanding the stream and must @@ -780,7 +779,8 @@ public override void WriteByte(byte value) } } - Volatile.Write(ref _length, (nuint)n); // volatile to prevent reading of uninitialized memory + // set length after zeroing memory to avoid race condition of accessing unzeroed memory + Interlocked.Exchange(ref _length, n); } } @@ -810,7 +810,7 @@ public override void WriteByte(byte value) _mem[pos] = value; } } - _position = n; + Interlocked.Exchange(ref _position, n); } } } diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs index 594f7ad9770c3c..e0dac6a9ad82ce 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs @@ -863,7 +863,7 @@ private List ParsePropertyGenerationSpecs( { Location? typeLocation = typeToGenerate.Location; List properties = new(); - PropertyHierarchyResolutionState state = new(options); + PropertyHierarchyResolutionState state = new(); hasExtensionDataProperty = false; // Walk the type hierarchy starting from the current type up to the base type(s) @@ -970,10 +970,11 @@ bool PropertyIsOverriddenAndIgnored(IPropertySymbol property, Dictionary Properties = new(); - public Dictionary AddedProperties = new(options?.PropertyNameCaseInsensitive == true ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal); + public Dictionary AddedProperties = new(); public Dictionary? IgnoredMembers; public bool IsPropertyOrderSpecified; public bool HasInvalidConfigurationForFastPath; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs index 3f929d87378485..c654a920f8ff6e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs @@ -88,7 +88,7 @@ private static void PopulateProperties(JsonTypeInfo typeInfo) bool constructorHasSetsRequiredMembersAttribute = typeInfo.Converter.ConstructorInfo?.HasSetsRequiredMembersAttribute() ?? false; - JsonTypeInfo.PropertyHierarchyResolutionState state = new(typeInfo.Options); + JsonTypeInfo.PropertyHierarchyResolutionState state = new(); // Walk the type hierarchy starting from the current type up to the base type(s) foreach (Type currentType in typeInfo.Type.GetSortedTypeHierarchy()) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs index 965b4cea39570a..1b7113f9dd758a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs @@ -137,7 +137,7 @@ internal static void PopulateProperties(JsonTypeInfo typeInfo, JsonTypeInfo.Json // Regardless of the source generator we need to re-run the naming conflict resolution algorithm // at run time since it is possible that the naming policy or other configs can be different then. - JsonTypeInfo.PropertyHierarchyResolutionState state = new(typeInfo.Options); + JsonTypeInfo.PropertyHierarchyResolutionState state = new(); foreach (JsonPropertyInfo jsonPropertyInfo in properties) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs index 668e0c7b15e1a1..a1a184f6059d2b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs @@ -992,9 +992,10 @@ public JsonPropertyInfo CreateJsonPropertyInfo(Type propertyType, string name) internal abstract ValueTask DeserializeAsObjectAsync(Stream utf8Json, CancellationToken cancellationToken); internal abstract object? DeserializeAsObject(Stream utf8Json); - internal ref struct PropertyHierarchyResolutionState(JsonSerializerOptions options) + internal ref struct PropertyHierarchyResolutionState { - public Dictionary AddedProperties = new(options.PropertyNameCaseInsensitive ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal); + public PropertyHierarchyResolutionState() { } + public Dictionary AddedProperties = new(); public Dictionary? IgnoredProperties; public bool IsPropertyOrderSpecified; } diff --git a/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs b/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs index 021481ae5a1362..4295359c6f0380 100644 --- a/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs +++ b/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs @@ -494,34 +494,5 @@ public class ClassWithSpecialCharacters [JsonPropertyName("\uA000_2")] // Valid C# property name: \uA000_2 public int YiIt_2 { get; set; } } - - [Theory] - [InlineData(false)] - [InlineData(true)] - public async Task ClassWithIgnoredCaseInsensitiveConflict_RespectsIgnoredMember(bool propertyNameCaseInsensitive) - { - // Regression test for https://github.com/dotnet/runtime/issues/93903 - // specifically for propertyNameCaseInsensitive := true - - JsonSerializerOptions options = Serializer.CreateOptions(makeReadOnly: false); - options.PropertyNameCaseInsensitive = propertyNameCaseInsensitive; - - var value = new ClassWithIgnoredCaseInsensitiveConflict { name = "lowercase", Name = "uppercase" }; - string json = await Serializer.SerializeWrapper(value, options); - - Assert.Equal("""{"name":"lowercase"}""", json); - - value = await Serializer.DeserializeWrapper(json, options); - Assert.Equal("lowercase", value.name); - Assert.Null(value.Name); - } - - public class ClassWithIgnoredCaseInsensitiveConflict - { - public string name { get; set; } - - [JsonIgnore] - public string Name { get; set; } - } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs index e512451eed72bc..82566bf7123ce7 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs @@ -28,7 +28,6 @@ public PropertyNameTests_Metadata() [JsonSerializable(typeof(ObjectPropertyNamesDifferentByCaseOnly_TestClass))] [JsonSerializable(typeof(OverridePropertyNameDesignTime_TestClass))] [JsonSerializable(typeof(SimpleTestClass))] - [JsonSerializable(typeof(ClassWithIgnoredCaseInsensitiveConflict))] internal sealed partial class PropertyNameTestsContext_Metadata : JsonSerializerContext { } @@ -54,7 +53,6 @@ public PropertyNameTests_Default() [JsonSerializable(typeof(ObjectPropertyNamesDifferentByCaseOnly_TestClass))] [JsonSerializable(typeof(OverridePropertyNameDesignTime_TestClass))] [JsonSerializable(typeof(SimpleTestClass))] - [JsonSerializable(typeof(ClassWithIgnoredCaseInsensitiveConflict))] internal sealed partial class PropertyNameTestsContext_Default : JsonSerializerContext { } diff --git a/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj b/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj index ec2cce14320ca5..c6c44c64130006 100644 --- a/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj +++ b/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj @@ -1,5 +1,5 @@ - net8.0 + net7.0 diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj b/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj index 761ac6354ce861..33858b9a6a755f 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj +++ b/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj @@ -4,7 +4,6 @@ browser-wasm Exe true - true diff --git a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs index 21170ea2152843..62817719af0a14 100644 --- a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs +++ b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs @@ -301,8 +301,8 @@ private bool InstallWorkloadManifest(ITaskItem workloadId, string name, string v string packagePreleaseVersion = bandVersionRegex().Match(version).Groups[1].Value; string bandPreleaseVersion = bandVersionRegex().Match(bandVersion).Groups[1].Value; - if (packagePreleaseVersion != bandPreleaseVersion && packagePreleaseVersion != "-dev" && packagePreleaseVersion != "-ci" && bandPreleaseVersion != "") - bandVersion = bandVersion.Replace(bandPreleaseVersion, packagePreleaseVersion); + if (packagePreleaseVersion != bandPreleaseVersion && packagePreleaseVersion != "-dev" && packagePreleaseVersion != "-ci") + bandVersion = bandVersion.Replace (bandPreleaseVersion, packagePreleaseVersion); PackageReference pkgRef = new(Name: $"{name}.Manifest-{bandVersion}", Version: version, From b62c8ff4a7044c8e7008a4d9f83b1d6560d9c86a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:00:00 -0700 Subject: [PATCH 438/783] [release/8.0-staging] Support IValidatableObject for nested model types in options source gen (#94062) Co-authored-by: Tarek Mahmoud Sayed --- .../gen/Parser.cs | 2 +- .../src/Microsoft.Extensions.Options.csproj | 2 + .../Baselines/NetCoreApp/Validators.g.cs | 50 +++++++++++++++++++ .../Baselines/NetFX/Validators.g.cs | 48 ++++++++++++++++++ .../Generated/SelfValidationTests.cs | 10 +++- .../TestClasses/SelfValidation.cs | 20 ++++++++ 6 files changed, 130 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs b/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs index 47cb71c3411cde..ab2c19de81923a 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs @@ -687,7 +687,7 @@ private void TrackRangeAttributeForSubstitution(AttributeData attribute, ITypeSy var model = new ValidatedModel( GetFQN(mt), mt.Name, - false, + ModelSelfValidates(mt), membersToValidate); var validatorTypeName = "__" + mt.Name + "Validator__"; diff --git a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj index c7ea3e00049e3e..abbc5d2329c5c1 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj +++ b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj @@ -4,6 +4,8 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.1;netstandard2.0;$(NetFrameworkMinimum) true true + true + 1 Provides a strongly typed way of specifying and accessing settings using dependency injection. diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs index c487888c9f16bb..956cae26e90f6d 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs @@ -1154,6 +1154,41 @@ partial class FirstValidator } } namespace SelfValidation +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + internal sealed partial class __SecondModelValidator__ + { + /// + /// Validates a specific named options instance (or all when is ). + /// + /// The name of the options instance being validated. + /// The options instance. + /// Validation result. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] + public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::SelfValidation.SecondModel options) + { + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; + var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); + var validationResults = new global::System.Collections.Generic.List(); + var validationAttributes = new global::System.Collections.Generic.List(1); + + context.MemberName = "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P3" : $"{name}.P3"; + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + (builder ??= new()).AddResults(((global::System.ComponentModel.DataAnnotations.IValidatableObject)options).Validate(context)); + + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); + } + } +} +namespace SelfValidation { partial struct FirstValidator { @@ -1181,6 +1216,21 @@ partial struct FirstValidator (builder ??= new()).AddResults(validationResults); } + context.MemberName = "P2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + if (options.P2 is not null) + { + (builder ??= new()).AddResult(global::SelfValidation.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2", options.P2)); + } + (builder ??= new()).AddResults(((global::System.ComponentModel.DataAnnotations.IValidatableObject)options).Validate(context)); return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs index 7e998cea22cddf..faae7d62d9c410 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs @@ -1098,6 +1098,39 @@ partial class FirstValidator } } namespace SelfValidation +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + internal sealed partial class __SecondModelValidator__ + { + /// + /// Validates a specific named options instance (or all when is ). + /// + /// The name of the options instance being validated. + /// The options instance. + /// Validation result. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + public static global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::SelfValidation.SecondModel options) + { + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; + var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); + var validationResults = new global::System.Collections.Generic.List(); + var validationAttributes = new global::System.Collections.Generic.List(1); + + context.MemberName = "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "SecondModel.P3" : $"{name}.P3"; + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + (builder ??= new()).AddResults(((global::System.ComponentModel.DataAnnotations.IValidatableObject)options).Validate(context)); + + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); + } + } +} +namespace SelfValidation { partial struct FirstValidator { @@ -1123,6 +1156,21 @@ partial struct FirstValidator (builder ??= new()).AddResults(validationResults); } + context.MemberName = "P2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A1); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + if (options.P2 is not null) + { + (builder ??= new()).AddResult(global::SelfValidation.__SecondModelValidator__.Validate(string.IsNullOrEmpty(name) ? "FirstModel.P2" : $"{name}.P2", options.P2)); + } + (builder ??= new()).AddResults(((global::System.ComponentModel.DataAnnotations.IValidatableObject)options).Validate(context)); return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/SelfValidationTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/SelfValidationTests.cs index 0a511333f03571..36d15fe74a10e5 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/SelfValidationTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/SelfValidationTests.cs @@ -15,12 +15,16 @@ public void Invalid() var firstModel = new FirstModel { P1 = "1234", + P2 = new SecondModel + { + P3 = "5678" + } }; var validator = default(FirstValidator); var vr = validator.Validate("SelfValidation", firstModel); - Utils.VerifyValidateOptionsResult(vr, 1, "P1"); + Utils.VerifyValidateOptionsResult(vr, 2, "P3", "P1"); } [Fact] @@ -29,6 +33,10 @@ public void Valid() var firstModel = new FirstModel { P1 = "12345", + P2 = new SecondModel + { + P3 = "67890" + } }; var validator = default(FirstValidator); diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/TestClasses/SelfValidation.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/TestClasses/SelfValidation.cs index 1ca4e93142a372..893c3ffc90ad99 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/TestClasses/SelfValidation.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/TestClasses/SelfValidation.cs @@ -15,6 +15,10 @@ public class FirstModel : IValidatableObject [Required] public string P1 { get; set; } = string.Empty; + [Required] + [ValidateObjectMembers] + public SecondModel P2 { get; set; } + public IEnumerable Validate(ValidationContext validationContext) { if (P1.Length < 5) @@ -26,6 +30,22 @@ public IEnumerable Validate(ValidationContext validationContex } } + public class SecondModel : IValidatableObject + { + [Required] + public string P3 { get; set; } = string.Empty; + + public IEnumerable Validate(ValidationContext validationContext) + { + if (P3.Length < 5) + { + return new[] { new ValidationResult("P3 is not long enough") }; + } + + return Array.Empty(); + } + } + [OptionsValidator] public partial struct FirstValidator : IValidateOptions { From 85d1fce48f873b859c38213908645b6a23c70611 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:07:11 -0700 Subject: [PATCH 439/783] Update dependencies from https://github.com/dotnet/hotreload-utils build 20231023.2 (#93872) Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23518.2 -> To Version 8.0.0-alpha.0.23523.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 96128eaf65a696..54d1c7ee84bb22 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -354,9 +354,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization e5d9d61ccb43b9135a7471429b338aa7332e2eb5 - + https://github.com/dotnet/hotreload-utils - 7e01dcd64329d25070ad66af5eddd02410e80111 + 8e108a21d0c7d8fa2050a1bdd4d4ba50d2b8df13 https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index 788b7c1ab4ea96..40ce1ee40a1a38 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -186,7 +186,7 @@ 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 - 8.0.0-alpha.0.23518.2 + 8.0.0-alpha.0.23523.2 2.4.2 1.0.0 2.4.5 From f5f1aafcc904a8cb8853d7e6ce0daa546ffd3840 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:07:39 -0700 Subject: [PATCH 440/783] Update dependencies from https://github.com/dotnet/icu build 20231023.2 (#93873) Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rtm.23511.1 -> To Version 8.0.0-rtm.23523.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 54d1c7ee84bb22..c8106a1e06857f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/icu - feea7b8dcee39fd35ee6c415197e47d19102bb0b + e76010c828e5913da4b6a5332f4d8b14f660dd88 https://github.com/dotnet/msquic diff --git a/eng/Versions.props b/eng/Versions.props index 40ce1ee40a1a38..d1fcf7ad767d7a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -217,7 +217,7 @@ 8.0.0-rc.1.23406.6 - 8.0.0-rtm.23511.1 + 8.0.0-rtm.23523.2 2.2.3 8.0.0-alpha.1.23468.1 From bc0b9fbaf43c1a13c22a64eea5c99f79f518d4f4 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:09:49 -0700 Subject: [PATCH 441/783] [release/8.0-staging] Update dependencies from dotnet/roslyn-analyzers (#94037) * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231025.2 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23516.2 -> To Version 3.11.0-beta1.23525.2 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231025.2 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23516.2 -> To Version 3.11.0-beta1.23525.2 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231025.2 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23516.2 -> To Version 3.11.0-beta1.23525.2 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231025.2 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23516.2 -> To Version 3.11.0-beta1.23525.2 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231025.2 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23516.2 -> To Version 3.11.0-beta1.23525.2 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c8106a1e06857f..c789ea64ef6eec 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -375,13 +375,13 @@ https://github.com/dotnet/roslyn 12b11685a551e0a6a203dcecb584f610f4df1157 - + https://github.com/dotnet/roslyn-analyzers - 4ff28092cdb2006c30869fb35b2fd6b7b11382b1 + b4d9a1334d5189172977ba8fddd00bda70161e4a - + https://github.com/dotnet/roslyn-analyzers - 4ff28092cdb2006c30869fb35b2fd6b7b11382b1 + b4d9a1334d5189172977ba8fddd00bda70161e4a https://github.com/dotnet/sdk diff --git a/eng/Versions.props b/eng/Versions.props index d1fcf7ad767d7a..08440b6bb132c6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -36,8 +36,8 @@ - 3.11.0-beta1.23516.2 - 8.0.0-preview.23516.2 + 3.11.0-beta1.23525.2 + 8.0.0-preview.23525.2 - + - 8.0.0 + 8.0.1 8 0 - 0 + 1 8.0.100 7.0.14 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) From 141b386ee2acf1827f728e331552725f0e084fff Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 8 Nov 2023 09:45:19 -0500 Subject: [PATCH 446/783] [release/8.0-staging] [mono] [imt] Don't increment vt_slot for non-virtual generic methods (#94469) * [mono] [imt] Don't increment vt_slot for non-virtual generic methods Interfaces can have static generic methods, for example. They don't have a vt_slot. When building an IMT slot, we need to collect all the interface methods that map to a particular IMT slot along with their implementing vtable entries. To do that, vt_slot starts at the interface offset of a particular interface and keeps incrementing as we iterate over the methods of the interface. It is crtitical that vt_slot is accurate - otherwise we may dispatch the interface call to the wrong virtual method. Fixes https://github.com/dotnet/runtime/issues/93770 * [mono][imt] remove dead appdomain code the extra_interfaces argument was used to implement additional interfaces on cross-domain transparent proxy objects. * [mono][imt] fixup ifdefed debug code * Add test case --------- Co-authored-by: Aleksey Kliger --- src/mono/mono/metadata/object.c | 32 ++--- .../regressions/GitHub_93770/GitHub_93770.cs | 128 ++++++++++++++++++ .../GitHub_93770/GitHub_93770.csproj | 7 + 3 files changed, 143 insertions(+), 24 deletions(-) create mode 100644 src/tests/Loader/classloader/regressions/GitHub_93770/GitHub_93770.cs create mode 100644 src/tests/Loader/classloader/regressions/GitHub_93770/GitHub_93770.csproj diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index 0b79c0d713b67e..a0e271130ffe7d 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -1384,8 +1384,8 @@ print_imt_entry (const char* message, MonoImtBuilderEntry *e, int num) { message, num, method, - method->klass->name_space, - method->klass->name, + m_class_get_name_space (method->klass), + m_class_get_name (method->klass), method->name); } else { printf (" * %s: NULL\n", message); @@ -1497,12 +1497,11 @@ get_generic_virtual_entries (MonoMemoryManager *mem_manager, gpointer *vtable_sl * */ static void -build_imt_slots (MonoClass *klass, MonoVTable *vt, gpointer* imt, GSList *extra_interfaces, int slot_num) +build_imt_slots (MonoClass *klass, MonoVTable *vt, gpointer* imt, int slot_num) { MONO_REQ_GC_NEUTRAL_MODE; int i; - GSList *list_item; guint32 imt_collisions_bitmap = 0; MonoImtBuilderEntry **imt_builder = (MonoImtBuilderEntry **)g_calloc (MONO_IMT_SIZE, sizeof (MonoImtBuilderEntry*)); int method_count = 0; @@ -1550,8 +1549,10 @@ build_imt_slots (MonoClass *klass, MonoVTable *vt, gpointer* imt, GSList *extra_ } method = mono_class_get_method_by_index (iface, method_slot_in_interface); if (method->is_generic) { - has_generic_virtual = TRUE; - vt_slot ++; + if (m_method_is_virtual (method)) { + has_generic_virtual = TRUE; + vt_slot ++; + } continue; } @@ -1567,23 +1568,6 @@ build_imt_slots (MonoClass *klass, MonoVTable *vt, gpointer* imt, GSList *extra_ } } } - if (extra_interfaces) { - int interface_offset = m_class_get_vtable_size (klass); - - for (list_item = extra_interfaces; list_item != NULL; list_item=list_item->next) { - MonoClass* iface = (MonoClass *)list_item->data; - int method_slot_in_interface; - int mcount = mono_class_get_method_count (iface); - for (method_slot_in_interface = 0; method_slot_in_interface < mcount; method_slot_in_interface++) { - MonoMethod *method = mono_class_get_method_by_index (iface, method_slot_in_interface); - - if (method->is_generic) - has_generic_virtual = TRUE; - add_imt_builder_entry (imt_builder, method, &imt_collisions_bitmap, interface_offset + method_slot_in_interface, slot_num); - } - interface_offset += mcount; - } - } for (i = 0; i < MONO_IMT_SIZE; ++i) { /* overwrite the imt slot only if we're building all the entries or if * we're building this specific one @@ -1683,7 +1667,7 @@ mono_vtable_build_imt_slot (MonoVTable* vtable, int imt_slot) mono_loader_lock (); /* we change the slot only if it wasn't changed from the generic imt trampoline already */ if (!callbacks.imt_entry_inited (vtable, imt_slot)) - build_imt_slots (vtable->klass, vtable, imt, NULL, imt_slot); + build_imt_slots (vtable->klass, vtable, imt, imt_slot); mono_loader_unlock (); } diff --git a/src/tests/Loader/classloader/regressions/GitHub_93770/GitHub_93770.cs b/src/tests/Loader/classloader/regressions/GitHub_93770/GitHub_93770.cs new file mode 100644 index 00000000000000..7784ed40a0c73d --- /dev/null +++ b/src/tests/Loader/classloader/regressions/GitHub_93770/GitHub_93770.cs @@ -0,0 +1,128 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using Xunit; + +namespace ReproGH93770; + +// By default in Mono every class that implements interfaces has 19 +// interface method table slots that are used to dispatch interface +// calls. The methods are assigned to slots based on a hash of some +// metadata. This test tries to create at least one IMT slot that has +// a collision by creating an interface with 20 virtual methods. +// +// The bug is that if the method also has a non-virtual generic +// method, the IMT slot with the collision calls the wrong vtable +// element. + +public class ReproGH93770 +{ + [Fact] + public static int TestEntryPoint() + { + C c = new C(); + I1 i1 = c; + Helper(i1); + return 100; + } + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Helper(I1 i1) + { + var e = 0; + var n = i1.M0(); + Assert.Equal(e, n); + e++; + n = i1.M1(); + Assert.Equal(e, n); + e++; + n = i1.M2(); + Assert.Equal(e, n); + e++; + n = i1.M3(); + Assert.Equal(e, n); + e++; + n = i1.M4(); + Assert.Equal(e, n); + e++; + n = i1.M5(); + Assert.Equal(e, n); + e++; + n = i1.M6(); + Assert.Equal(e, n); + e++; + n = i1.M7(); + Assert.Equal(e, n); + e++; + n = i1.M8(); + Assert.Equal(e, n); + e++; + n = i1.M9(); + Assert.Equal(e, n); + e++; + n = i1.M10(); + Assert.Equal(e, n); + e++; + n = i1.M11(); + Assert.Equal(e, n); + e++; + n = i1.M12(); + Assert.Equal(e, n); + e++; + n = i1.M13(); + Assert.Equal(e, n); + e++; + n = i1.M14(); + Assert.Equal(e, n); + e++; + n = i1.M15(); + Assert.Equal(e, n); + e++; + n = i1.M16(); + Assert.Equal(e, n); + e++; + n = i1.M17(); + Assert.Equal(e, n); + e++; + n = i1.M18(); + Assert.Equal(e, n); + e++; + n = i1.M19(); + Assert.Equal(e, n); + e++; + } +} + +public interface I1 { + public static T Id (T t)=> t; + + public int M0() => 0; + public int M1() => 1; + public int M2() => 2; + public int M3() => 3; + public int M4() => 4; + + public int M5() => 5; + public int M6() => 6; + public int M7() => 7; + public int M8() => 8; + public int M9() => 9; + public int M10() => 10; + public int M11() => 11; + public int M12() => 12; + public int M13() => 13; + public int M14() => 14; + public int M15() => 15; + public int M16() => 16; + public int M17() => 17; + public int M18() => 18; + public int M19() => 19; + +} + +public class C : I1 { + +} + + diff --git a/src/tests/Loader/classloader/regressions/GitHub_93770/GitHub_93770.csproj b/src/tests/Loader/classloader/regressions/GitHub_93770/GitHub_93770.csproj new file mode 100644 index 00000000000000..72aaed3e55208c --- /dev/null +++ b/src/tests/Loader/classloader/regressions/GitHub_93770/GitHub_93770.csproj @@ -0,0 +1,7 @@ + + + + + + + From d8e799683ed5db9c8afe7f75a3d1b64c0151485f Mon Sep 17 00:00:00 2001 From: Matt Mitchell Date: Wed, 8 Nov 2023 11:51:33 -0800 Subject: [PATCH 447/783] Update to servicing branding (#94526) --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 602667e9057a80..141c333bf098e3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -9,7 +9,7 @@ 8.0.100 7.0.14 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) - rtm + servicing From e97e97d929f3ef2e084425c0fde3c337f0532e58 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 8 Nov 2023 12:09:02 -0800 Subject: [PATCH 448/783] [release/8.0] Update dependencies from dotnet/hotreload-utils dotnet/icu (#93919) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/dotnet/hotreload-utils build 20231023.2 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23518.2 -> To Version 8.0.0-alpha.0.23523.2 * Update dependencies from https://github.com/dotnet/icu build 20231023.2 Microsoft.NETCore.Runtime.ICU.Transport From Version 8.0.0-rtm.23511.1 -> To Version 8.0.0-rtm.23523.2 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 11e66be9b72e5e..fae8eacddfa116 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/icu - feea7b8dcee39fd35ee6c415197e47d19102bb0b + e76010c828e5913da4b6a5332f4d8b14f660dd88 https://github.com/dotnet/msquic @@ -354,9 +354,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization e5d9d61ccb43b9135a7471429b338aa7332e2eb5 - + https://github.com/dotnet/hotreload-utils - 7e01dcd64329d25070ad66af5eddd02410e80111 + 8e108a21d0c7d8fa2050a1bdd4d4ba50d2b8df13 https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index 141c333bf098e3..1ef0940771fd3f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -186,7 +186,7 @@ 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 - 8.0.0-alpha.0.23518.2 + 8.0.0-alpha.0.23523.2 2.4.2 1.0.0 2.4.5 @@ -217,7 +217,7 @@ 8.0.0-rc.1.23406.6 - 8.0.0-rtm.23511.1 + 8.0.0-rtm.23523.2 2.2.3 8.0.0-alpha.1.23468.1 From ef625e47d01e0eba5fcd07f5a61dd8eeaf538875 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 8 Nov 2023 12:17:42 -0800 Subject: [PATCH 449/783] [release/8.0-staging] Update dependencies from dotnet/hotreload-utils (#94309) * Update dependencies from https://github.com/dotnet/hotreload-utils build 20231102.2 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23523.2 -> To Version 8.0.0-alpha.0.23552.2 * Update dependencies from https://github.com/dotnet/hotreload-utils build 20231106.2 Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23523.2 -> To Version 8.0.0-alpha.0.23556.2 --------- Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 3 +++ eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/NuGet.config b/NuGet.config index 29f8225aac34fb..0774b81f58ec7c 100644 --- a/NuGet.config +++ b/NuGet.config @@ -10,6 +10,9 @@ + + + + + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index fae8eacddfa116..7e072d4ec91ac9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -375,13 +375,13 @@ https://github.com/dotnet/roslyn 12b11685a551e0a6a203dcecb584f610f4df1157 - + https://github.com/dotnet/roslyn-analyzers - 4ff28092cdb2006c30869fb35b2fd6b7b11382b1 + b4d9a1334d5189172977ba8fddd00bda70161e4a - + https://github.com/dotnet/roslyn-analyzers - 4ff28092cdb2006c30869fb35b2fd6b7b11382b1 + b4d9a1334d5189172977ba8fddd00bda70161e4a https://github.com/dotnet/sdk diff --git a/eng/Versions.props b/eng/Versions.props index 1ef0940771fd3f..6d98e283670779 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -36,8 +36,8 @@ - 3.11.0-beta1.23516.2 - 8.0.0-preview.23516.2 + 3.11.0-beta1.23525.2 + 8.0.0-preview.23525.2 2.2.3 - 8.0.0-alpha.1.23468.1 + 8.0.0-alpha.1.23527.1 16.0.5-alpha.1.23478.1 16.0.5-alpha.1.23478.1 From a4d11e2e795d0701779ded30709682d0d8a72223 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 8 Nov 2023 17:59:59 -0800 Subject: [PATCH 453/783] [release/8.0] Update dependencies from dnceng/internal/dotnet-optimization (#94035) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231025.5 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23521.3 -> To Version 1.0.0-prerelease.23525.5 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3ff9296395579d..c3e52bea99c64c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -338,21 +338,21 @@ https://github.com/dotnet/arcade 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - e5d9d61ccb43b9135a7471429b338aa7332e2eb5 + d80a861521d84459c9290c31127b2a0ce511f279 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - e5d9d61ccb43b9135a7471429b338aa7332e2eb5 + d80a861521d84459c9290c31127b2a0ce511f279 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - e5d9d61ccb43b9135a7471429b338aa7332e2eb5 + d80a861521d84459c9290c31127b2a0ce511f279 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - e5d9d61ccb43b9135a7471429b338aa7332e2eb5 + d80a861521d84459c9290c31127b2a0ce511f279 https://github.com/dotnet/hotreload-utils @@ -388,13 +388,13 @@ 7e33fd449381b337c290a801057fdcd68c4b7220 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - e5d9d61ccb43b9135a7471429b338aa7332e2eb5 + d80a861521d84459c9290c31127b2a0ce511f279 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - e5d9d61ccb43b9135a7471429b338aa7332e2eb5 + d80a861521d84459c9290c31127b2a0ce511f279 diff --git a/eng/Versions.props b/eng/Versions.props index dedd6acc6ec5e8..8f044d7cd3a21e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23521.3 - 1.0.0-prerelease.23521.3 - 1.0.0-prerelease.23521.3 - 1.0.0-prerelease.23521.3 - 1.0.0-prerelease.23521.3 - 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23525.5 + 1.0.0-prerelease.23525.5 + 1.0.0-prerelease.23525.5 + 1.0.0-prerelease.23525.5 + 1.0.0-prerelease.23525.5 + 1.0.0-prerelease.23525.5 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From 6c6c111f04347cccb1bcc55341f041baca5e21f9 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 8 Nov 2023 18:01:24 -0800 Subject: [PATCH 454/783] [release/8.0] Update dependencies from dotnet/runtime-assets (#94520) * Update dependencies from https://github.com/dotnet/runtime-assets build 20231108.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23421.1 -> To Version 8.0.0-beta.23558.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20231108.5 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23421.1 -> To Version 8.0.0-beta.23558.5 --------- Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 ++ eng/Version.Details.xml | 56 ++++++++++++++++++++--------------------- eng/Versions.props | 28 ++++++++++----------- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/NuGet.config b/NuGet.config index b2e7776ca0af93..4a661d10176116 100644 --- a/NuGet.config +++ b/NuGet.config @@ -14,6 +14,8 @@ + + - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 1.0.0-prerelease.23525.5 1.0.0-prerelease.23525.5 From 87fbb389d9e18f9249aa9cc609916cd22be9746a Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Thu, 9 Nov 2023 18:19:38 +0100 Subject: [PATCH 455/783] [release/8.0-staging] Socket Tests Disable (#94243) * Linux Kernel Regression Socket Test Failures Disable * Fix formatting * Delete spaces * Format Connect.cs * Revert "Format Connect.cs" This reverts commit 6ee1383a1d300668654d26cdb085b21f8f70f722. * Add spaces again --- .../System.Net.Sockets/tests/FunctionalTests/Connect.cs | 6 ++++++ .../tests/FunctionalTests/TelemetryTest.cs | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs index 7fbb92a2717428..7c8afc925f7388 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs @@ -137,6 +137,12 @@ public async Task Connect_AfterDisconnect_Fails() [InlineData("[::ffff:1.1.1.1]", true, false)] public async Task ConnectGetsCanceledByDispose(string addressString, bool useDns, bool owning) { + if (UsesSync && PlatformDetection.IsLinux) + { + // [ActiveIssue("https://github.com/dotnet/runtime/issues/94149", TestPlatforms.Linux)] + return; + } + // Aborting sync operations for non-owning handles is not supported on Unix. if (!owning && UsesSync && !PlatformDetection.IsWindows) { diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/TelemetryTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/TelemetryTest.cs index 851b68288fd866..0f342572c6c6bf 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/TelemetryTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/TelemetryTest.cs @@ -193,6 +193,12 @@ await listener.RunWithCallbackAsync(e => events.Enqueue((e, e.ActivityId)), asyn [MemberData(nameof(SocketMethods_WithBools_MemberData))] public void EventSource_SocketConnectFailure_LogsConnectFailed(string connectMethod, bool useDnsEndPoint) { + if (connectMethod == "Sync" && PlatformDetection.IsLinux) + { + // [ActiveIssue("https://github.com/dotnet/runtime/issues/94149", TestPlatforms.Linux)] + return; + } + RemoteExecutor.Invoke(async (connectMethod, useDnsEndPointString) => { EndPoint endPoint = await GetRemoteEndPointAsync(useDnsEndPointString, port: 12345); From dd683c852a9b8cac2e93f28d45babc36240573d1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 14:54:20 -0800 Subject: [PATCH 456/783] [release/8.0] Update dependencies from dotnet/roslyn (#93915) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/dotnet/roslyn build 20231024.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23518.7 -> To Version 4.8.0-3.23524.2 * Update dependencies from https://github.com/dotnet/roslyn build 20231024.10 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23518.7 -> To Version 4.8.0-3.23524.10 * Update dependencies from https://github.com/dotnet/roslyn build 20231024.11 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23518.7 -> To Version 4.8.0-3.23524.11 * Update dependencies from https://github.com/dotnet/roslyn build 20231102.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23518.7 -> To Version 4.8.0-7.23552.5 * Update dependencies from https://github.com/dotnet/roslyn build 20231103.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23518.7 -> To Version 4.8.0-7.23553.3 * Update dependencies from https://github.com/dotnet/roslyn build 20231108.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-3.23518.7 -> To Version 4.8.0-7.23558.1 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6ababc33f4c3f4..784d1e8dd17f6f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -362,18 +362,18 @@ https://github.com/dotnet/runtime-assets 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/roslyn - 12b11685a551e0a6a203dcecb584f610f4df1157 + e091728607ca0fc9efca55ccfb3e59259c6b5a0a - + https://github.com/dotnet/roslyn - 12b11685a551e0a6a203dcecb584f610f4df1157 + e091728607ca0fc9efca55ccfb3e59259c6b5a0a - + https://github.com/dotnet/roslyn - 12b11685a551e0a6a203dcecb584f610f4df1157 + e091728607ca0fc9efca55ccfb3e59259c6b5a0a https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index 64cc2fc3f98b51..d2b92fe791e826 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -44,9 +44,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-3.23518.7 - 4.8.0-3.23518.7 - 4.8.0-3.23518.7 + 4.8.0-7.23558.1 + 4.8.0-7.23558.1 + 4.8.0-7.23558.1 8.0.100-rtm.23520.8 - 8.0.0-beta.23516.4 - 8.0.0-beta.23516.4 - 8.0.0-beta.23516.4 - 8.0.0-beta.23516.4 - 8.0.0-beta.23516.4 - 2.5.1-beta.23516.4 - 8.0.0-beta.23516.4 - 8.0.0-beta.23516.4 - 8.0.0-beta.23516.4 - 8.0.0-beta.23516.4 - 8.0.0-beta.23516.4 - 8.0.0-beta.23516.4 - 8.0.0-beta.23516.4 - 8.0.0-beta.23516.4 - 8.0.0-beta.23516.4 + 8.0.0-beta.23556.5 + 8.0.0-beta.23556.5 + 8.0.0-beta.23556.5 + 8.0.0-beta.23556.5 + 8.0.0-beta.23556.5 + 2.5.1-beta.23556.5 + 8.0.0-beta.23556.5 + 8.0.0-beta.23556.5 + 8.0.0-beta.23556.5 + 8.0.0-beta.23556.5 + 8.0.0-beta.23556.5 + 8.0.0-beta.23556.5 + 8.0.0-beta.23556.5 + 8.0.0-beta.23556.5 + 8.0.0-beta.23556.5 6.0.0-preview.1.102 diff --git a/global.json b/global.json index 38ec23b6193a2f..0ba22484d372e8 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.100-rtm.23506.1" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23516.4", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23516.4", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23516.4", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23556.5", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23556.5", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23556.5", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From 34119e287b549aceb10117fa55d5beba905e5760 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 14:55:28 -0800 Subject: [PATCH 458/783] [release/8.0-staging] Update dependencies from dotnet/emsdk (#94197) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/dotnet/emsdk build 20231030.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.0-rtm.23523.2 -> To Version 8.0.0-rtm.23530.2 * Update dependencies from https://github.com/dotnet/emsdk build 20231108.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.0-rtm.23523.2 -> To Version 8.0.0-rtm.23558.2 * Update dependencies from https://github.com/dotnet/emsdk build 20231108.4 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.0-rtm.23523.2 -> To Version 8.0.1-rtm.23558.4 * Update dependencies from https://github.com/dotnet/emsdk build 20231109.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.0-rtm.23523.2 -> To Version 8.0.1-servicing.23559.1 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- NuGet.config | 5 +---- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/NuGet.config b/NuGet.config index 0774b81f58ec7c..1ca1556e66b4a1 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,10 +9,7 @@ - - - - + - 8.0.0 + 8.0.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda From 7ebc464a88a6553d7fe90226979d3402231a30fe Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 14:56:31 -0800 Subject: [PATCH 459/783] Update dependencies from https://github.com/dotnet/runtime-assets build 20231108.5 (#94568) Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23421.1 -> To Version 8.0.0-beta.23558.5 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 56 ++++++++++++++++++++--------------------- eng/Versions.props | 28 ++++++++++----------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4b6e21c8fa783a..0f135f24c91152 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -185,57 +185,57 @@ https://github.com/dotnet/arcade 39042b4048580366d35a7c1c4f4ce8fc0dbea4b4 - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d https://github.com/dotnet/llvm-project @@ -358,9 +358,9 @@ https://github.com/dotnet/hotreload-utils 86c49390a5b9ab8673f976dcdd4a60b073bab083 - + https://github.com/dotnet/runtime-assets - 99168dcff56809205e7ef8530d1256f3a07fab1f + 59430f9a34c6fba965d1941a7eb5df08ed24cc2d https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index 93080f06215bfe..9f7f8a3a7de710 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -143,20 +143,20 @@ 4.5.0 8.0.0-rc.1.23406.6 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 - 8.0.0-beta.23421.1 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 + 8.0.0-beta.23558.5 1.0.0-prerelease.23521.3 1.0.0-prerelease.23521.3 From 87d0f4555926ce0779cd4cacca9e7940e0f5653d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 20:37:23 -0500 Subject: [PATCH 460/783] [release/8.0-staging] Remove [EditorBrowsable(Never)] from [InlineArray], add XML docs (#94343) * Remove [EditorBrowsable] from [InlineArray] * Add XML comments * Tweak XML docs following review comments Co-authored-by: Stephen Toub --------- Co-authored-by: Sergio Pedri Co-authored-by: Stephen Toub --- .../CompilerServices/InlineArrayAttribute.cs | 22 ++++++++++++++++--- .../System.Runtime/ref/System.Runtime.cs | 1 - 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/InlineArrayAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/InlineArrayAttribute.cs index 9872c61e191ffa..0ce7e225042538 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/InlineArrayAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/InlineArrayAttribute.cs @@ -1,22 +1,38 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.ComponentModel; - namespace System.Runtime.CompilerServices { /// /// Indicates that the instance's storage is sequentially replicated "length" times. /// - [EditorBrowsable(EditorBrowsableState.Never)] + /// + /// + /// This attribute can be used to annotate a type with a single field. + /// The runtime will replicate that field in the actual type layout as many times as is specified. + /// + /// + /// Here's an example of how an inline array type with 8 values can be declared: + /// + /// [InlineArray(8)] + /// struct Float8InlineArray + /// { + /// private float _value; + /// } + /// + /// + /// [AttributeUsage(AttributeTargets.Struct, AllowMultiple = false)] public sealed class InlineArrayAttribute : Attribute { + /// Creates a new instance with the specified length. + /// The number of sequential fields to replicate in the inline array type. public InlineArrayAttribute(int length) { Length = length; } + /// Gets the number of sequential fields to replicate in the inline array type. public int Length { get; } } } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index bc7e04a54f96b3..18a8775076bd90 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -12888,7 +12888,6 @@ public sealed partial class InterpolatedStringHandlerAttribute : System.Attribut public InterpolatedStringHandlerAttribute() { } } [System.AttributeUsageAttribute(System.AttributeTargets.Struct, AllowMultiple = false)] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public sealed partial class InlineArrayAttribute : System.Attribute { public InlineArrayAttribute(int length) { } From ba7bf7840fc5fd0d4eb98ae6fa54aab5ea5bc937 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 10 Nov 2023 11:32:09 +0100 Subject: [PATCH 461/783] Correctly set sendTrustList flag when saving credentials to cache (#92731) (#94402) Co-authored-by: Radek Zikmund <32671551+rzikm@users.noreply.github.com> --- .../src/System/Net/Security/SslStream.Protocol.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs index 8c258b6f6bc5d5..38274fd85acd8d 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs @@ -817,15 +817,12 @@ private SecurityStatusPal GenerateToken(ReadOnlySpan inputBuffer, ref byte cachedCreds = _sslAuthenticationOptions.IsServer ? AcquireServerCredentials(ref thumbPrint) : AcquireClientCredentials(ref thumbPrint); - - if (cachedCreds && _sslAuthenticationOptions.IsServer) - { - sendTrustList = _sslAuthenticationOptions.CertificateContext?.Trust?._sendTrustInHandshake ?? false; - } } if (_sslAuthenticationOptions.IsServer) { + sendTrustList = _sslAuthenticationOptions.CertificateContext?.Trust?._sendTrustInHandshake ?? false; + status = SslStreamPal.AcceptSecurityContext( ref _credentialsHandle!, ref _securityContext, From 6b9220bc027be34f216ac17104bd7072b284606e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 10 Nov 2023 15:41:04 +0100 Subject: [PATCH 462/783] [release/8.0-staging] [Android] Fix SslStream on Android API 21-23 (#94506) Co-authored-by: Simon Rozsival --- .../pal_jni.c | 13 +++++++ .../pal_jni.h | 2 ++ .../pal_sslstream.c | 36 +++++++++++++++---- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c index 27a36b43f30ae3..d562451ee54a04 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c @@ -86,6 +86,7 @@ jmethodID g_SSLParametersSetServerNames; // com/android/org/conscrypt/OpenSSLEngineImpl jclass g_ConscryptOpenSSLEngineImplClass; jfieldID g_ConscryptOpenSSLEngineImplSslParametersField; +jfieldID g_ConscryptOpenSSLEngineImplHandshakeSessionField; // com/android/org/conscrypt/SSLParametersImpl jclass g_ConscryptSSLParametersImplClass; @@ -627,6 +628,17 @@ jfieldID GetField(JNIEnv *env, bool isStatic, jclass klass, const char* name, co return fid; } +jfieldID GetOptionalField(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) +{ + jfieldID fid = isStatic ? (*env)->GetStaticFieldID(env, klass, name, sig) : (*env)->GetFieldID(env, klass, name, sig); + if (!fid) { + LOG_INFO("optional field %s %s was not found", name, sig); + // Failing to find an optional field causes an exception state, which we need to clear. + TryClearJNIExceptions(env); + } + return fid; +} + static void DetachThreadFromJNI(void* unused) { LOG_DEBUG("Detaching thread from JNI"); @@ -761,6 +773,7 @@ JNI_OnLoad(JavaVM *vm, void *reserved) if (g_ConscryptOpenSSLEngineImplClass != NULL) { g_ConscryptOpenSSLEngineImplSslParametersField = GetField(env, false, g_ConscryptOpenSSLEngineImplClass, "sslParameters", "Lcom/android/org/conscrypt/SSLParametersImpl;"); + g_ConscryptOpenSSLEngineImplHandshakeSessionField = GetOptionalField(env, false, g_ConscryptOpenSSLEngineImplClass, "handshakeSession", "Lcom/android/org/conscrypt/OpenSSLSessionImpl;"); g_ConscryptSSLParametersImplClass = GetClassGRef(env, "com/android/org/conscrypt/SSLParametersImpl"); g_ConscryptSSLParametersImplSetUseSni = GetMethod(env, false, g_ConscryptSSLParametersImplClass, "setUseSni", "(Z)V"); diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h index 341a274ba110ee..d1dc577bdf078a 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h @@ -98,6 +98,7 @@ extern jmethodID g_SSLParametersSetServerNames; // com/android/org/conscrypt/OpenSSLEngineImpl extern jclass g_ConscryptOpenSSLEngineImplClass; extern jfieldID g_ConscryptOpenSSLEngineImplSslParametersField; +extern jfieldID g_ConscryptOpenSSLEngineImplHandshakeSessionField; // com/android/org/conscrypt/SSLParametersImpl extern jclass g_ConscryptSSLParametersImplClass; @@ -590,6 +591,7 @@ bool TryGetJNIException(JNIEnv* env, jthrowable *ex, bool printException) ARGS_N jmethodID GetMethod(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL; jmethodID GetOptionalMethod(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL; jfieldID GetField(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL; +jfieldID GetOptionalField(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL; JNIEnv* GetJNIEnv(void); int GetEnumAsInt(JNIEnv *env, jobject enumObj) ARGS_NON_NULL_ALL; diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.c index 37be72df3f494e..f19210fe9e05a6 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.c +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.c @@ -65,16 +65,38 @@ static bool IsHandshaking(int handshakeStatus) ARGS_NON_NULL(1, 2) static jobject GetSslSession(JNIEnv* env, SSLStream* sslStream, int handshakeStatus) { // During the initial handshake our sslStream->sslSession doesn't have access to the peer certificates - // which we need for hostname verification. Luckily, the SSLEngine has a getter for the handshake SSLSession. + // which we need for hostname verification. There are different ways to access the handshake session + // in different Android API levels. // SSLEngine.getHandshakeSession() is available since API 24. + // In older Android versions (API 21-23) we need to access the handshake session by accessing + // a private field instead. - jobject sslSession = IsHandshaking(handshakeStatus) && g_SSLEngineGetHandshakeSession != NULL - ? (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetHandshakeSession) - : (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetSession); - if (CheckJNIExceptions(env)) - return NULL; + if (g_SSLEngineGetHandshakeSession != NULL) + { + jobject sslSession = IsHandshaking(handshakeStatus) + ? (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetHandshakeSession) + : (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetSession); + if (CheckJNIExceptions(env)) + return NULL; - return sslSession; + return sslSession; + } + else if (g_ConscryptOpenSSLEngineImplHandshakeSessionField != NULL) + { + jobject sslSession = IsHandshaking(handshakeStatus) + ? (*env)->GetObjectField(env, sslStream->sslEngine, g_ConscryptOpenSSLEngineImplHandshakeSessionField) + : (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetSession); + if (CheckJNIExceptions(env)) + return NULL; + + return sslSession; + } + else + { + LOG_ERROR("Unable to get the current SSLSession from SSLEngine."); + assert(false && "Unable to get the current SSLSession from SSLEngine."); + return NULL; + } } ARGS_NON_NULL_ALL static jobject GetCurrentSslSession(JNIEnv* env, SSLStream* sslStream) From 27685cf47bf8001e363fd8e599796cfc1f2af871 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Fri, 10 Nov 2023 08:43:56 -0800 Subject: [PATCH 463/783] [release/8.0-staging] Avoid generating code for unsupported types in config source gen (#94588) --- .../ConfigurationBindingGenerator.Parser.cs | 91 +++++- .../gen/Emitter/CoreBindingHelpers.cs | 7 +- .../gen/Parser/KnownTypeSymbols.cs | 15 +- .../Baselines/UnsupportedTypes.generated.txt | 258 ++++++++++++++++++ .../ConfigBindingGenTestDriver.cs | 8 +- .../GeneratorTests.Baselines.cs | 160 ++++++++++- 6 files changed, 522 insertions(+), 17 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/UnsupportedTypes.generated.txt diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs index 849670bc04376c..2f6a221de90927 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Threading; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using SourceGenerators; namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration @@ -336,6 +337,11 @@ private TypeSpec CreateArraySpec(TypeParseInfo typeParseInfo) return CreateUnsupportedTypeSpec(typeParseInfo, NotSupportedReason.MultiDimArraysNotSupported); } + if (IsUnsupportedType(typeSymbol.ElementType)) + { + return CreateUnsupportedCollectionSpec(typeParseInfo); + } + TypeRef elementTypeRef = EnqueueTransitiveType( typeParseInfo, typeSymbol.ElementType, @@ -368,6 +374,11 @@ private TypeSpec CreateCollectionSpec(TypeParseInfo typeParseInfo) private TypeSpec CreateDictionarySpec(TypeParseInfo typeParseInfo, ITypeSymbol keyTypeSymbol, ITypeSymbol elementTypeSymbol) { + if (IsUnsupportedType(keyTypeSymbol) || IsUnsupportedType(elementTypeSymbol)) + { + return CreateUnsupportedCollectionSpec(typeParseInfo); + } + INamedTypeSymbol type = (INamedTypeSymbol)typeParseInfo.TypeSymbol; CollectionInstantiationStrategy instantiationStrategy; @@ -432,6 +443,11 @@ private TypeSpec CreateEnumerableSpec(TypeParseInfo typeParseInfo) return CreateUnsupportedCollectionSpec(typeParseInfo); } + if (IsUnsupportedType(elementType)) + { + return CreateUnsupportedCollectionSpec(typeParseInfo); + } + CollectionInstantiationStrategy instantiationStrategy; CollectionInstantiationConcreteType instantiationConcreteType; CollectionPopulationCastType populationCastType; @@ -500,6 +516,64 @@ private TypeSpec CreateEnumerableSpec(TypeParseInfo typeParseInfo) }; } + private bool IsAssignableTo(ITypeSymbol source, ITypeSymbol dest) + { + Conversion conversion = _typeSymbols.Compilation.ClassifyConversion(source, dest); + return conversion.IsReference && conversion.IsImplicit; + } + + private bool IsUnsupportedType(ITypeSymbol type) + { + if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) + { + type = ((INamedTypeSymbol)type).TypeArguments[0]; // extract the T from a Nullable + } + + if (SymbolEqualityComparer.Default.Equals(_typeSymbols.IntPtr, type) || + SymbolEqualityComparer.Default.Equals(_typeSymbols.UIntPtr, type) || + SymbolEqualityComparer.Default.Equals(_typeSymbols.SerializationInfo, type) || + SymbolEqualityComparer.Default.Equals(_typeSymbols.ParameterInfo, type) || + IsAssignableTo(type, _typeSymbols.MemberInfo) || + IsAssignableTo(type, _typeSymbols.Delegate)) + { + return true; + } + + if (type is IArrayTypeSymbol arrayTypeSymbol) + { + return arrayTypeSymbol.Rank > 1 || IsUnsupportedType(arrayTypeSymbol.ElementType); + } + + if (IsCollection(type)) + { + INamedTypeSymbol collectionType = (INamedTypeSymbol)type; + + if (IsCandidateDictionary(collectionType, out ITypeSymbol? keyType, out ITypeSymbol? elementType)) + { + return IsUnsupportedType(keyType) || IsUnsupportedType(elementType); + } + else if (TryGetElementType(collectionType, out elementType)) + { + return IsUnsupportedType(elementType); + } + } + + return false; + } + + private bool ConstructorParametersContainUnsupportedType(IMethodSymbol ctor) + { + foreach (IParameterSymbol parameter in ctor.Parameters) + { + if (IsUnsupportedType(parameter.Type)) + { + return true; + } + } + + return false; + } + private ObjectSpec CreateObjectSpec(TypeParseInfo typeParseInfo) { INamedTypeSymbol typeSymbol = (INamedTypeSymbol)typeParseInfo.TypeSymbol; @@ -527,13 +601,16 @@ private ObjectSpec CreateObjectSpec(TypeParseInfo typeParseInfo) { parameterlessCtor = candidate; } - else if (parameterizedCtor is not null) + else if (!ConstructorParametersContainUnsupportedType(candidate)) { - hasMultipleParameterizedCtors = true; - } - else - { - parameterizedCtor = candidate; + if (parameterizedCtor is not null) + { + hasMultipleParameterizedCtors = true; + } + else + { + parameterizedCtor = candidate; + } } } @@ -574,7 +651,7 @@ private ObjectSpec CreateObjectSpec(TypeParseInfo typeParseInfo) ImmutableArray members = current.GetMembers(); foreach (ISymbol member in members) { - if (member is IPropertySymbol { IsIndexer: false, IsImplicitlyDeclared: false } property) + if (member is IPropertySymbol { IsIndexer: false, IsImplicitlyDeclared: false } property && !IsUnsupportedType(property.Type)) { string propertyName = property.Name; TypeRef propertyTypeRef = EnqueueTransitiveType(typeParseInfo, property.Type, DiagnosticDescriptors.PropertyNotSupported, propertyName); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs index 4f72740d91335c..0f02f8aebcafb1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs @@ -102,9 +102,10 @@ private void EmitGetCoreMethod() bool isFirstType = true; foreach (TypeSpec type in targetTypes) { - Debug.Assert(_typeIndex.CanBindTo(type.TypeRef)); - TypeSpec effectiveType = _typeIndex.GetEffectiveTypeSpec(type); + + Debug.Assert(effectiveType is UnsupportedTypeSpec || _typeIndex.CanBindTo(type.TypeRef)); + string conditionKindExpr = GetConditionKindExpr(ref isFirstType); EmitStartBlock($"{conditionKindExpr} ({Identifier.type} == typeof({type.TypeRef.FullyQualifiedName}))"); @@ -501,7 +502,7 @@ private void EmitValidateConfigurationKeysMethod() if ({{Identifier.binderOptions}}?.{{Identifier.ErrorOnUnknownConfiguration}} is true) { {{TypeDisplayString.ListOfString}}? {{Identifier.temp}} = null; - + foreach ({{Identifier.IConfigurationSection}} {{Identifier.section}} in {{Identifier.configuration}}.{{Identifier.GetChildren}}()) { if (!{{keysIdentifier}}.Value.Contains({{Expression.sectionKey}})) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/KnownTypeSymbols.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/KnownTypeSymbols.cs index 07dae8689782e4..365f0fa8854cce 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/KnownTypeSymbols.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/KnownTypeSymbols.cs @@ -56,6 +56,12 @@ internal sealed class KnownTypeSymbols public INamedTypeSymbol? ISet_Unbound { get; } public INamedTypeSymbol? ISet { get; } public INamedTypeSymbol? List { get; } + public INamedTypeSymbol? SerializationInfo { get; } + public INamedTypeSymbol? IntPtr { get; } + public INamedTypeSymbol? UIntPtr { get; } + public INamedTypeSymbol? MemberInfo { get; } + public INamedTypeSymbol? ParameterInfo { get; } + public INamedTypeSymbol? Delegate { get; } public KnownTypeSymbols(CSharpCompilation compilation) { @@ -102,7 +108,7 @@ public KnownTypeSymbols(CSharpCompilation compilation) ISet = compilation.GetBestTypeByMetadataName(typeof(ISet<>)); // Used for type equivalency checks for unbound generics. The parameters of the types - // retured by the Roslyn Get*Type* APIs are not unbound, so we construct unbound + // returned by the Roslyn Get*Type* APIs are not unbound, so we construct unbound // generics to equal those corresponding to generic types in the input type graphs. GenericICollection_Unbound = GenericICollection.ConstructUnboundGenericType(); GenericIDictionary_Unbound = GenericIDictionary?.ConstructUnboundGenericType(); @@ -113,6 +119,13 @@ public KnownTypeSymbols(CSharpCompilation compilation) IReadOnlyList_Unbound = compilation.GetBestTypeByMetadataName(typeof(IReadOnlyList<>))?.ConstructUnboundGenericType(); IReadOnlySet_Unbound = compilation.GetBestTypeByMetadataName("System.Collections.Generic.IReadOnlySet`1")?.ConstructUnboundGenericType(); ISet_Unbound = ISet?.ConstructUnboundGenericType(); + + SerializationInfo = compilation.GetBestTypeByMetadataName(typeof(System.Runtime.Serialization.SerializationInfo)); + MemberInfo = compilation.GetBestTypeByMetadataName(typeof(System.Reflection.MemberInfo)); + ParameterInfo = compilation.GetBestTypeByMetadataName(typeof(System.Reflection.ParameterInfo)); + IntPtr = Compilation.GetSpecialType(SpecialType.System_IntPtr); + UIntPtr = Compilation.GetSpecialType(SpecialType.System_UIntPtr); + Delegate = Compilation.GetSpecialType(SpecialType.System_Delegate); } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/UnsupportedTypes.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/UnsupportedTypes.generated.txt new file mode 100644 index 00000000000000..e481503ce4d36b --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/UnsupportedTypes.generated.txt @@ -0,0 +1,258 @@ +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Runtime.CompilerServices +{ + using System; + using System.CodeDom.Compiler; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int column) + { + } + } +} + +namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration +{ + using Microsoft.Extensions.Configuration; + using System; + using System.CodeDom.Compiler; + using System.Collections.Generic; + using System.Globalization; + using System.Runtime.CompilerServices; + + [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] + file static class BindingExtensions + { + #region IConfiguration extensions. + /// Attempts to bind the configuration instance to a new instance of type T. + [InterceptsLocation(@"src-0.cs", 18, 23)] + [InterceptsLocation(@"src-0.cs", 21, 23)] + [InterceptsLocation(@"src-0.cs", 22, 15)] + public static T? Get(this IConfiguration configuration, Action? configureOptions) => (T?)(GetCore(configuration, typeof(T), configureOptions) ?? default(T)); + + /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. + [InterceptsLocation(@"src-0.cs", 17, 23)] + public static void Bind_Options(this IConfiguration configuration, object? instance) + { + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + if (instance is null) + { + return; + } + + var typedObj = (global::Options)instance; + BindCore(configuration, ref typedObj, defaultValueIfNotFound: false, binderOptions: null); + } + #endregion IConfiguration extensions. + + #region Core binding extensions. + private readonly static Lazy> s_configKeys_RecordAction = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "x" }); + private readonly static Lazy> s_configKeys_Options = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "Name", "Age", "List", "Array", "Record" }); + + public static object? GetCore(this IConfiguration configuration, Type type, Action? configureOptions) + { + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + BinderOptions? binderOptions = GetBinderOptions(configureOptions); + + if (!HasValueOrChildren(configuration)) + { + return null; + } + + if (type == typeof(global::Options)) + { + var instance = new global::Options(); + BindCore(configuration, ref instance, defaultValueIfNotFound: true, binderOptions); + return instance; + } + else if (type == typeof(global::System.Collections.Generic.List)) + { + } + else if (type == typeof(global::MyDictionary)) + { + } + + throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); + } + + public static void BindCore(IConfiguration configuration, ref global::System.Collections.Generic.List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) + { + foreach (IConfigurationSection section in configuration.GetChildren()) + { + if (section.Value is string value) + { + instance.Add(value); + } + } + } + + public static void BindCore(IConfiguration configuration, ref string[] instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) + { + var temp1 = new List(); + + foreach (IConfigurationSection section in configuration.GetChildren()) + { + if (section.Value is string value) + { + temp1.Add(value); + } + } + + int originalCount = instance.Length; + Array.Resize(ref instance, originalCount + temp1.Count); + temp1.CopyTo(instance, originalCount); + } + + public static void BindCore(IConfiguration configuration, ref global::Record instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) + { + ValidateConfigurationKeys(typeof(global::Record), s_configKeys_RecordAction, configuration, binderOptions); + } + + public static void BindCore(IConfiguration configuration, ref global::Options instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) + { + ValidateConfigurationKeys(typeof(global::Options), s_configKeys_Options, configuration, binderOptions); + + if (configuration["Name"] is string value2) + { + instance.Name = value2; + } + + if (configuration["Age"] is string value3) + { + instance.Age = ParseInt(value3, () => configuration.GetSection("Age").Path); + } + else if (defaultValueIfNotFound) + { + instance.Age = default; + } + + if (AsConfigWithChildren(configuration.GetSection("List")) is IConfigurationSection section4) + { + global::System.Collections.Generic.List? temp6 = instance.List; + temp6 ??= new global::System.Collections.Generic.List(); + BindCore(section4, ref temp6, defaultValueIfNotFound: false, binderOptions); + instance.List = temp6; + } + + if (AsConfigWithChildren(configuration.GetSection("Array")) is IConfigurationSection section7) + { + string[]? temp9 = instance.Array; + temp9 ??= new string[0]; + BindCore(section7, ref temp9, defaultValueIfNotFound: false, binderOptions); + instance.Array = temp9; + } + + if (AsConfigWithChildren(configuration.GetSection("Record")) is IConfigurationSection section10) + { + global::Record? temp12 = instance.Record; + temp12 ??= InitializeRecordAction(section10, binderOptions); + BindCore(section10, ref temp12, defaultValueIfNotFound: false, binderOptions); + instance.Record = temp12; + } + } + + public static global::Record InitializeRecordAction(IConfiguration configuration, BinderOptions? binderOptions) + { + int x = (int)(10); + if (configuration["x"] is string value13) + { + x = ParseInt(value13, () => configuration.GetSection("x").Path); + } + + return new global::Record(x) + { + x = x, + }; + } + + + /// If required by the binder options, validates that there are no unknown keys in the input configuration object. + public static void ValidateConfigurationKeys(Type type, Lazy> keys, IConfiguration configuration, BinderOptions? binderOptions) + { + if (binderOptions?.ErrorOnUnknownConfiguration is true) + { + List? temp = null; + + foreach (IConfigurationSection section in configuration.GetChildren()) + { + if (!keys.Value.Contains(section.Key)) + { + (temp ??= new List()).Add($"'{section.Key}'"); + } + } + + if (temp is not null) + { + throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); + } + } + } + + public static bool HasValueOrChildren(IConfiguration configuration) + { + if ((configuration as IConfigurationSection)?.Value is not null) + { + return true; + } + return AsConfigWithChildren(configuration) is not null; + } + + public static IConfiguration? AsConfigWithChildren(IConfiguration configuration) + { + foreach (IConfigurationSection _ in configuration.GetChildren()) + { + return configuration; + } + return null; + } + + public static BinderOptions? GetBinderOptions(Action? configureOptions) + { + if (configureOptions is null) + { + return null; + } + + BinderOptions binderOptions = new(); + configureOptions(binderOptions); + + if (binderOptions.BindNonPublicProperties) + { + throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); + } + + return binderOptions; + } + + public static int ParseInt(string value, Func getPath) + { + try + { + return int.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture); + } + catch (Exception exception) + { + throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); + } + } + #endregion Core binding extensions. + } +} diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigBindingGenTestDriver.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigBindingGenTestDriver.cs index 4373b404fc67f0..88dfca789b420e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigBindingGenTestDriver.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigBindingGenTestDriver.cs @@ -38,9 +38,9 @@ public ConfigBindingGenTestDriver( _assemblyReferences = assemblyReferences ?? s_compilationAssemblyRefs; - _parseOptions = new CSharpParseOptions(langVersion).WithFeatures(new[] { - new KeyValuePair("InterceptorsPreview", "") , - new KeyValuePair("InterceptorsPreviewNamespaces", "Microsoft.Extensions.Configuration.Binder.SourceGeneration") + _parseOptions = new CSharpParseOptions(langVersion).WithFeatures(new[] { + new KeyValuePair("InterceptorsPreview", "") , + new KeyValuePair("InterceptorsPreviewNamespaces", "Microsoft.Extensions.Configuration.Binder.SourceGeneration") }); ConfigurationBindingGenerator generator = new() { OnSourceEmitting = spec => _genSpec = spec }; @@ -139,7 +139,7 @@ public static void ValidateDiagnostics(this ConfigBindingGenRunResult result, Ex { Assert.True( IsPermitted(diagnostic), - $"Generator caused dagnostic in output compilation: {diagnostic.GetMessage(CultureInfo.InvariantCulture)}."); + $"Generator caused diagnostic in output compilation: {diagnostic.GetMessage(CultureInfo.InvariantCulture)}."); } } else diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs index 8dd225ba4227b3..67741c87f7b000 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Baselines.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Immutable; using System.Linq; +using System.Text; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Xunit; @@ -742,7 +743,7 @@ public class MyClass await VerifyAgainstBaselineUsingFile("Primitives.generated.txt", source); } - + [Fact] public async Task DefaultConstructorParameters() { @@ -872,7 +873,7 @@ public async Task MinimalGenerationIfNoBindableMembers() string source = """ using System.Collections.Generic; using Microsoft.Extensions.Configuration; - + public class Program { public static void Main() @@ -912,5 +913,160 @@ public abstract class AbstractType_CannotInit Assert.Equal(2, result.Diagnostics.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); } + + private readonly static string [] s_typesToSkip = new string [] + { + "Action", + "List>", + "List>>", + "Func", + "List>", + "List>>", + "myMethodDelegate", + "List", + "List>", + "IntPtr", + "List", + "List>", + "UIntPtr", + "List", + "List>", + "SerializationInfo", + "List", + "List>", + "MethodInfo", + "List", + "List>", + "ConstructorInfo", + "List", + "List>", + "string[,]", + "List", + "List>", + "Func[]", + "Action[]", + "myMethodDelegate[]", + "MethodInfo[]", + "ConstructorInfo[]", + "SerializationInfo[]", + "IntPtr[]", + "UIntPtr[]", + "Action?", + "List?>", + "List?>>", + "Func?", + "List?>", + "List?>>", + "myMethodDelegate?", + "List", + "List>", + "IntPtr?", + "List", + "List>", + "UIntPtr?", + "List", + "List>", + "SerializationInfo?", + "List", + "List>", + "MethodInfo?", + "List", + "List>", + "ConstructorInfo?", + "List", + "List>", + "string[,]?", + "List", + "List>", + "Func?[]", + "Action?[]", + "myMethodDelegate?[]", + "MethodInfo?[]", + "ConstructorInfo?[]", + "SerializationInfo?[]", + "IntPtr?[]", + "UIntPtr?[]", + "ParameterInfo", + "ParameterInfo?", + "List", + "List", + "ParameterInfo[]", + "MyDictionary" + }; + + private readonly static string [] s_rootCollectionTypesToGenerateDiagnostics = new string [] + { + "List", + "MyDictionary", + }; + + [Fact] + public async Task UnsupportedTypes() + { + StringBuilder sb1 = new(); + for (int i = 0; i < s_typesToSkip.Length; i++) + { + sb1.AppendLine($"public {s_typesToSkip[i]} SkipProp{i} {{ get; set; }}"); + } + + StringBuilder sb2 = new(); + for (int i = 0; i < s_rootCollectionTypesToGenerateDiagnostics.Length; i++) + { + sb2.AppendLine($"configuration.Get<{s_rootCollectionTypesToGenerateDiagnostics[i]}>(_ => {{ }});"); + } + + string source = $$""" + using System; + using System.Collections.Generic; + using System.Reflection; + using System.Runtime.Serialization; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfiguration configuration = configurationBuilder.Build(); + + // var ws = config.GetSection("MySection"); + var w = new Options(); + configuration.Bind(w); + configuration.Get(_ => { }); + + // Should generate a diagnostics + {{sb2}} + } + } + + public class Options + { + public string? Name { get; set; } + public int Age { get; set; } + public List List { get; set; } + public string[] Array { get; set; } + public Record Record { get; set; } + {{sb1}} + public delegate string myMethodDelegate( int myInt ); + } + + public class MyDictionary : Dictionary { } + + public record Record(int x = 10); + + namespace System.Runtime.CompilerServices { internal static class IsExternalInit { } } + """; + + ConfigBindingGenRunResult result = await VerifyAgainstBaselineUsingFile( + "UnsupportedTypes.generated.txt", + source, expectedDiags: ExpectedDiagnostics.FromGeneratorOnly); + + Assert.Equal(s_rootCollectionTypesToGenerateDiagnostics.Length, result.Diagnostics.Where(diag => diag.Id == Diagnostics.TypeNotSupported.Id).Count()); + Assert.True(result.GeneratedSource.HasValue); + string generatedSource = result.GeneratedSource.Value.SourceText.ToString(); + Assert.DoesNotContain(generatedSource, "SkipProp"); + Assert.Contains("global::Record", generatedSource); + } } } From d0804a9176fd0670db3aa61765f337d1df8d7c48 Mon Sep 17 00:00:00 2001 From: Natalia Kondratyeva Date: Sat, 11 Nov 2023 20:36:50 +0000 Subject: [PATCH 464/783] [release/8.0-staging] Update alpine arm32 in release 8.0 CI (#94609) * Update Alpine Arm32 image * TO REVERT: test specifically linux_musl_arm platform * Pin the image to previous tag * Revert "TO REVERT: test specifically linux_musl_arm platform" This reverts commit 63b83026f62259dcc8cde810d94f041a5ab5c918. --- eng/pipelines/coreclr/templates/helix-queues-setup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml index e264588ee78c91..240c010b8c9da5 100644 --- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml +++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml @@ -86,9 +86,9 @@ jobs: # Linux musl arm32 - ${{ if eq(parameters.platform, 'linux_musl_arm') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - (Alpine.315.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7 + - (Alpine.315.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7-20230807201723-7ea784e - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - (Alpine.315.Arm32)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7 + - (Alpine.315.Arm32)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7-20230807201723-7ea784e # Linux musl arm64 - ${{ if eq(parameters.platform, 'linux_musl_arm64') }}: From 0087f0b50667ecb3a8fd7b820621797b08e642db Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 09:35:50 -0500 Subject: [PATCH 465/783] [release/8.0-staging] [mono] catch the case of updated methods in mono_debug_lookup_source_location (#94612) Backport of #94540 to release/8.0-staging If a newly added method is in a stack trace, look it up in the EnC debug information, if available. Related to #93860 * Add new crashing test * [mono] catch the case of updated methods in mono_debug_lookup_source_location Co-authored-by: Aleksey Kliger Co-authored-by: Thays Grazia --- .../NewMethodThrows.cs | 16 +++++ .../NewMethodThrows_v1.cs | 21 +++++++ ...ta.ApplyUpdate.Test.NewMethodThrows.csproj | 11 ++++ .../deltascript.json | 6 ++ .../tests/ApplyUpdateTest.cs | 47 +++++++++++++- .../tests/System.Runtime.Loader.Tests.csproj | 1 + src/mono/mono/metadata/mono-debug.c | 22 +++++++ .../DebuggerTestSuite/HotReloadTests.cs | 62 +++++++++++++++++++ .../MethodBody1.cs | 19 ++++++ .../MethodBody1_v1.cs | 14 +++++ .../MethodBody1_v2.cs | 14 +++++ 11 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/NewMethodThrows.cs create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/NewMethodThrows_v1.cs create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows.csproj create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/deltascript.json diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/NewMethodThrows.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/NewMethodThrows.cs new file mode 100644 index 00000000000000..baef24d1ab19ec --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/NewMethodThrows.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; + + +namespace System.Reflection.Metadata.ApplyUpdate.Test +{ + public class NewMethodThrows + { + public string ExistingMethod(string x) + { + return x; + } + + } +} diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/NewMethodThrows_v1.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/NewMethodThrows_v1.cs new file mode 100644 index 00000000000000..be7ee1389ce1de --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/NewMethodThrows_v1.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; + + +namespace System.Reflection.Metadata.ApplyUpdate.Test +{ + public class NewMethodThrows + { + public string ExistingMethod(string x) + { + return NewMethod(x); + } + + public string NewMethod(string x) + { + throw new InvalidOperationException (x); + } + + } +} diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows.csproj b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows.csproj new file mode 100644 index 00000000000000..2948ee7979c527 --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows.csproj @@ -0,0 +1,11 @@ + + + System.Runtime.Loader.Tests + $(NetCoreAppCurrent) + true + deltascript.json + + + + + diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/deltascript.json b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/deltascript.json new file mode 100644 index 00000000000000..fbc53a9a091f95 --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows/deltascript.json @@ -0,0 +1,6 @@ +{ + "changes": [ + {"document": "NewMethodThrows.cs", "update": "NewMethodThrows_v1.cs"}, + ] +} + diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs index 8ca126834cfcdb..2fdb62c7e4bfb4 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs @@ -938,5 +938,50 @@ public static void TestGenericAddInstanceField() Assert.Equal(dt, z.GetIt()); }); } - } + + [ConditionalFact(typeof(ApplyUpdateUtil), nameof(ApplyUpdateUtil.IsSupported))] + public static void TestNewMethodThrows() + { + ApplyUpdateUtil.TestCase(static () => + { + var assm = typeof(System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows).Assembly; + + var x = new System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows(); + + Assert.Equal("abcd", x.ExistingMethod("abcd")); + + ApplyUpdateUtil.ApplyUpdate(assm); + + InvalidOperationException exn = Assert.Throws(() => x.ExistingMethod("spqr")); + + Assert.Equal("spqr", exn.Message); + + var stackTrace = new System.Diagnostics.StackTrace(exn, fNeedFileInfo: true); + + var frames = stackTrace.GetFrames(); + + // the throwing method and its caller and a few frames of XUnit machinery for Assert.Throws, above + Assert.True(frames.Length >= 2); + + var throwingMethod = frames[0].GetMethod(); + + var newMethod = typeof (System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows).GetMethod("NewMethod"); + + Assert.Equal(newMethod, throwingMethod); + + // We don't have the filename on all runtimes and platforms + var frame0Name = frames[0].GetFileName(); + Assert.True(frame0Name == null || frame0Name.Contains("NewMethodThrows.cs")); + + var existingMethod = typeof (System.Reflection.Metadata.ApplyUpdate.Test.NewMethodThrows).GetMethod("ExistingMethod"); + + var throwingMethodCaller = frames[1].GetMethod(); + + Assert.Equal(existingMethod, throwingMethodCaller); + + var frame1Name = frames[0].GetFileName(); + Assert.True(frame1Name == null || frame1Name.Contains("NewMethodThrows.cs")); + }); + } + } } diff --git a/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj index 293105e20d4345..3cd6969d01d745 100644 --- a/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj +++ b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj @@ -66,6 +66,7 @@ + diff --git a/src/mono/mono/metadata/mono-debug.c b/src/mono/mono/metadata/mono-debug.c index 2472c62e62d33b..e49089b3e4652c 100644 --- a/src/mono/mono/metadata/mono-debug.c +++ b/src/mono/mono/metadata/mono-debug.c @@ -777,6 +777,28 @@ mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDoma if (mono_debug_format == MONO_DEBUG_FORMAT_NONE) return NULL; + MonoImage *img = m_class_get_image (method->klass); + if (G_UNLIKELY (img->has_updates)) { + guint32 idx = mono_metadata_token_index (method->token); + MonoDebugInformationEnc *mdie = (MonoDebugInformationEnc *) mono_metadata_update_get_updated_method_ppdb (img, idx); + if (mdie != NULL) { + offset = il_offset_from_address (method, address); + if (offset < 0) { + mono_debugger_unlock (); + return NULL; + } + + MonoDebugSourceLocation * ret = mono_ppdb_lookup_location_enc (mdie->ppdb_file, mdie->idx, offset); + if (ret) + return ret; + } else { + /// added method without EnC info, maybe the delta came in without a PDB delta + gboolean added_method = idx >= table_info_get_rows (&img->tables[MONO_TABLE_METHOD]); + if (added_method) + return NULL; + } + } + mono_debugger_lock (); minfo = lookup_method (method); if (!minfo || !minfo->handle) { diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/HotReloadTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/HotReloadTests.cs index ade5c6adc8bbd5..5383b9d9a61733 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/HotReloadTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/HotReloadTests.cs @@ -627,6 +627,68 @@ public async Task DebugHotReloadMethod_AddingNewClassUsingDebugAttribute() await StepAndCheck(StepKind.Into, $"dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 119, 12, "ApplyUpdateReferencedAssembly.MethodBody10.StaticMethod1"); } + [ConditionalFact(nameof(RunningOnChrome))] + public async Task DebugHotReloadMethod_AddingNewMethodAndThrowException() + { + //await SetPauseOnException("all"); + string asm_file = Path.Combine(DebuggerTestAppPath, "ApplyUpdateReferencedAssembly.dll"); + string pdb_file = Path.Combine(DebuggerTestAppPath, "ApplyUpdateReferencedAssembly.pdb"); + string asm_file_hot_reload = Path.Combine(DebuggerTestAppPath, "../wasm/ApplyUpdateReferencedAssembly.dll"); + + var bp_notchanged = await SetBreakpoint(".*/MethodBody1.cs$", 129, 12, use_regex: true); + var bp_invalid = await SetBreakpoint(".*/MethodBody1.cs$", 133, 12, use_regex: true); + + var pause_location = await LoadAssemblyAndTestHotReloadUsingSDBWithoutChanges( + asm_file, pdb_file, "MethodBody11", "StaticMethod1", expectBpResolvedEvent: true, sourcesToWait: new string [] { "MethodBody0.cs", "MethodBody1.cs" }); + + CheckLocation("dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 129, 12, scripts, pause_location["callFrames"]?[0]["location"]); + //apply first update + pause_location = await LoadAssemblyAndTestHotReloadUsingSDB( + asm_file_hot_reload, "MethodBody11", "NewMethodStaticWithThrow", 1); + + JToken top_frame = pause_location["callFrames"]?[0]; + AssertEqual("ApplyUpdateReferencedAssembly.MethodBody11.NewMethodStaticWithThrow", top_frame?["functionName"]?.Value(), top_frame?.ToString()); + CheckLocation("dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 133, 12, scripts, top_frame["location"]); + await StepAndCheck(StepKind.Over, "dotnet://ApplyUpdateReferencedAssembly.dll/MethodBody1.cs", 134, 12, "ApplyUpdateReferencedAssembly.MethodBody11.NewMethodStaticWithThrow", + locals_fn: async (locals) => + { + CheckNumber(locals, "i", 20); + await Task.CompletedTask; + } + ); + + await SetPauseOnException("all"); + + pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", null, 0, 0, null); + + await CheckValue(pause_location["data"], JObject.FromObject(new + { + type = "object", + subtype = "error", + className = "System.Exception", + uncaught = false + }), "exception0.data"); + + pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", null, 0, 0, null); + try + { + pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", null, 0, 0, null); + } + catch (System.Exception ae) + { + System.Console.WriteLine(ae); + var eo = JObject.Parse(ae.Message); + + AssertEqual("Uncaught", eo["exceptionDetails"]?["text"]?.Value(), "text"); + + await CheckValue(eo["exceptionDetails"]?["exception"], JObject.FromObject(new + { + type = "object", + subtype = "error", + className = "Error" + }), "exception"); + } + } // Enable this test when https://github.com/dotnet/hotreload-utils/pull/264 flows into dotnet/runtime repo // [ConditionalFact(nameof(RunningOnChrome))] // public async Task DebugHotReloadMethod_ChangeParameterName() diff --git a/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/MethodBody1.cs b/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/MethodBody1.cs index 2c510d1415d515..bb23eb2b9d2b5a 100644 --- a/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/MethodBody1.cs +++ b/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/MethodBody1.cs @@ -112,4 +112,23 @@ public static void StaticMethod1 () { // return M1(1, 2); // } // } + + + + + + + + + + + + + + public class MethodBody11 { + public static void StaticMethod1 () { + Console.WriteLine("breakpoint in a line that will not be changed"); + Console.WriteLine("original"); + } + } } diff --git a/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/MethodBody1_v1.cs b/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/MethodBody1_v1.cs index b813b506d86925..7b6c0403de45f5 100644 --- a/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/MethodBody1_v1.cs +++ b/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/MethodBody1_v1.cs @@ -124,4 +124,18 @@ public static void StaticMethod2 () { Console.WriteLine($"do not step into here"); } } + + public class MethodBody11 { + public static void StaticMethod1 () { + Console.WriteLine("breakpoint in a line that will not be changed"); + Console.WriteLine("original"); + } + public static void NewMethodStaticWithThrow () { + int i = 20; + Console.WriteLine($"add a breakpoint in the new static method, look at locals {i}"); + throw new Exception("my exception"); + /*var newvar = new MethodBody6(); + newvar.NewMethodInstance (10);*/ + } + } } diff --git a/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/MethodBody1_v2.cs b/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/MethodBody1_v2.cs index 3ea27466fa549a..dda7496ccc91e4 100644 --- a/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/MethodBody1_v2.cs +++ b/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/MethodBody1_v2.cs @@ -124,4 +124,18 @@ public static void StaticMethod2 () { Console.WriteLine($"do not step into here"); } } + + public class MethodBody11 { + public static void StaticMethod1 () { + Console.WriteLine("breakpoint in a line that will not be changed"); + Console.WriteLine("original"); + } + public static void NewMethodStaticWithThrow () { + int i = 20; + Console.WriteLine($"add a breakpoint in the new static method, look at locals {i}"); + throw new Exception("my exception"); + /*var newvar = new MethodBody6(); + newvar.NewMethodInstance (10);*/ + } + } } From 84427da983a18eddeabb95b76a2329449754cb43 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 15:42:48 -0800 Subject: [PATCH 466/783] Update dependencies from https://github.com/dotnet/emsdk build 20231113.2 (#94677) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.1-servicing.23559.1 -> To Version 8.0.1-servicing.23563.2 Dependency coherency updates runtime.linux-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.win-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.win-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.osx-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.osx-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.win-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.win-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.osx-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.osx-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.osx-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.osx-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.osx-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.osx-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools From Version 16.0.5-alpha.1.23478.1 -> To Version 16.0.5-alpha.1.23558.12 (parent: Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 126 ++++++++++++++++++++-------------------- eng/Versions.props | 60 +++++++++---------- 3 files changed, 94 insertions(+), 94 deletions(-) diff --git a/NuGet.config b/NuGet.config index 1ca1556e66b4a1..2daf70bbead041 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + 8.0.0-rc.1.23406.6 8.0.0-preview.7.23325.2 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 6.0.0 1.1.1 @@ -222,20 +222,20 @@ 2.2.3 8.0.0-alpha.1.23468.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 3.1.7 1.0.406601 From 18c80f54ef4e3e4c24699ce8907ac3f5dc62e27c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 15:43:19 -0800 Subject: [PATCH 467/783] Update dependencies from https://github.com/dotnet/hotreload-utils build 20231113.1 (#94669) Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23556.2 -> To Version 8.0.0-alpha.0.23563.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 73dc7cb7dca282..2934b6e8c984bc 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -354,9 +354,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization e5d9d61ccb43b9135a7471429b338aa7332e2eb5 - + https://github.com/dotnet/hotreload-utils - 86c49390a5b9ab8673f976dcdd4a60b073bab083 + 12d02e5c2310be6460f896bc3aeb0ddf1e8926bc https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index 8de8af90b6b19f..120b28e4439936 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -186,7 +186,7 @@ 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 - 8.0.0-alpha.0.23556.2 + 8.0.0-alpha.0.23563.1 2.4.2 1.0.0 2.4.5 From 481168028c4f87f2de8d725dd826b7b752470cf7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 15:44:10 -0800 Subject: [PATCH 468/783] Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20231106.3 (#94665) Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23516.4 -> To Version 8.0.0-alpha.1.23556.3 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2934b6e8c984bc..ae82d0c522e433 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -99,9 +99,9 @@ 0af50f733332e8c148f7f2debef2cb90504840d5 - + https://github.com/dotnet/source-build-reference-packages - b4fa7f2e1e65ef49881be2ab2df27624280a8c55 + fa4c0e8f53ef2541a23e519af4dfb86cb88e1bae From 82089e50b9529e76551b1d1bad110001809aaf0f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 20:57:52 -0800 Subject: [PATCH 469/783] [release/8.0] Update dependencies from dnceng/internal/dotnet-optimization (#94605) * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231109.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23525.5 -> To Version 1.0.0-prerelease.23559.3 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231109.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23525.5 -> To Version 1.0.0-prerelease.23559.3 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231111.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23525.5 -> To Version 1.0.0-prerelease.23561.3 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231111.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23525.5 -> To Version 1.0.0-prerelease.23561.3 --------- Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 4 ---- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/NuGet.config b/NuGet.config index 4a661d10176116..0c7e2962cba265 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,10 +9,6 @@ - - - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e0dafd57c184e1..2352181aa0037f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -338,21 +338,21 @@ https://github.com/dotnet/arcade 080141bf0f9f15408bb6eb8e301b23bddf81d054 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - d80a861521d84459c9290c31127b2a0ce511f279 + c68e08c656a1e9b058fe22cc0546dbbd245c85fb - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - d80a861521d84459c9290c31127b2a0ce511f279 + c68e08c656a1e9b058fe22cc0546dbbd245c85fb - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - d80a861521d84459c9290c31127b2a0ce511f279 + c68e08c656a1e9b058fe22cc0546dbbd245c85fb - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - d80a861521d84459c9290c31127b2a0ce511f279 + c68e08c656a1e9b058fe22cc0546dbbd245c85fb https://github.com/dotnet/hotreload-utils @@ -388,13 +388,13 @@ 7e33fd449381b337c290a801057fdcd68c4b7220 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - d80a861521d84459c9290c31127b2a0ce511f279 + c68e08c656a1e9b058fe22cc0546dbbd245c85fb - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - d80a861521d84459c9290c31127b2a0ce511f279 + c68e08c656a1e9b058fe22cc0546dbbd245c85fb diff --git a/eng/Versions.props b/eng/Versions.props index 6cdad19d086c47..39cd16e0073b2e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23558.5 8.0.0-beta.23558.5 - 1.0.0-prerelease.23525.5 - 1.0.0-prerelease.23525.5 - 1.0.0-prerelease.23525.5 - 1.0.0-prerelease.23525.5 - 1.0.0-prerelease.23525.5 - 1.0.0-prerelease.23525.5 + 1.0.0-prerelease.23561.3 + 1.0.0-prerelease.23561.3 + 1.0.0-prerelease.23561.3 + 1.0.0-prerelease.23561.3 + 1.0.0-prerelease.23561.3 + 1.0.0-prerelease.23561.3 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From dc944d57c4f403c8dc80cfad57f07c32038355c8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 Nov 2023 08:48:30 -0500 Subject: [PATCH 470/783] [release/8.0-staging] [mono] Fix deadlock in static constructor initialization (#93943) Backport of #93875 to release/8.0-staging * [mono] Fix deadlock in static constructor initialization If two threads (A and B) need to call the static constructors for 3 classes X, Y, Z in this order: Thread A: X, Z, Y Thread B: Y, Z, X where the cctor for X in thread A invokes the cctor for Z and for Y, and the cctor for Y in thread B invokes the cctor for Z and X, then we can get into a situation where A and B both start the cctors for X and Y (so they will be in the type_initialization_hash for those two classes) and then both will try to init Z. In that case it could be that A will be responsible for initializing Z and B will block. Then A could finish initializing Z but B may not have woken up yet (and so it will be in blocked_thread_hash waiting for Z). At that point A (who is at this point already need to init Y) may think that it can wait for B to finish initializing Y. That is we get to `mono_coop_cond_timedwait (&lock->cond, &lock->mutex, timeout_ms)` with "lock" being the lock for `Y`. But in fact thread B will not be able to complete initializing Y because it will attempt to init X next - but meanwhile we did not indicate that thread A is blocked. As a result in thread A the timed wait will eventually timeout. And in this case we need to go back to the top and now correctly detect that A is waiting for Y and B is waiting for X. (At that point there is a cctor deadlock and ECMA rules allow one of the threads to return without calling the cctor) The old code here used to do an infinite wait: while (!lock->done) mono_coop_cond_wait (&lock->cond, &lock->mutex) This cannot succeed because "lock" (in thread A it's the lock for Y) will not be signaled since B (who is supposed to init Y) will instead block on the cctor for X. Fixes https://github.com/dotnet/runtime/issues/93778 * Add test case * remove prototyping log messages * disable mt test on wasm * better issues.target exclusion * code review feedback Co-authored-by: Aleksey Kliger --- src/mono/mono/metadata/object.c | 51 ++++- .../CircularCctorTwoThreadsThreeCC.cs | 182 ++++++++++++++++++ .../CircularCctorTwoThreadsThreeCC.csproj | 9 + src/tests/issues.targets | 3 + 4 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 src/tests/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorTwoThreadsThreeCC.cs create mode 100644 src/tests/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorTwoThreadsThreeCC.csproj diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index a0e271130ffe7d..5d23bb87273ea6 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -458,6 +458,7 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error) * on this cond var. */ +retry_top: mono_type_initialization_lock (); /* double check... */ if (vtable->initialized) { @@ -507,6 +508,12 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error) blocked = GUINT_TO_POINTER (MONO_NATIVE_THREAD_ID_TO_UINT (lock->initializing_tid)); while ((pending_lock = (TypeInitializationLock*) g_hash_table_lookup (blocked_thread_hash, blocked))) { if (mono_native_thread_id_equals (pending_lock->initializing_tid, tid)) { + if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_TYPE)) { + char* type_name = mono_type_full_name (m_class_get_byval_arg (klass)); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_TYPE, "Detected deadlock for class .cctor for %s from '%s'", type_name, m_class_get_image (klass)->name); + g_free (type_name); + } + if (!pending_lock->done) { mono_type_initialization_unlock (); goto return_true; @@ -605,9 +612,49 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error) } else { /* this just blocks until the initializing thread is done */ mono_type_init_lock (lock); - while (!lock->done) - mono_coop_cond_wait (&lock->cond, &lock->mutex); + if (!lock->done) { + int timeout_ms = 500; + int wait_result = mono_coop_cond_timedwait (&lock->cond, &lock->mutex, timeout_ms); + if (wait_result == -1) { + /* timed out - go around again from the beginning. If we got here + * from the "is_blocked = FALSE" case, above (another thread was + * blocked on the current thread, but on a lock that was already + * done but it didn't get to wake up yet), then it might still be + * the case that the current thread cannot proceed even if the other + * thread got to wake up - there might be a new deadlock. We need + * to re-evaluate. + * + * This can happen if two threads A and B need to call the cctors + * for classes X and Y but in opposite orders, and also call a cctor + * for a third class Z. (That is thread A wants to init: X, Z, Y; + * thread B wants to init: Y, Z, X.) In that case, if B is waiting + * for A to finish initializing Z, and A (the current thread ) + * already finished Z and wants to init Y. In A, control will come + * here with "lock" being Y's lock. But we will time out because B + * will see that A is responsible for initializing X and will also + * block. So A is waiting for B to finish Y and B is waiting for A + * to finish X. So the fact that A allowed B to wait for Z to + * finish didn't actually let us make progress. Thread A must go + * around to the top once more and try to init Y - and detect that + * there is now a deadlock between X and Y. + */ + mono_type_init_unlock (lock); + // clean up blocked thread hash and lock refcount. + mono_type_initialization_lock (); + g_hash_table_remove (blocked_thread_hash, GUINT_TO_POINTER (tid)); + gboolean deleted = unref_type_lock (lock); + if (deleted) + g_hash_table_remove (type_initialization_hash, vtable); + mono_type_initialization_unlock (); + goto retry_top; + } else if (wait_result == 0) { + /* Success: we were signaled that the other thread is done. Proceed */ + } else { + g_assert_not_reached (); + } + } mono_type_init_unlock (lock); + g_assert (lock->done); } /* Do cleanup and setting vtable->initialized inside the global lock again */ diff --git a/src/tests/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorTwoThreadsThreeCC.cs b/src/tests/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorTwoThreadsThreeCC.cs new file mode 100644 index 00000000000000..cd5b45ca95527f --- /dev/null +++ b/src/tests/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorTwoThreadsThreeCC.cs @@ -0,0 +1,182 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Threading; + +using Xunit; + +// Regression test for https://github.com/dotnet/runtime/issues/93778 +namespace CircularCctorTwoThreadsThreeCC; + +[Flags] +public enum SlotConstants : int +{ + ZInited = 1, + YInitedFromX = 2, + XInitedFromY = 4, + + Thread1 = 1 << 16, + Thread2 = 2 << 16, +} + +/// X and Y both try to use each other, and also both use Z. +/// We expect to see exactly one thread initialize Z and +/// either X inited from Y or Y inited from X. +public class X +{ + public static X Singleton = new(); + private X() { + Z.Singleton.Ping(); + Y.Singleton?.Pong(); + } + + public void Pong() => Coordinator.Note(SlotConstants.XInitedFromY); +} + +public class Y +{ + public static Y Singleton = new(); + private Y() { + Z.Singleton.Ping(); + X.Singleton?.Pong(); + } + + public void Pong() => Coordinator.Note(SlotConstants.YInitedFromX); +} + +public class Z +{ + public static Z Singleton = new(); + + private Z() { + Coordinator.Note(SlotConstants.ZInited); + } + + public void Ping() { } + +} + +public class Coordinator +{ + [ThreadStatic] + private static SlotConstants t_threadTag; + + private static int s_NextNote; + private static readonly SlotConstants[] Notes = new SlotConstants[12]; + + private static SlotConstants DecorateWithThread(SlotConstants c) + { + return c | t_threadTag; + } + + public static void Note(SlotConstants s) { + int idx = Interlocked.Increment(ref s_NextNote); + idx--; + Notes[idx] = DecorateWithThread (s); + } + + public static Coordinator CreateThread(bool xThenY, SlotConstants threadTag) + { + return new Coordinator(xThenY, threadTag); + } + + public readonly Thread Thread; + private static readonly Barrier s_barrier = new (3); + + private Coordinator(bool xThenY, SlotConstants threadTag) + { + var t = new Thread(() => { + t_threadTag = threadTag; + // Log("started"); + NextPhase(); + // Log("racing"); + DoConstructions(xThenY); + NextPhase(); + // Log("done"); + }); + Thread = t; + t.Start(); + } + + public static void NextPhase() { s_barrier.SignalAndWait(); } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void DoConstructions(bool xThenY) + { + if (xThenY) { + XCreate(); + } else { + YCreate(); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void XCreate() + { + var _ = X.Singleton; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void YCreate() + { + var _ = Y.Singleton; + } + + public static void Log(string msg) + { + Console.WriteLine ($"{Thread.CurrentThread.ManagedThreadId}: {msg}"); + } + + [Fact] + public static void RunTestCase() + { + var c1 = CreateThread(xThenY: true, threadTag: SlotConstants.Thread1); + var c2 = CreateThread(xThenY: false, threadTag: SlotConstants.Thread2); + // created all threads + NextPhase(); + // racing + NextPhase(); + // done + + // one second should be plenty for all these threads, but it's arbitrary + int threadJoinTimeoutMS = 1000; + var j1 = c1.Thread.Join(threadJoinTimeoutMS); + var j2 = c2.Thread.Join(threadJoinTimeoutMS); + Assert.True(j1); + Assert.True(j2); + // all joined + + // exactly one thread inited Z + Assert.Equal(1, CountNotes(SlotConstants.ZInited)); + // either X was inited or Y, not both. + Assert.Equal(1, Count2Notes(SlotConstants.XInitedFromY, SlotConstants.YInitedFromX)); + } + + private static int CountNotes(SlotConstants mask) + { + int found = 0; + foreach (var note in Notes) { + if ((note & mask) != (SlotConstants)0) { + found++; + } + } + return found; + } + + private static int Count2Notes(SlotConstants mask1, SlotConstants mask2) + { + int found = 0; + foreach (var note in Notes) { + if ((note & mask1) != (SlotConstants)0) { + found++; + } + if ((note & mask2) != (SlotConstants)0) { + found++; + } + } + return found; + } + +} diff --git a/src/tests/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorTwoThreadsThreeCC.csproj b/src/tests/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorTwoThreadsThreeCC.csproj new file mode 100644 index 00000000000000..c9936332a86764 --- /dev/null +++ b/src/tests/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorTwoThreadsThreeCC.csproj @@ -0,0 +1,9 @@ + + + true + 0 + + + + + diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 5c9868e334b088..537655fa553ce1 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -3259,6 +3259,9 @@ System.Threading.Thread.UnsafeStart not supported + + System.Threading.Thread.ThrowIfNoThreadStart: PlatformNotSupportedException + Could not load legacy Microsoft.Diagnostics.Tools.RuntimeClient From 4c6ce468b5c26ea4ec37a3ea794604c3c9bd8a3a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:47:25 -0600 Subject: [PATCH 471/783] [release/8.0-staging] Handle null signature destinations for ECDsa / DSA / RSA (#93996) * Handle null signature destinations. When RSA/ECDSA/DSA use a "null" span as a destination for a signature, a nullptr was handed to CNG. CNG would interpret this as asking for the signature length. It would set the output length and return success without actually computing the signature. This changes the p/invokes to prevent null values for the signature destination. * Fix DSA test on macOS to not generate a DSA key --------- Co-authored-by: Kevin Jones --- .../Windows/BCrypt/Interop.BCryptSignHash.cs | 5 +- .../Windows/NCrypt/Interop.SignVerify.cs | 12 ++++- .../DSA/DSASignVerify.cs | 19 +++++++ .../ECDsa/ECDsaTests.cs | 26 +++++++++ .../RSA/SignVerify.cs | 54 +++++++++++++++++++ .../Cryptography/CngCommon.SignVerify.cs | 12 ++--- 6 files changed, 119 insertions(+), 9 deletions(-) diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs index 4bacf465c5a1dc..c7daa15baaa945 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs @@ -3,6 +3,7 @@ using System; using System.Runtime.InteropServices; +using Internal.Cryptography; using Microsoft.Win32.SafeHandles; @@ -30,7 +31,7 @@ internal static unsafe NTSTATUS BCryptSignHashPkcs1( { fixed (char* pHashAlgorithmName = hashAlgorithmName) fixed (byte* pHash = &MemoryMarshal.GetReference(hash)) - fixed (byte* pDest = &MemoryMarshal.GetReference(destination)) + fixed (byte* pDest = &Helpers.GetNonNullPinnableReference(destination)) { BCRYPT_PKCS1_PADDING_INFO paddingInfo = default; paddingInfo.pszAlgId = (IntPtr)pHashAlgorithmName; @@ -56,7 +57,7 @@ internal static unsafe NTSTATUS BCryptSignHashPss( { fixed (char* pHashAlgorithmName = hashAlgorithmName) fixed (byte* pHash = &MemoryMarshal.GetReference(hash)) - fixed (byte* pDest = &MemoryMarshal.GetReference(destination)) + fixed (byte* pDest = &Helpers.GetNonNullPinnableReference(destination)) { BCRYPT_PSS_PADDING_INFO paddingInfo = default; paddingInfo.pszAlgId = (IntPtr)pHashAlgorithmName; diff --git a/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.SignVerify.cs b/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.SignVerify.cs index 08356b15d3211a..a55c158cfdea1d 100644 --- a/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.SignVerify.cs +++ b/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.SignVerify.cs @@ -3,6 +3,7 @@ using System; using System.Runtime.InteropServices; +using Internal.Cryptography; using Microsoft.Win32.SafeHandles; internal static partial class Interop @@ -10,7 +11,16 @@ internal static partial class Interop internal static partial class NCrypt { [LibraryImport(Libraries.NCrypt, StringMarshalling = StringMarshalling.Utf16)] - internal static unsafe partial ErrorCode NCryptSignHash(SafeNCryptKeyHandle hKey, void* pPaddingInfo, ReadOnlySpan pbHashValue, int cbHashValue, Span pbSignature, int cbSignature, out int pcbResult, AsymmetricPaddingMode dwFlags); + private static unsafe partial ErrorCode NCryptSignHash(SafeNCryptKeyHandle hKey, void* pPaddingInfo, byte* pbHashValue, int cbHashValue, byte* pbSignature, int cbSignature, out int pcbResult, AsymmetricPaddingMode dwFlags); + + internal static unsafe ErrorCode NCryptSignHash(SafeNCryptKeyHandle hKey, void* pPaddingInfo, ReadOnlySpan pbHashValue, Span pbSignature, out int pcbResult, AsymmetricPaddingMode dwFlags) + { + fixed (byte* pHash = &MemoryMarshal.GetReference(pbHashValue)) + fixed (byte* pSignature = &Helpers.GetNonNullPinnableReference(pbSignature)) + { + return NCryptSignHash(hKey, pPaddingInfo, pHash, pbHashValue.Length, pSignature, pbSignature.Length, out pcbResult, dwFlags); + } + } [LibraryImport(Libraries.NCrypt, StringMarshalling = StringMarshalling.Utf16)] internal static unsafe partial ErrorCode NCryptVerifySignature(SafeNCryptKeyHandle hKey, void* pPaddingInfo, ReadOnlySpan pbHashValue, int cbHashValue, ReadOnlySpan pbSignature, int cbSignature, AsymmetricPaddingMode dwFlags); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSASignVerify.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSASignVerify.cs index 03a12cbdbcf410..cd8bf922227cd6 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSASignVerify.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSASignVerify.cs @@ -391,6 +391,25 @@ public void Verify2048WithSha1() } } + [Fact] + public void SignData_NullSignature_Fails() + { + using (DSA dsa = DSAFactory.Create()) + { + dsa.ImportParameters(DSATestData.GetDSA1024Params()); + + bool result = dsa.TrySignData( + "hello"u8, + (Span)null, + HashAlgorithmName.SHA1, + DSASignatureFormat.IeeeP1363FixedFieldConcatenation, + out int bytesWritten); + + Assert.False(result); + Assert.Equal(0, bytesWritten); + } + } + private void SignAndVerify(byte[] data, string hashAlgorithmName, DSAParameters dsaParameters, int expectedSignatureLength) { using (DSA dsa = DSAFactory.Create()) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.cs index 94d458564c9f94..da6b507994cd2b 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.cs @@ -86,6 +86,32 @@ public void VerifyHash_InvalidArguments_Throws(ECDsa ecdsa) AssertExtensions.Throws("hash", () => ecdsa.VerifyHash(null, null)); AssertExtensions.Throws("signature", () => ecdsa.VerifyHash(new byte[0], null)); } + + [Theory] + [MemberData(nameof(RealImplementations))] + public void SignHash_NullSignature_Fails(ECDsa ecdsa) + { + byte[] hash = RandomNumberGenerator.GetBytes(SHA256.HashSizeInBytes); + + AssertExtensions.Throws("destination", () => + ecdsa.SignHash(hash, (Span)null, DSASignatureFormat.IeeeP1363FixedFieldConcatenation)); + + bool result = ecdsa.TrySignHash(hash, (Span)null, DSASignatureFormat.IeeeP1363FixedFieldConcatenation, out int bytesWritten); + Assert.False(result); + Assert.Equal(0, bytesWritten); + } + + [Theory] + [MemberData(nameof(RealImplementations))] + public void SignData_NullSignature_Fails(ECDsa ecdsa) + { + AssertExtensions.Throws("destination", () => + ecdsa.SignData("hello"u8, (Span)null, HashAlgorithmName.SHA256, DSASignatureFormat.IeeeP1363FixedFieldConcatenation)); + + bool result = ecdsa.TrySignData("hello"u8, (Span)null, HashAlgorithmName.SHA256, DSASignatureFormat.IeeeP1363FixedFieldConcatenation, out int bytesWritten); + Assert.False(result); + Assert.Equal(0, bytesWritten); + } } [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs index 6b0fd33bf89e7b..84c8f76d2b3eec 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/SignVerify.cs @@ -1429,6 +1429,60 @@ public void PssSignature_WrongLength() } } + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public void SignHash_NullSignature_Fails(bool usePss) + { + if (!SupportsPss) + { + throw new SkipTestException("Platform does not support PSS"); + } + + RSASignaturePadding padding = usePss ? RSASignaturePadding.Pss : RSASignaturePadding.Pkcs1; + + using (RSA rsa = RSA.Create()) + { + byte[] hash = RandomNumberGenerator.GetBytes(SHA256.HashSizeInBytes); + + AssertExtensions.Throws("destination", () => + rsa.SignHash(hash, (Span)null, HashAlgorithmName.SHA256, padding)); + + bool result = rsa.TrySignHash( + hash, + (Span)null, + HashAlgorithmName.SHA256, + padding, + out int bytesWritten); + + Assert.False(result); + Assert.Equal(0, bytesWritten); + } + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public void SignData_NullSignature_Fails(bool usePss) + { + if (!SupportsPss) + { + throw new SkipTestException("Platform does not support PSS"); + } + + RSASignaturePadding padding = usePss ? RSASignaturePadding.Pss : RSASignaturePadding.Pkcs1; + + using (RSA rsa = RSA.Create()) + { + AssertExtensions.Throws("destination", () => + rsa.SignData("hello"u8, (Span)null, HashAlgorithmName.SHA256, padding)); + + bool result = rsa.TrySignData("hello"u8, (Span)null, HashAlgorithmName.SHA256, padding, out int bytesWritten); + Assert.False(result); + Assert.Equal(0, bytesWritten); + } + } + private void ExpectSignature( byte[] expectedSignature, byte[] data, diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngCommon.SignVerify.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngCommon.SignVerify.cs index 994772779b23e3..ec6241baa7f1a1 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngCommon.SignVerify.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngCommon.SignVerify.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics; using Internal.Cryptography; using Microsoft.Win32.SafeHandles; using ErrorCode = Interop.NCrypt.ErrorCode; @@ -20,22 +21,22 @@ public static unsafe byte[] SignHash(this SafeNCryptKeyHandle keyHandle, ReadOnl #endif byte[] signature = new byte[estimatedSize]; int numBytesNeeded; - ErrorCode errorCode = Interop.NCrypt.NCryptSignHash(keyHandle, pPaddingInfo, hash, hash.Length, signature, signature.Length, out numBytesNeeded, paddingMode); + ErrorCode errorCode = Interop.NCrypt.NCryptSignHash(keyHandle, pPaddingInfo, hash, signature, out numBytesNeeded, paddingMode); if (errorCode == ErrorCode.STATUS_UNSUCCESSFUL) { - errorCode = Interop.NCrypt.NCryptSignHash(keyHandle, pPaddingInfo, hash, hash.Length, signature, signature.Length, out numBytesNeeded, paddingMode); + errorCode = Interop.NCrypt.NCryptSignHash(keyHandle, pPaddingInfo, hash, signature, out numBytesNeeded, paddingMode); } if (errorCode.IsBufferTooSmall()) { signature = new byte[numBytesNeeded]; - errorCode = Interop.NCrypt.NCryptSignHash(keyHandle, pPaddingInfo, hash, hash.Length, signature, signature.Length, out numBytesNeeded, paddingMode); + errorCode = Interop.NCrypt.NCryptSignHash(keyHandle, pPaddingInfo, hash, signature, out numBytesNeeded, paddingMode); } if (errorCode == ErrorCode.STATUS_UNSUCCESSFUL) { - errorCode = Interop.NCrypt.NCryptSignHash(keyHandle, pPaddingInfo, hash, hash.Length, signature, signature.Length, out numBytesNeeded, paddingMode); + errorCode = Interop.NCrypt.NCryptSignHash(keyHandle, pPaddingInfo, hash, signature, out numBytesNeeded, paddingMode); } if (errorCode != ErrorCode.ERROR_SUCCESS) @@ -53,9 +54,7 @@ public static unsafe bool TrySignHash(this SafeNCryptKeyHandle keyHandle, ReadOn keyHandle, pPaddingInfo, hash, - hash.Length, signature, - signature.Length, out int numBytesNeeded, paddingMode); @@ -63,6 +62,7 @@ public static unsafe bool TrySignHash(this SafeNCryptKeyHandle keyHandle, ReadOn { case ErrorCode.ERROR_SUCCESS: bytesWritten = numBytesNeeded; + Debug.Assert(bytesWritten <= signature.Length); return true; case ErrorCode code when code.IsBufferTooSmall(): From e585246faebbfd704625302fc68c9e6fcc268a9d Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Tue, 14 Nov 2023 20:26:30 +0000 Subject: [PATCH 472/783] Disable optimization which sometimes results in incorrect case sensitivity in FrozenCollections (#94667) (#94685) * Add failing tests * Fix incorrect case sensitivity in FrozenDictionary and FrozenSet for some cases fixes #93974 * When hashing the entire string, case sensitivity of hash and equals should be the same * Address code review comments * Only ignore case insensitivity if entire string is ASCII non-letters * Code review comments * Undo some new lines * Fixed tests - incorrect leftover from previous PR Co-authored-by: Andrew J Said --- .../Collections/Frozen/String/KeyAnalyzer.cs | 20 ++++----- .../Frozen/FrozenFromKnownValuesTests.cs | 42 +++++++++++++++++++ .../tests/Frozen/KeyAnalyzerTests.cs | 8 ++++ 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs index da050f12a83cb5..23742d276e23fc 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs @@ -37,7 +37,7 @@ public static AnalysisResults Analyze( AnalysisResults results; if (minLength == 0 || !TryUseSubstring(uniqueStrings, ignoreCase, minLength, maxLength, out results)) { - results = CreateAnalysisResults(uniqueStrings, ignoreCase, minLength, maxLength, 0, 0, static (s, _, _) => s.AsSpan()); + results = CreateAnalysisResults(uniqueStrings, ignoreCase, minLength, maxLength, 0, 0, isSubstring: false, static (s, _, _) => s.AsSpan()); } return results; @@ -71,7 +71,7 @@ private static bool TryUseSubstring(ReadOnlySpan uniqueStrings, bool ign if (HasSufficientUniquenessFactor(set, uniqueStrings)) { results = CreateAnalysisResults( - uniqueStrings, ignoreCase, minLength, maxLength, index, count, + uniqueStrings, ignoreCase, minLength, maxLength, index, count, isSubstring: true, static (string s, int index, int count) => s.AsSpan(index, count)); return true; } @@ -96,7 +96,7 @@ private static bool TryUseSubstring(ReadOnlySpan uniqueStrings, bool ign if (HasSufficientUniquenessFactor(set, uniqueStrings)) { results = CreateAnalysisResults( - uniqueStrings, ignoreCase, minLength, maxLength, comparer.Index, count, + uniqueStrings, ignoreCase, minLength, maxLength, comparer.Index, count, isSubstring: true, static (string s, int index, int count) => s.AsSpan(s.Length + index, count)); return true; } @@ -110,7 +110,7 @@ private static bool TryUseSubstring(ReadOnlySpan uniqueStrings, bool ign } private static AnalysisResults CreateAnalysisResults( - ReadOnlySpan uniqueStrings, bool ignoreCase, int minLength, int maxLength, int index, int count, GetSpan getSubstringSpan) + ReadOnlySpan uniqueStrings, bool ignoreCase, int minLength, int maxLength, int index, int count, bool isSubstring, GetSpan getSubstringSpan) { // Start off by assuming all strings are ASCII bool allAsciiIfIgnoreCase = true; @@ -120,11 +120,11 @@ private static AnalysisResults CreateAnalysisResults( // substrings are ASCII, so we check each. if (ignoreCase) { - // Further, if the ASCII substrings don't contain any letters, then we can + // Further, if the ASCII keys (in their entirety) don't contain any letters, then we can // actually perform the comparison as case-sensitive even if case-insensitive // was requested, as there's nothing that would compare equally to the substring // other than the substring itself. - bool canSwitchIgnoreCaseToCaseSensitive = true; + bool canSwitchIgnoreCaseHashToCaseSensitive = !isSubstring; foreach (string s in uniqueStrings) { @@ -135,20 +135,20 @@ private static AnalysisResults CreateAnalysisResults( if (!IsAllAscii(substring)) { allAsciiIfIgnoreCase = false; - canSwitchIgnoreCaseToCaseSensitive = false; + canSwitchIgnoreCaseHashToCaseSensitive = false; break; } // All substrings so far are still ASCII only. If this one contains any ASCII // letters, mark that we can't switch to case-sensitive. - if (canSwitchIgnoreCaseToCaseSensitive && ContainsAnyLetters(substring)) + if (canSwitchIgnoreCaseHashToCaseSensitive && ContainsAnyLetters(substring)) { - canSwitchIgnoreCaseToCaseSensitive = false; + canSwitchIgnoreCaseHashToCaseSensitive = false; } } // If we can switch to case-sensitive, do so. - if (canSwitchIgnoreCaseToCaseSensitive) + if (canSwitchIgnoreCaseHashToCaseSensitive) { ignoreCase = false; } diff --git a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenFromKnownValuesTests.cs b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenFromKnownValuesTests.cs index e11de4412941e5..5776a7373bb5fd 100644 --- a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenFromKnownValuesTests.cs +++ b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenFromKnownValuesTests.cs @@ -142,6 +142,15 @@ public static IEnumerable StringStringData() => Enumerable.Range(0, 100).Select(i => $"{i:D2}ABCDEFGH\U0001F600").ToArray(), // left justified substring non-ascii Enumerable.Range(0, 100).Select(i => $"ABCDEFGH\U0001F600{i:D2}").ToArray(), // right justified substring non-ascii Enumerable.Range(0, 20).Select(i => i.ToString("D2")).Select(s => (char)(s[0] + 128) + "" + (char)(s[1] + 128)).ToArray(), // left-justified non-ascii + + Enumerable.Range(0, 10).Select(i => $"{i}ABCDefgh").ToArray(), // left justified single char ascii, mixed casing + Enumerable.Range(0, 10).Select(i => $"ABCDefgh{i}").ToArray(), // right justified single char ascii, mixed casing + Enumerable.Range(0, 100).Select(i => $"{i:D2}ABCDefgh").ToArray(), // left justified substring ascii, mixed casing + Enumerable.Range(0, 100).Select(i => $"ABCDefgh{i:D2}").ToArray(), // right justified substring ascii, mixed casing + Enumerable.Range(0, 10).Select(i => $"{i}ABCDefgh\U0001F600").ToArray(), // left justified single char non-ascii, mixed casing + Enumerable.Range(0, 10).Select(i => $"ABCDefgh\U0001F600{i}").ToArray(), // right justified single char non-ascii, mixed casing + Enumerable.Range(0, 100).Select(i => $"{i:D2}ABCDefgh\U0001F600").ToArray(), // left justified substring non-ascii, mixed casing + Enumerable.Range(0, 100).Select(i => $"ABCDefgh\U0001F600{i:D2}").ToArray(), // right justified substring non-ascii, mixed casing } select new object[] { keys.ToDictionary(i => i, i => i, comparer) }; @@ -191,6 +200,23 @@ private static void FrozenDictionaryWorker(Dictionary pair in source) + { + TKey keyUpper = (TKey)(object)((string)(object)pair.Key).ToUpper(); + bool isValidTest = frozen.Comparer.Equals(pair.Key, keyUpper); + if (isValidTest) + { + Assert.Equal(pair.Value, frozen.GetValueRefOrNullRef(keyUpper)); + Assert.Equal(pair.Value, frozen[keyUpper]); + Assert.True(frozen.TryGetValue(keyUpper, out TValue value)); + Assert.Equal(pair.Value, value); + } + } + } + foreach (KeyValuePair pair in frozen) { Assert.True(source.TryGetValue(pair.Key, out TValue value)); @@ -269,6 +295,22 @@ private void FrozenSetWorker(Dictionary source) Assert.True(frozen.TryGetValue(pair.Key, out TKey actualKey)); Assert.Equal(pair.Key, actualKey); } + + if (typeof(TKey) == typeof(string) && ReferenceEquals(frozen.Comparer, StringComparer.OrdinalIgnoreCase)) + { + foreach (KeyValuePair pair in source) + { + TKey keyUpper = (TKey)(object)((string)(object)pair.Key).ToUpper(); + bool isValidTest = frozen.Comparer.Equals(pair.Key, keyUpper); + if (isValidTest) + { + Assert.True(frozen.Contains(keyUpper)); + Assert.True(frozen.TryGetValue(keyUpper, out TKey actualKey)); + Assert.Equal(pair.Key, actualKey); + } + } + } + foreach (TKey key in frozen) { Assert.True(source.TryGetValue(key, out _)); diff --git a/src/libraries/System.Collections.Immutable/tests/Frozen/KeyAnalyzerTests.cs b/src/libraries/System.Collections.Immutable/tests/Frozen/KeyAnalyzerTests.cs index 6ddec56b6005e8..417ac4eb3533da 100644 --- a/src/libraries/System.Collections.Immutable/tests/Frozen/KeyAnalyzerTests.cs +++ b/src/libraries/System.Collections.Immutable/tests/Frozen/KeyAnalyzerTests.cs @@ -97,6 +97,14 @@ public static void LeftHandCaseInsensitive() Assert.False(r.AllAsciiIfIgnoreCase); Assert.Equal(7, r.HashIndex); Assert.Equal(1, r.HashCount); + + r = RunAnalysis(new[] { "1abc", "2abc", "3abc", "4abc", "5abc", "6abc" }, true); + Assert.False(r.RightJustifiedSubstring); + Assert.True(r.IgnoreCase); + Assert.True(r.AllAsciiIfIgnoreCase); + Assert.Equal(0, r.HashIndex); + Assert.Equal(1, r.HashCount); + } [Fact] From 64bff1aaada15d855be6b3e4dcec8adcb1826175 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Wed, 15 Nov 2023 11:57:28 +0100 Subject: [PATCH 473/783] [release/8.0-staging] Update APICompat baseline version to 8.0.0 (#94716) --- Directory.Build.props | 4 +- eng/Version.Details.xml | 8 +- eng/Versions.props | 4 +- eng/packaging.targets | 8 + .../src/CompatibilitySuppressions.xml | 10 - .../src/CompatibilitySuppressions.xml | 7 - .../Microsoft.NET.WebAssembly.Threading.proj | 1 + src/libraries/apicompat/ApiCompat.proj | 2 +- ...iCompatBaseline.NetCoreAppLatestStable.xml | 2690 +---------------- 9 files changed, 21 insertions(+), 2713 deletions(-) delete mode 100644 src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/CompatibilitySuppressions.xml delete mode 100644 src/libraries/Microsoft.NET.WebAssembly.Threading/src/CompatibilitySuppressions.xml diff --git a/Directory.Build.props b/Directory.Build.props index f6776738457046..3c8246c896739e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -114,8 +114,8 @@ - 7.0.0 - net7.0 + 8.0.0 + net8.0 $(NetFrameworkToolCurrent) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ae82d0c522e433..38706d841ef2a7 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -383,9 +383,13 @@ https://github.com/dotnet/roslyn-analyzers b4d9a1334d5189172977ba8fddd00bda70161e4a - + https://github.com/dotnet/sdk - 7e33fd449381b337c290a801057fdcd68c4b7220 + e9d13cbe7e8c1d52ce276a8655f52a87e1017c46 + + + https://github.com/dotnet/sdk + e9d13cbe7e8c1d52ce276a8655f52a87e1017c46 diff --git a/eng/Versions.props b/eng/Versions.props index 120b28e4439936..6cf72b14af94de 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -85,7 +85,7 @@ 0.2.0 - 8.0.100-rtm.23520.8 + 8.0.100 8.0.0-beta.23516.4 8.0.0-beta.23516.4 @@ -127,7 +127,7 @@ 7.0.0 5.0.0 4.8.5 - 7.0.0 + 8.0.0 5.0.0 4.5.5 7.0.0 diff --git a/eng/packaging.targets b/eng/packaging.targets index a36102a37acd5d..a1fbe07ed2a570 100644 --- a/eng/packaging.targets +++ b/eng/packaging.targets @@ -11,6 +11,7 @@ '$(SuppressFinalPackageVersion)' == 'true' or '$(DotNetBuildFromSource)' == 'true'">true $(ApiCompatNetCoreAppBaselineVersion) + $(BeforePack);IncludeAnalyzersInPackage;AddNETStandardCompatErrorFileForPackaging $(TargetsForTfmSpecificContentInPackage);AddRuntimeSpecificFilesToPackage;IncludeProjectReferencesWithPackAttributeInPackage @@ -37,6 +38,13 @@ false + + + true + + $(NoWarn);CP0003 + + - - - - CP0002 - M:Microsoft.Extensions.DependencyInjection.Specification.DependencyInjectionSpecificationTests.TypeActivatorCreateInstanceUsesFirstMathchedConstructor(System.Object,System.String) - true - - \ No newline at end of file diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/CompatibilitySuppressions.xml b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/CompatibilitySuppressions.xml deleted file mode 100644 index 26a2ff56955993..00000000000000 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/CompatibilitySuppressions.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - PKV006 - net7.0 - - \ No newline at end of file diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj index 3613b012fe57f2..45b3320dcfb5f6 100644 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj @@ -12,6 +12,7 @@ $(NoWarn);NU5128;NU5131;PKV004 ref + true diff --git a/src/libraries/apicompat/ApiCompat.proj b/src/libraries/apicompat/ApiCompat.proj index 06c48f5cd57af7..15c5b617fe509f 100644 --- a/src/libraries/apicompat/ApiCompat.proj +++ b/src/libraries/apicompat/ApiCompat.proj @@ -44,7 +44,7 @@ - + diff --git a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml index 0e532d660810fe..05317adadabbfe 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml +++ b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml @@ -1,2692 +1,4 @@  - - CP0002 - F:System.Net.Quic.QuicError.AddressInUse - net7.0/System.Net.Quic.dll - net8.0/System.Net.Quic.dll - - - CP0002 - F:System.Net.Quic.QuicError.HostUnreachable - net7.0/System.Net.Quic.dll - net8.0/System.Net.Quic.dll - - - CP0002 - F:System.Net.Quic.QuicError.InvalidAddress - net7.0/System.Net.Quic.dll - net8.0/System.Net.Quic.dll - - - CP0002 - F:System.Net.Quic.QuicError.ProtocolError - net7.0/System.Net.Quic.dll - net8.0/System.Net.Quic.dll - - - CP0002 - M:System.Runtime.InteropServices.JavaScript.JSFunctionBinding.#ctor - net7.0/System.Runtime.InteropServices.JavaScript.dll - net8.0/System.Runtime.InteropServices.JavaScript.dll - - - CP0014 - M:System.Console.get_WindowHeight:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] - net7.0/mscorlib.dll - net8.0/mscorlib.dll - - - CP0014 - M:System.Console.get_WindowWidth:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] - net7.0/mscorlib.dll - net8.0/mscorlib.dll - - - CP0014 - M:System.Console.set_WindowHeight(System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] - net7.0/mscorlib.dll - net8.0/mscorlib.dll - - - CP0014 - M:System.Console.set_WindowWidth(System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] - net7.0/mscorlib.dll - net8.0/mscorlib.dll - - - CP0014 - M:System.Console.SetWindowSize(System.Int32,System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] - net7.0/mscorlib.dll - net8.0/mscorlib.dll - - - CP0014 - M:System.Console.get_WindowHeight:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Console.get_WindowWidth:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Console.set_WindowHeight(System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Console.set_WindowWidth(System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Console.SetWindowSize(System.Int32,System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Aggregate``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``0,``0}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Aggregate``2(System.Linq.IQueryable{``0},``1,System.Linq.Expressions.Expression{System.Func{``1,``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Aggregate``3(System.Linq.IQueryable{``0},``1,System.Linq.Expressions.Expression{System.Func{``1,``0,``1}},System.Linq.Expressions.Expression{System.Func{``1,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.All``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Any``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Any``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Append``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Decimal}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Double}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int64}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Decimal}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Double}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Int32}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Int64}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Single}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Single}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Cast``1(System.Linq.IQueryable):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Chunk``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Concat``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Contains``1(System.Linq.IQueryable{``0},``0,System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Contains``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Count``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Count``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.DefaultIfEmpty``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.DefaultIfEmpty``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Distinct``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Distinct``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.DistinctBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.DistinctBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.ElementAt``1(System.Linq.IQueryable{``0},System.Index):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.ElementAt``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.ElementAtOrDefault``1(System.Linq.IQueryable{``0},System.Index):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.ElementAtOrDefault``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Except``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Except``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.ExceptBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.ExceptBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.First``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.First``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.FirstOrDefault``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.FirstOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.FirstOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.FirstOrDefault``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``0,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``1,System.Collections.Generic.IEnumerable{``0},``2}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``1,System.Collections.Generic.IEnumerable{``0},``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``4(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,System.Collections.Generic.IEnumerable{``2},``3}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``4(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,System.Collections.Generic.IEnumerable{``2},``3}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.GroupJoin``4(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,``2}},System.Linq.Expressions.Expression{System.Func{``0,System.Collections.Generic.IEnumerable{``1},``3}},System.Collections.Generic.IEqualityComparer{``2}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.GroupJoin``4(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,``2}},System.Linq.Expressions.Expression{System.Func{``0,System.Collections.Generic.IEnumerable{``1},``3}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Intersect``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Intersect``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.IntersectBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.IntersectBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Join``4(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,``2}},System.Linq.Expressions.Expression{System.Func{``0,``1,``3}},System.Collections.Generic.IEqualityComparer{``2}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Join``4(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,``2}},System.Linq.Expressions.Expression{System.Func{``0,``1,``3}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Last``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Last``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.LastOrDefault``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.LastOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.LastOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.LastOrDefault``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.LongCount``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.LongCount``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Max``1(System.Linq.IQueryable{``0},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Max``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Max``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.MaxBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.MaxBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Min``1(System.Linq.IQueryable{``0},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Min``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Min``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.MinBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.MinBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.OfType``1(System.Linq.IQueryable):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Order``1(System.Linq.IQueryable{``0},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Order``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.OrderBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.OrderBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.OrderByDescending``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.OrderByDescending``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.OrderDescending``1(System.Linq.IQueryable{``0},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.OrderDescending``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Prepend``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Reverse``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Select``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Select``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.SelectMany``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Collections.Generic.IEnumerable{``1}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.SelectMany``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Collections.Generic.IEnumerable{``1}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.SelectMany``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Collections.Generic.IEnumerable{``1}}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.SelectMany``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Collections.Generic.IEnumerable{``1}}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.SequenceEqual``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.SequenceEqual``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Single``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Single``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.SingleOrDefault``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.SingleOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.SingleOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.SingleOrDefault``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Skip``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.SkipLast``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.SkipWhile``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.SkipWhile``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Decimal}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Double}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int64}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Decimal}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Double}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Int32}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Int64}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Single}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Single}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Take``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Take``1(System.Linq.IQueryable{``0},System.Range):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.TakeLast``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.TakeWhile``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.TakeWhile``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.ThenBy``2(System.Linq.IOrderedQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.ThenBy``2(System.Linq.IOrderedQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.ThenByDescending``2(System.Linq.IOrderedQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.ThenByDescending``2(System.Linq.IOrderedQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Union``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Union``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.UnionBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.UnionBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Where``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Where``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Zip``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Zip``3(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Linq.Queryable.Zip``3(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - T:System.Net.Security.NegotiateStream:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0014 - M:System.Console.get_WindowHeight:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] - net7.0/System.Console.dll - net8.0/System.Console.dll - - - CP0014 - M:System.Console.get_WindowWidth:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] - net7.0/System.Console.dll - net8.0/System.Console.dll - - - CP0014 - M:System.Console.set_WindowHeight(System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] - net7.0/System.Console.dll - net8.0/System.Console.dll - - - CP0014 - M:System.Console.set_WindowWidth(System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] - net7.0/System.Console.dll - net8.0/System.Console.dll - - - CP0014 - M:System.Console.SetWindowSize(System.Int32,System.Int32):[T:System.Runtime.Versioning.SupportedOSPlatformAttribute] - net7.0/System.Console.dll - net8.0/System.Console.dll - - - CP0014 - M:System.Linq.Queryable.Aggregate``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``0,``0}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Aggregate``2(System.Linq.IQueryable{``0},``1,System.Linq.Expressions.Expression{System.Func{``1,``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Aggregate``3(System.Linq.IQueryable{``0},``1,System.Linq.Expressions.Expression{System.Func{``1,``0,``1}},System.Linq.Expressions.Expression{System.Func{``1,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.All``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Any``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Any``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Append``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Decimal}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Double}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int64}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Decimal}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Double}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Int32}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Int64}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Single}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Single}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Cast``1(System.Linq.IQueryable):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Chunk``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Concat``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Contains``1(System.Linq.IQueryable{``0},``0,System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Contains``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Count``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Count``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.DefaultIfEmpty``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.DefaultIfEmpty``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Distinct``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Distinct``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.DistinctBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.DistinctBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.ElementAt``1(System.Linq.IQueryable{``0},System.Index):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.ElementAt``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.ElementAtOrDefault``1(System.Linq.IQueryable{``0},System.Index):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.ElementAtOrDefault``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Except``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Except``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.ExceptBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.ExceptBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.First``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.First``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.FirstOrDefault``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.FirstOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.FirstOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.FirstOrDefault``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``0,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``1,System.Collections.Generic.IEnumerable{``0},``2}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``1,System.Collections.Generic.IEnumerable{``0},``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``4(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,System.Collections.Generic.IEnumerable{``2},``3}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``4(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,System.Collections.Generic.IEnumerable{``2},``3}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.GroupJoin``4(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,``2}},System.Linq.Expressions.Expression{System.Func{``0,System.Collections.Generic.IEnumerable{``1},``3}},System.Collections.Generic.IEqualityComparer{``2}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.GroupJoin``4(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,``2}},System.Linq.Expressions.Expression{System.Func{``0,System.Collections.Generic.IEnumerable{``1},``3}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Intersect``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Intersect``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.IntersectBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.IntersectBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Join``4(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,``2}},System.Linq.Expressions.Expression{System.Func{``0,``1,``3}},System.Collections.Generic.IEqualityComparer{``2}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Join``4(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,``2}},System.Linq.Expressions.Expression{System.Func{``0,``1,``3}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Last``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Last``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.LastOrDefault``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.LastOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.LastOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.LastOrDefault``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.LongCount``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.LongCount``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Max``1(System.Linq.IQueryable{``0},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Max``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Max``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.MaxBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.MaxBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Min``1(System.Linq.IQueryable{``0},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Min``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Min``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.MinBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.MinBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.OfType``1(System.Linq.IQueryable):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Order``1(System.Linq.IQueryable{``0},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Order``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.OrderBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.OrderBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.OrderByDescending``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.OrderByDescending``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.OrderDescending``1(System.Linq.IQueryable{``0},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.OrderDescending``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Prepend``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Reverse``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Select``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Select``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.SelectMany``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Collections.Generic.IEnumerable{``1}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.SelectMany``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Collections.Generic.IEnumerable{``1}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.SelectMany``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Collections.Generic.IEnumerable{``1}}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.SelectMany``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Collections.Generic.IEnumerable{``1}}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.SequenceEqual``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.SequenceEqual``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Single``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Single``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.SingleOrDefault``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.SingleOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.SingleOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.SingleOrDefault``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Skip``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.SkipLast``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.SkipWhile``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.SkipWhile``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Decimal}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Double}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int64}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Decimal}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Double}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Int32}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Int64}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Single}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Single}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Take``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Take``1(System.Linq.IQueryable{``0},System.Range):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.TakeLast``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.TakeWhile``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.TakeWhile``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.ThenBy``2(System.Linq.IOrderedQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.ThenBy``2(System.Linq.IOrderedQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.ThenByDescending``2(System.Linq.IOrderedQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.ThenByDescending``2(System.Linq.IOrderedQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Union``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Union``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.UnionBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.UnionBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Where``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Where``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Zip``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Zip``3(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Linq.Queryable.Zip``3(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0014 - M:System.Diagnostics.DiagnosticListener.Write(System.String,System.Object):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Diagnostics.DiagnosticSource.dll - net8.0/System.Diagnostics.DiagnosticSource.dll - - - CP0014 - M:System.Diagnostics.DiagnosticSource.StartActivity(System.Diagnostics.Activity,System.Object):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Diagnostics.DiagnosticSource.dll - net8.0/System.Diagnostics.DiagnosticSource.dll - - - CP0014 - M:System.Diagnostics.DiagnosticSource.StopActivity(System.Diagnostics.Activity,System.Object):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Diagnostics.DiagnosticSource.dll - net8.0/System.Diagnostics.DiagnosticSource.dll - - - CP0014 - M:System.Diagnostics.DiagnosticSource.Write(System.String,System.Object):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Diagnostics.DiagnosticSource.dll - net8.0/System.Diagnostics.DiagnosticSource.dll - - - CP0014 - T:System.Net.Security.NegotiateStream:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] - net7.0/System.dll - net8.0/System.dll - - - CP0014 - M:System.Linq.Queryable.Aggregate``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``0,``0}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Aggregate``2(System.Linq.IQueryable{``0},``1,System.Linq.Expressions.Expression{System.Func{``1,``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Aggregate``3(System.Linq.IQueryable{``0},``1,System.Linq.Expressions.Expression{System.Func{``1,``0,``1}},System.Linq.Expressions.Expression{System.Func{``1,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.All``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Any``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Any``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Append``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Decimal}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Double}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int64}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Decimal}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Double}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Int32}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Int64}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Single}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Average``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Single}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Cast``1(System.Linq.IQueryable):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Chunk``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Concat``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Contains``1(System.Linq.IQueryable{``0},``0,System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Contains``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Count``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Count``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.DefaultIfEmpty``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.DefaultIfEmpty``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Distinct``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Distinct``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.DistinctBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.DistinctBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.ElementAt``1(System.Linq.IQueryable{``0},System.Index):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.ElementAt``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.ElementAtOrDefault``1(System.Linq.IQueryable{``0},System.Index):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.ElementAtOrDefault``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Except``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Except``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.ExceptBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.ExceptBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.First``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.First``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.FirstOrDefault``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.FirstOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.FirstOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.FirstOrDefault``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``0,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``1,System.Collections.Generic.IEnumerable{``0},``2}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``1,System.Collections.Generic.IEnumerable{``0},``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``4(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,System.Collections.Generic.IEnumerable{``2},``3}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.GroupBy``4(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,System.Collections.Generic.IEnumerable{``2},``3}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.GroupJoin``4(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,``2}},System.Linq.Expressions.Expression{System.Func{``0,System.Collections.Generic.IEnumerable{``1},``3}},System.Collections.Generic.IEqualityComparer{``2}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.GroupJoin``4(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,``2}},System.Linq.Expressions.Expression{System.Func{``0,System.Collections.Generic.IEnumerable{``1},``3}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Intersect``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Intersect``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.IntersectBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.IntersectBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Join``4(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,``2}},System.Linq.Expressions.Expression{System.Func{``0,``1,``3}},System.Collections.Generic.IEqualityComparer{``2}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Join``4(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``2}},System.Linq.Expressions.Expression{System.Func{``1,``2}},System.Linq.Expressions.Expression{System.Func{``0,``1,``3}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Last``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Last``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.LastOrDefault``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.LastOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.LastOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.LastOrDefault``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.LongCount``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.LongCount``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Max``1(System.Linq.IQueryable{``0},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Max``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Max``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.MaxBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.MaxBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Min``1(System.Linq.IQueryable{``0},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Min``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Min``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.MinBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.MinBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.OfType``1(System.Linq.IQueryable):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Order``1(System.Linq.IQueryable{``0},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Order``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.OrderBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.OrderBy``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.OrderByDescending``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.OrderByDescending``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.OrderDescending``1(System.Linq.IQueryable{``0},System.Collections.Generic.IComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.OrderDescending``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Prepend``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Reverse``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Select``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Select``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.SelectMany``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Collections.Generic.IEnumerable{``1}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.SelectMany``2(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Collections.Generic.IEnumerable{``1}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.SelectMany``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Collections.Generic.IEnumerable{``1}}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.SelectMany``3(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Collections.Generic.IEnumerable{``1}}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.SequenceEqual``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.SequenceEqual``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Single``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Single``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.SingleOrDefault``1(System.Linq.IQueryable{``0},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.SingleOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},``0):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.SingleOrDefault``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.SingleOrDefault``1(System.Linq.IQueryable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Skip``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.SkipLast``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.SkipWhile``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.SkipWhile``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Decimal}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Double}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int64}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Decimal}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Double}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Int32}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Int64}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Nullable{System.Single}}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Sum``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Single}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Take``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Take``1(System.Linq.IQueryable{``0},System.Range):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.TakeLast``1(System.Linq.IQueryable{``0},System.Int32):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.TakeWhile``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.TakeWhile``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.ThenBy``2(System.Linq.IOrderedQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.ThenBy``2(System.Linq.IOrderedQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.ThenByDescending``2(System.Linq.IOrderedQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.ThenByDescending``2(System.Linq.IOrderedQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Union``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEqualityComparer{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Union``1(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.UnionBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Collections.Generic.IEqualityComparer{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.UnionBy``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Where``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Where``1(System.Linq.IQueryable{``0},System.Linq.Expressions.Expression{System.Func{``0,System.Int32,System.Boolean}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Zip``2(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Zip``3(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Collections.Generic.IEnumerable{``2}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - M:System.Linq.Queryable.Zip``3(System.Linq.IQueryable{``0},System.Collections.Generic.IEnumerable{``1},System.Linq.Expressions.Expression{System.Func{``0,``1,``2}}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0014 - T:System.Net.Security.NegotiateStream:[T:System.Runtime.Versioning.UnsupportedOSPlatformAttribute] - net7.0/System.Net.Security.dll - net8.0/System.Net.Security.dll - - - CP0015 - M:System.Type.GetEnumValues:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/mscorlib.dll - net8.0/mscorlib.dll - - - CP0015 - M:System.Linq.Queryable.AsQueryable(System.Collections.IEnumerable):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0015 - M:System.Linq.Queryable.AsQueryable``1(System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0015 - M:System.Type.GetEnumValues:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0015 - T:System.Linq.EnumerableQuery`1:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/netstandard.dll - net8.0/netstandard.dll - - - CP0015 - M:System.Linq.Queryable.AsQueryable(System.Collections.IEnumerable):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0015 - M:System.Linq.Queryable.AsQueryable``1(System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0015 - T:System.Linq.EnumerableQuery`1:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Core.dll - net8.0/System.Core.dll - - - CP0015 - M:System.Linq.Queryable.AsQueryable(System.Collections.IEnumerable):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0015 - M:System.Linq.Queryable.AsQueryable``1(System.Collections.Generic.IEnumerable{``0}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0015 - T:System.Linq.EnumerableQuery`1:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Linq.Queryable.dll - net8.0/System.Linq.Queryable.dll - - - CP0015 - M:System.Type.GetEnumValues:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Runtime.dll - net8.0/System.Runtime.dll - - - CP0015 - T:System.Runtime.InteropServices.Marshalling.NativeMarshallingAttribute:[T:System.AttributeUsageAttribute] - net7.0/System.Runtime.dll - net8.0/System.Runtime.dll - - - CP0015 - M:System.Reflection.Metadata.MetadataUpdateHandlerAttribute.#ctor(System.Type)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] - net7.0/System.Runtime.Loader.dll - net8.0/System.Runtime.Loader.dll - - - CP0015 - P:System.Reflection.Metadata.MetadataUpdateHandlerAttribute.HandlerType:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] - net7.0/System.Runtime.Loader.dll - net8.0/System.Runtime.Loader.dll - - - CP0015 - T:System.Text.Json.Serialization.JsonStringEnumConverter:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - net7.0/System.Text.Json.dll - net8.0/System.Text.Json.dll - - \ No newline at end of file + From 7bdab0ee915a27499239a22c7d580c88bb781a31 Mon Sep 17 00:00:00 2001 From: David Cantu Date: Wed, 15 Nov 2023 18:34:10 +0000 Subject: [PATCH 474/783] [8.0] Do not cache unknown friendly names as null in OidLookup --- .../src/System/Security/Cryptography/OidLookup.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/OidLookup.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/OidLookup.cs index 0108cb3f13e330..d2d07d42e57266 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/OidLookup.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/OidLookup.cs @@ -12,8 +12,8 @@ internal static partial class OidLookup private static readonly ConcurrentDictionary s_lateBoundOidToFriendlyName = new ConcurrentDictionary(); - private static readonly ConcurrentDictionary s_lateBoundFriendlyNameToOid = - new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + private static readonly ConcurrentDictionary s_lateBoundFriendlyNameToOid = + new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); // // Attempts to map a friendly name to an OID. Returns null if not a known name. @@ -77,19 +77,13 @@ internal static partial class OidLookup mappedOid = NativeFriendlyNameToOid(friendlyName, oidGroup, fallBackToAllGroups); - if (shouldUseCache) + if (shouldUseCache && mappedOid != null) { s_lateBoundFriendlyNameToOid.TryAdd(friendlyName, mappedOid); // Don't add the reverse here. Friendly Name => OID is a case insensitive search, // so the casing provided as input here may not be the 'correct' one. Just let // ToFriendlyName capture the response and cache it itself. - - // Also, mappedOid could be null here if the lookup failed. Allowing storing null - // means we're able to cache that a lookup failed so we don't repeat it. It's - // theoretically possible, however, the failure could have been intermittent, e.g. - // if the call was forced to follow an AD fallback path and the relevant servers - // were offline. } return mappedOid; From 6e0ecbd5638c0e1ca4fea99f181aa94a5e33a91c Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Wed, 15 Nov 2023 18:35:11 +0000 Subject: [PATCH 475/783] [8.0] Do not use AllocHGlobal in Pkcs12Reader --- .../X509Certificates/UnixPkcs12Reader.cs | 40 ++++--------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixPkcs12Reader.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixPkcs12Reader.cs index a9a89f6769690e..8b4e999750f8c1 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixPkcs12Reader.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixPkcs12Reader.cs @@ -24,7 +24,7 @@ internal abstract class UnixPkcs12Reader : IDisposable private ContentInfoAsn[]? _safeContentsValues; private CertAndKey[]? _certs; private int _certCount; - private PointerMemoryManager? _tmpManager; + private Memory _tmpMemory; private bool _allowDoubleBind; protected abstract ICertificatePalCore ReadX509Der(ReadOnlyMemory data); @@ -39,19 +39,13 @@ protected void ParsePkcs12(ReadOnlySpan data) // Windows compatibility: Ignore trailing data. ReadOnlySpan encodedData = reader.PeekEncodedValue(); + byte[] dataWithoutTrailing = GC.AllocateUninitializedArray(encodedData.Length, pinned: true); + encodedData.CopyTo(dataWithoutTrailing); + _tmpMemory = MemoryMarshal.CreateFromPinnedArray(dataWithoutTrailing, 0, dataWithoutTrailing.Length); - unsafe - { - IntPtr tmpPtr = Marshal.AllocHGlobal(encodedData.Length); - Span tmpSpan = new Span((byte*)tmpPtr, encodedData.Length); - encodedData.CopyTo(tmpSpan); - _tmpManager = new PointerMemoryManager((void*)tmpPtr, encodedData.Length); - } - - ReadOnlyMemory tmpMemory = _tmpManager.Memory; - reader = new AsnValueReader(tmpMemory.Span, AsnEncodingRules.BER); + reader = new AsnValueReader(_tmpMemory.Span, AsnEncodingRules.BER); - PfxAsn.Decode(ref reader, tmpMemory, out PfxAsn pfxAsn); + PfxAsn.Decode(ref reader, _tmpMemory, out PfxAsn pfxAsn); if (pfxAsn.AuthSafe.ContentType != Oids.Pkcs7Data) { @@ -112,26 +106,8 @@ internal IEnumerable EnumerateAll() public void Dispose() { - // Generally, having a MemoryManager cleaned up in a Dispose is a bad practice. - // In this case, the UnixPkcs12Reader is only ever created in a using statement, - // never accessed by a second thread, and there isn't a manual call to Dispose - // mixed in anywhere. - if (_tmpManager != null) - { - unsafe - { - Span tmp = _tmpManager.GetSpan(); - CryptographicOperations.ZeroMemory(tmp); - - fixed (byte* ptr = tmp) - { - Marshal.FreeHGlobal((IntPtr)ptr); - } - } - - ((IDisposable)_tmpManager).Dispose(); - _tmpManager = null; - } + CryptographicOperations.ZeroMemory(_tmpMemory.Span); + _tmpMemory = Memory.Empty; ContentInfoAsn[]? rentedContents = Interlocked.Exchange(ref _safeContentsValues, null); CertAndKey[]? rentedCerts = Interlocked.Exchange(ref _certs, null); From 8f5de404556082064463eca507ee26e14a419a7b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 15 Nov 2023 10:48:53 -0800 Subject: [PATCH 476/783] [release/8.0-staging] #ifdef out code that requires FEATURE_EVENT_TRACE (#94715) * #ifdef out code that requires FEATURE_EVENT_TRACE * remove assert --------- Co-authored-by: yowl --- src/coreclr/gc/gc.cpp | 1 - src/coreclr/nativeaot/Runtime/gcrhenv.cpp | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 7351954070725e..86022c70550a50 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -10069,7 +10069,6 @@ void gc_heap::update_ro_segment (heap_segment* seg, uint8_t* allocated, uint8_t* { enter_spin_lock (&gc_heap::gc_lock); - assert (use_frozen_segments_p); assert (heap_segment_read_only_p (seg)); assert (allocated <= committed); assert (committed <= heap_segment_reserved (seg)); diff --git a/src/coreclr/nativeaot/Runtime/gcrhenv.cpp b/src/coreclr/nativeaot/Runtime/gcrhenv.cpp index 3ec488605c1b33..379bf5003f9b2a 100644 --- a/src/coreclr/nativeaot/Runtime/gcrhenv.cpp +++ b/src/coreclr/nativeaot/Runtime/gcrhenv.cpp @@ -749,10 +749,12 @@ void GCToEEInterface::DiagGCEnd(size_t index, int gen, int reason, bool fConcurr UNREFERENCED_PARAMETER(gen); UNREFERENCED_PARAMETER(reason); +#ifdef FEATURE_EVENT_TRACE if (!fConcurrent) { ETW::GCLog::WalkHeap(); } +#endif // FEATURE_EVENT_TRACE } // Note on last parameter: when calling this for bgc, only ETW From 5acd05ee4e532907dd4ff912e40d0ebb7417994b Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Wed, 15 Nov 2023 11:10:00 -0800 Subject: [PATCH 477/783] [release/8.0] Calculate PackageVersionNet7 (#94614) Since 8.0 is GA, we'll be able to calculate the net7 version based on PatchVersion --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 6cf72b14af94de..aa3a04369fe027 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,7 +7,7 @@ 0 0 8.0.100 - 7.0.12 + 7.0.$([MSBuild]::Add($(PatchVersion),14)) 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) rtm From 467099ff4313ca8c8abfd83ca10888dc1c42896e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 15 Nov 2023 16:43:47 -0500 Subject: [PATCH 478/783] [release/8.0-staging] [main] Fixed DateTimeOffset.Now calls on Android with specific conditions (#94718) Fixed issue when DateTimeOffset.Now throws exception on Android with Arabic language & western hemisphere timezone Backport of https://github.com/dotnet/runtime/pull/94710 Co-authored-by: Taras Shevchuk --- .../src/System/DateTimeOffset.Android.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.Android.cs b/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.Android.cs index c40e4708e47aab..e9ca7bb3eeb877 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.Android.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.Android.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Globalization; using System.Threading; namespace System @@ -60,7 +61,7 @@ public static DateTimeOffset Now } // Fast path obtained offset incorporated into ToLocalTime(DateTime.UtcNow, true) logic - int localDateTimeOffsetSeconds = Convert.ToInt32(localDateTimeOffset); + int localDateTimeOffsetSeconds = Convert.ToInt32(localDateTimeOffset, CultureInfo.InvariantCulture); TimeSpan offset = TimeSpan.FromSeconds(localDateTimeOffsetSeconds); long localTicks = utcDateTime.Ticks + offset.Ticks; if (localTicks < DateTime.MinTicks || localTicks > DateTime.MaxTicks) From fef37023557f560431ba7766828136d1dc0ed1e4 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 15 Nov 2023 14:10:23 -0800 Subject: [PATCH 479/783] [release/8.0] Update dependencies from dotnet/emsdk (#94516) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/dotnet/emsdk build 20231108.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.0-rtm.23530.2 -> To Version 8.0.0-rtm.23558.2 * Update dependencies from https://github.com/dotnet/emsdk build 20231108.4 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.0-rtm.23530.2 -> To Version 8.0.1-rtm.23558.4 * Update dependencies from https://github.com/dotnet/emsdk build 20231109.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.0-rtm.23530.2 -> To Version 8.0.1-servicing.23559.1 * Update dependencies from https://github.com/dotnet/emsdk build 20231113.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.0-rtm.23530.2 -> To Version 8.0.1-servicing.23563.2 Dependency coherency updates runtime.linux-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.win-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.win-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.osx-arm64.Microsoft.NETCore.Runtime.ObjWriter,runtime.osx-x64.Microsoft.NETCore.Runtime.ObjWriter,runtime.linux-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.win-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.win-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.osx-arm64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.osx-x64.Microsoft.NETCore.Runtime.JIT.Tools,runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-musl-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.linux-musl-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.osx-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.osx-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools,runtime.osx-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk,runtime.osx-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools From Version 16.0.5-alpha.1.23478.1 -> To Version 16.0.5-alpha.1.23558.12 (parent: Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- NuGet.config | 1 + eng/Version.Details.xml | 128 ++++++++++++++++++++-------------------- eng/Versions.props | 62 +++++++++---------- 3 files changed, 96 insertions(+), 95 deletions(-) diff --git a/NuGet.config b/NuGet.config index 0c7e2962cba265..fd2b87b608a8c8 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,6 +9,7 @@ + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2352181aa0037f..4d2d5b07608b86 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -12,69 +12,69 @@ https://github.com/dotnet/wcf 7f504aabb1988e9a093c1e74d8040bd52feb2f01 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 https://github.com/dotnet/command-line-api @@ -90,13 +90,13 @@ 45dd3a73dd5b64b010c4251303b3664bb30df029 - + https://github.com/dotnet/emsdk - 2406616d0e3a31d80b326e27c156955bfa41c791 + 0af50f733332e8c148f7f2debef2cb90504840d5 - + https://github.com/dotnet/emsdk - 2406616d0e3a31d80b326e27c156955bfa41c791 + 0af50f733332e8c148f7f2debef2cb90504840d5 @@ -237,61 +237,61 @@ https://github.com/dotnet/runtime-assets 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 - + https://github.com/dotnet/llvm-project - a0c65bc3a652036d21cd2c506a54c4b6cf8c49bd + ed5cffbdf262fdd9bb075b7b68d84bf3e4e090d4 https://github.com/dotnet/runtime diff --git a/eng/Versions.props b/eng/Versions.props index 39cd16e0073b2e..d37b781bec6fe8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -110,14 +110,14 @@ 8.0.0-rc.1.23406.6 8.0.0-preview.7.23325.2 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 6.0.0 1.1.1 @@ -222,38 +222,38 @@ 2.2.3 8.0.0-alpha.1.23527.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 - 8.0.0 + 8.0.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda 1.0.0-v3.14.0.5722 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 - 16.0.5-alpha.1.23478.1 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23558.12 3.1.7 1.0.406601 From a787c341d8c5f7fb3cc82b891aaff223bac78a64 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Wed, 15 Nov 2023 17:11:30 -0600 Subject: [PATCH 480/783] Pin to 8.0.100 (#94815) --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index aa3a04369fe027..c24d02e785c4d8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -258,7 +258,7 @@ 3.1.7 1.0.406601 - 8.0.100-rtm.23527.6 + 8.0.100 $(MicrosoftDotnetSdkInternalVersion) From aab2b2edc4d15f6ee4f2f88d2521eef506a1b1cd Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 14:35:15 +0100 Subject: [PATCH 481/783] [release/8.0] Update dependencies from dotnet/arcade (#94792) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/dotnet/arcade build 20231114.4 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23556.5 -> To Version 8.0.0-beta.23564.4 * Set MicrosoftDotnetSdkInternalVersion to 8.0.100. Uncomment SdkVersionForWorkloadTesting line. * Upgrade to VS preview image --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> Co-authored-by: Viktor Hofer --- eng/Version.Details.xml | 72 ++++++++++++++-------------- eng/Versions.props | 34 ++++++------- eng/pipelines/common/xplat-setup.yml | 2 +- global.json | 10 ++-- 4 files changed, 59 insertions(+), 59 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4d2d5b07608b86..16705807a4d5e3 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -111,9 +111,9 @@ - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d @@ -121,69 +121,69 @@ 73f0850939d96131c28cf6ea6ee5aacb4da0083a - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d https://github.com/dotnet/runtime-assets @@ -334,9 +334,9 @@ https://github.com/dotnet/xharness 480b9159eb7e69b182a87581d5a336e97e0b6dae - + https://github.com/dotnet/arcade - 080141bf0f9f15408bb6eb8e301b23bddf81d054 + 0aaeafef60933f87b0b50350313bb2fd77defb5d https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index d37b781bec6fe8..1766bc52259019 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -87,21 +87,21 @@ 8.0.100-rtm.23520.8 - 8.0.0-beta.23556.5 - 8.0.0-beta.23556.5 - 8.0.0-beta.23556.5 - 8.0.0-beta.23556.5 - 8.0.0-beta.23556.5 - 2.5.1-beta.23556.5 - 8.0.0-beta.23556.5 - 8.0.0-beta.23556.5 - 8.0.0-beta.23556.5 - 8.0.0-beta.23556.5 - 8.0.0-beta.23556.5 - 8.0.0-beta.23556.5 - 8.0.0-beta.23556.5 - 8.0.0-beta.23556.5 - 8.0.0-beta.23556.5 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 + 2.5.1-beta.23564.4 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 + 8.0.0-beta.23564.4 6.0.0-preview.1.102 @@ -258,7 +258,7 @@ 3.1.7 1.0.406601 - 8.0.100-rtm.23506.1 - + 8.0.100 + $(MicrosoftDotnetSdkInternalVersion) diff --git a/eng/pipelines/common/xplat-setup.yml b/eng/pipelines/common/xplat-setup.yml index eb19570aeecac2..bd00245788f552 100644 --- a/eng/pipelines/common/xplat-setup.yml +++ b/eng/pipelines/common/xplat-setup.yml @@ -173,7 +173,7 @@ jobs: # Public Windows Build Pool ${{ if and(or(eq(parameters.osGroup, 'windows'), eq(parameters.jobParameters.hostedOs, 'windows')), eq(variables['System.TeamProject'], 'public')) }}: name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals windows.vs2022.amd64.open + demands: ImageOverride -equals windows.vs2022preview.amd64.open ${{ if eq(parameters.helixQueuesTemplate, '') }}: diff --git a/global.json b/global.json index 0ba22484d372e8..517059ae7a3859 100644 --- a/global.json +++ b/global.json @@ -1,16 +1,16 @@ { "sdk": { - "version": "8.0.100-rtm.23506.1", + "version": "8.0.100", "allowPrerelease": true, "rollForward": "major" }, "tools": { - "dotnet": "8.0.100-rtm.23506.1" + "dotnet": "8.0.100" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23556.5", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23556.5", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23556.5", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23564.4", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23564.4", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23564.4", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From be88b591aa898f1e5fd43e3f3e24b4f215d04d09 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 10:37:21 -0800 Subject: [PATCH 482/783] Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231115.3 (#94851) optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23561.3 -> To Version 1.0.0-prerelease.23565.3 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 3 --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/NuGet.config b/NuGet.config index fd2b87b608a8c8..2daf70bbead041 100644 --- a/NuGet.config +++ b/NuGet.config @@ -10,9 +10,6 @@ - - - diff --git a/eng/Versions.props b/eng/Versions.props index e139f1eb0ed0ec..523816f7052b79 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23558.5 8.0.0-beta.23558.5 - 1.0.0-prerelease.23561.3 - 1.0.0-prerelease.23561.3 - 1.0.0-prerelease.23561.3 - 1.0.0-prerelease.23561.3 - 1.0.0-prerelease.23561.3 - 1.0.0-prerelease.23561.3 + 1.0.0-prerelease.23565.3 + 1.0.0-prerelease.23565.3 + 1.0.0-prerelease.23565.3 + 1.0.0-prerelease.23565.3 + 1.0.0-prerelease.23565.3 + 1.0.0-prerelease.23565.3 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From 656f461c50a46971fb5e6273bbe57d46f713a3e2 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Thu, 16 Nov 2023 12:51:02 -0600 Subject: [PATCH 483/783] Downgrade 6 & 7 per tactics (#94863) --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 523816f7052b79..ad201088988efe 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,7 +7,7 @@ 0 1 8.0.100 - 7.0.$([MSBuild]::Add($(PatchVersion),14)) + 7.0.$([MSBuild]::Add($(PatchVersion),13)) 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) servicing From 1f53b81051e6560f63147d0a9f9a3b50d97d1976 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 17:31:07 -0800 Subject: [PATCH 484/783] [release/8.0-staging] Support TimeSpan with RangeAttribute in Options validation source generator (#94857) Co-authored-by: Tarek Mahmoud Sayed --- .../gen/Emitter.cs | 91 +++++++++++-- .../gen/Parser.cs | 41 ++++-- .../gen/SymbolHolder.cs | 1 + .../gen/SymbolLoader.cs | 4 + .../src/Microsoft.Extensions.Options.csproj | 2 +- .../EmitterWithCustomValidator.netcore.g.cs | 8 +- .../EmitterWithCustomValidator.netfx.g.cs | 8 +- ...eneratedAttributesTest.netcore.lang10.g.cs | 81 +++++++++++- ...eneratedAttributesTest.netcore.lang11.g.cs | 81 +++++++++++- .../GeneratedAttributesTest.netfx.lang10.g.cs | 81 +++++++++++- .../GeneratedAttributesTest.netfx.lang11.g.cs | 81 +++++++++++- .../tests/SourceGeneration.Unit.Tests/Main.cs | 7 + .../Baselines/NetCoreApp/Validators.g.cs | 124 ++++++++++++++++-- .../Baselines/NetFX/Validators.g.cs | 120 +++++++++++++++-- .../Generated/OptionsValidationTests.cs | 38 ++++++ .../TestClasses/Models.cs | 20 +++ .../tests/TrimmingTests/ConfigureTests.cs | 7 +- 17 files changed, 713 insertions(+), 82 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs b/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs index 41609ad4b2010a..1edc4293785287 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs @@ -374,12 +374,83 @@ public void EmitCompareAttribute(string modifier, string prefix, string classNam """); } - public void EmitRangeAttribute(string modifier, string prefix, string className, string suffix) + public void EmitRangeAttribute(string modifier, string prefix, string className, string suffix, bool emitTimeSpanSupport) { OutGeneratedCodeAttribute(); string qualifiedClassName = $"{prefix}{suffix}_{className}"; + string initializationString = emitTimeSpanSupport ? + """ + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(c_minMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + } + """ + : + """ + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + """; + + string convertValue = emitTimeSpanSupport ? + """ + if (OperandType == typeof(global::System.TimeSpan)) + { + if (value is global::System.TimeSpan) + { + convertedValue = value; + } + else if (value is string) + { + if (!global::System.TimeSpan.TryParse((string)value, formatProvider, out global::System.TimeSpan timeSpanValue)) + { + return false; + } + convertedValue = timeSpanValue; + } + else + { + throw new global::System.InvalidOperationException($"A value type {value.GetType()} that is not a TimeSpan or a string has been given. This might indicate a problem with the source generator."); + } + } + else + { + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } + } + """ + : + """ + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } + """; + + + OutLn($$""" [global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Field | global::System.AttributeTargets.Parameter, AllowMultiple = false)] {{modifier}} class {{qualifiedClassName}} : {{StaticValidationAttributeType}} @@ -414,19 +485,20 @@ public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); private bool NeedToConvertMinMax { get; } private bool Initialized { get; set; } + private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + public override bool IsValid(object? value) { if (!Initialized) { if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + throw new global::System.InvalidOperationException(c_minMaxError); } if (NeedToConvertMinMax) { System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); +{{initializationString}} } int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); if (cmp > 0) @@ -448,14 +520,7 @@ public override bool IsValid(object? value) System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; object? convertedValue; - try - { - convertedValue = ConvertValue(value, formatProvider); - } - catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) - { - return false; - } +{{convertValue}} var min = (global::System.IComparable)Minimum; var max = (global::System.IComparable)Maximum; @@ -574,7 +639,7 @@ private void GenValidationAttributesClasses() } else if (attributeData.Key == _symbolHolder.RangeAttributeSymbol.Name) { - EmitRangeAttribute(_optionsSourceGenContext.ClassModifier, Emitter.StaticAttributeClassNamePrefix, attributeData.Key, _optionsSourceGenContext.Suffix); + EmitRangeAttribute(_optionsSourceGenContext.ClassModifier, Emitter.StaticAttributeClassNamePrefix, attributeData.Key, _optionsSourceGenContext.Suffix, attributeData.Value is not null); } } diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs b/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs index ab2c19de81923a..8a88ec6f2f4e65 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/Parser.cs @@ -624,10 +624,21 @@ private void TrackCompareAttributeForSubstitution(AttributeData attribute, IType private void TrackRangeAttributeForSubstitution(AttributeData attribute, ITypeSymbol memberType, ref string attributeFullQualifiedName) { ImmutableArray constructorParameters = attribute.AttributeConstructor?.Parameters ?? ImmutableArray.Empty; - SpecialType argumentSpecialType = SpecialType.None; + ITypeSymbol? argumentType = null; + bool hasTimeSpanType = false; + + ITypeSymbol typeSymbol = memberType; + if (typeSymbol.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) + { + typeSymbol = ((INamedTypeSymbol)typeSymbol).TypeArguments[0]; + } + if (constructorParameters.Length == 2) { - argumentSpecialType = constructorParameters[0].Type.SpecialType; + if (OptionsSourceGenContext.IsConvertibleBasicType(typeSymbol)) + { + argumentType = constructorParameters[0].Type; + } } else if (constructorParameters.Length == 3) { @@ -641,23 +652,25 @@ private void TrackRangeAttributeForSubstitution(AttributeData attribute, ITypeSy } } - if (argumentValue is INamedTypeSymbol namedTypeSymbol && OptionsSourceGenContext.IsConvertibleBasicType(namedTypeSymbol)) + if (argumentValue is INamedTypeSymbol namedTypeSymbol) { - argumentSpecialType = namedTypeSymbol.SpecialType; + // When type is provided as a parameter, it has to match the property type. + if (OptionsSourceGenContext.IsConvertibleBasicType(namedTypeSymbol) && typeSymbol.SpecialType == namedTypeSymbol.SpecialType) + { + argumentType = namedTypeSymbol; + } + else if (SymbolEqualityComparer.Default.Equals(namedTypeSymbol, _symbolHolder.TimeSpanSymbol) && + (SymbolEqualityComparer.Default.Equals(typeSymbol, _symbolHolder.TimeSpanSymbol) || typeSymbol.SpecialType == SpecialType.System_String)) + { + hasTimeSpanType = true; + argumentType = _symbolHolder.TimeSpanSymbol; + } } } - ITypeSymbol typeSymbol = memberType; - if (typeSymbol.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) - { - typeSymbol = ((INamedTypeSymbol)typeSymbol).TypeArguments[0]; - } - - if (argumentSpecialType != SpecialType.None && - OptionsSourceGenContext.IsConvertibleBasicType(typeSymbol) && - (constructorParameters.Length != 3 || typeSymbol.SpecialType == argumentSpecialType)) // When type is provided as a parameter, it has to match the property type. + if (argumentType is not null) { - _optionsSourceGenContext.EnsureTrackingAttribute(attribute.AttributeClass!.Name, createValue: false, out _); + _optionsSourceGenContext.EnsureTrackingAttribute(attribute.AttributeClass!.Name, createValue: hasTimeSpanType, out _); attributeFullQualifiedName = $"{Emitter.StaticGeneratedValidationAttributesClassesNamespace}.{Emitter.StaticAttributeClassNamePrefix}{_optionsSourceGenContext.Suffix}_{attribute.AttributeClass!.Name}"; } } diff --git a/src/libraries/Microsoft.Extensions.Options/gen/SymbolHolder.cs b/src/libraries/Microsoft.Extensions.Options/gen/SymbolHolder.cs index 3447a07d398305..8e7073f8ec2182 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/SymbolHolder.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/SymbolHolder.cs @@ -23,6 +23,7 @@ internal sealed record class SymbolHolder( INamedTypeSymbol IValidatableObjectSymbol, INamedTypeSymbol GenericIEnumerableSymbol, INamedTypeSymbol TypeSymbol, + INamedTypeSymbol TimeSpanSymbol, INamedTypeSymbol ValidateObjectMembersAttributeSymbol, INamedTypeSymbol ValidateEnumeratedItemsAttributeSymbol); } diff --git a/src/libraries/Microsoft.Extensions.Options/gen/SymbolLoader.cs b/src/libraries/Microsoft.Extensions.Options/gen/SymbolLoader.cs index ea556228929756..5be4932d8d6c41 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/SymbolLoader.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/SymbolLoader.cs @@ -19,6 +19,7 @@ internal static class SymbolLoader internal const string IValidatableObjectType = "System.ComponentModel.DataAnnotations.IValidatableObject"; internal const string IValidateOptionsType = "Microsoft.Extensions.Options.IValidateOptions`1"; internal const string TypeOfType = "System.Type"; + internal const string TimeSpanType = "System.TimeSpan"; internal const string ValidateObjectMembersAttribute = "Microsoft.Extensions.Options.ValidateObjectMembersAttribute"; internal const string ValidateEnumeratedItemsAttribute = "Microsoft.Extensions.Options.ValidateEnumeratedItemsAttribute"; internal const string GenericIEnumerableType = "System.Collections.Generic.IEnumerable`1"; @@ -42,6 +43,7 @@ public static bool TryLoad(Compilation compilation, out SymbolHolder? symbolHold var validateOptionsSymbol = GetSymbol(IValidateOptionsType); var genericIEnumerableSymbol = GetSymbol(GenericIEnumerableType); var typeSymbol = GetSymbol(TypeOfType); + var timeSpanSymbol = GetSymbol(TimeSpanType); var validateObjectMembersAttribute = GetSymbol(ValidateObjectMembersAttribute); var validateEnumeratedItemsAttribute = GetSymbol(ValidateEnumeratedItemsAttribute); var unconditionalSuppressMessageAttributeSymbol = GetSymbol(UnconditionalSuppressMessageAttributeType); @@ -70,6 +72,7 @@ public static bool TryLoad(Compilation compilation, out SymbolHolder? symbolHold validateOptionsSymbol == null || genericIEnumerableSymbol == null || typeSymbol == null || + timeSpanSymbol == null || validateObjectMembersAttribute == null || validateEnumeratedItemsAttribute == null) { @@ -93,6 +96,7 @@ public static bool TryLoad(Compilation compilation, out SymbolHolder? symbolHold ivalidatableObjectSymbol, genericIEnumerableSymbol, typeSymbol, + timeSpanSymbol, validateObjectMembersAttribute, validateEnumeratedItemsAttribute); diff --git a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj index abbc5d2329c5c1..e35606898e3914 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj +++ b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj @@ -5,7 +5,7 @@ true true true - 1 + 2 Provides a strongly typed way of specifying and accessing settings using dependency injection. diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netcore.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netcore.g.cs index 2c5af12c5b5f24..38bacf966df052 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netcore.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netcore.g.cs @@ -99,19 +99,21 @@ public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); private bool NeedToConvertMinMax { get; } private bool Initialized { get; set; } + private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + public override bool IsValid(object? value) { if (!Initialized) { if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + throw new global::System.InvalidOperationException(c_minMaxError); } if (NeedToConvertMinMax) { System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); } int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); if (cmp > 0) diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netfx.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netfx.g.cs index 9dc3ded5bd4624..fe77e3e6bd924a 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netfx.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netfx.g.cs @@ -97,19 +97,21 @@ public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); private bool NeedToConvertMinMax { get; } private bool Initialized { get; set; } + private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + public override bool IsValid(object? value) { if (!Initialized) { if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + throw new global::System.InvalidOperationException(c_minMaxError); } if (NeedToConvertMinMax) { System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); } int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); if (cmp > 0) diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang10.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang10.g.cs index cc9864a2619c45..7cf1fe61e1a94b 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang10.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang10.g.cs @@ -150,6 +150,26 @@ partial class OptionsUsingGeneratedAttributesValidator (builder ??= new()).AddResults(validationResults); } + context.MemberName = "P13"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P13" : $"{name}.P13"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A6); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P13, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P14"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P14" : $"{name}.P14"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A7); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P14, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } @@ -175,6 +195,16 @@ internal static class __Attributes_2C497155 internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_CompareAttribute A5 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_CompareAttribute( "P5"); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_RangeAttribute A6 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_RangeAttribute( + typeof(global::System.TimeSpan), + "00:00:00", + "23:59:59"); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_RangeAttribute A7 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_RangeAttribute( + typeof(global::System.TimeSpan), + "01:00:00", + "23:59:59"); } } namespace __OptionValidationStaticInstances @@ -395,19 +425,34 @@ public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); private bool NeedToConvertMinMax { get; } private bool Initialized { get; set; } + private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + public override bool IsValid(object? value) { if (!Initialized) { if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + throw new global::System.InvalidOperationException(c_minMaxError); } if (NeedToConvertMinMax) { System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(c_minMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + } } int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); if (cmp > 0) @@ -429,13 +474,35 @@ public override bool IsValid(object? value) System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; object? convertedValue; - try + if (OperandType == typeof(global::System.TimeSpan)) { - convertedValue = ConvertValue(value, formatProvider); + if (value is global::System.TimeSpan) + { + convertedValue = value; + } + else if (value is string) + { + if (!global::System.TimeSpan.TryParse((string)value, formatProvider, out global::System.TimeSpan timeSpanValue)) + { + return false; + } + convertedValue = timeSpanValue; + } + else + { + throw new global::System.InvalidOperationException($"A value type {value.GetType()} that is not a TimeSpan or a string has been given. This might indicate a problem with the source generator."); + } } - catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + else { - return false; + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } } var min = (global::System.IComparable)Minimum; diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang11.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang11.g.cs index 2a33e51b0b6175..f7bba046033420 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang11.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang11.g.cs @@ -150,6 +150,26 @@ partial class OptionsUsingGeneratedAttributesValidator (builder ??= new()).AddResults(validationResults); } + context.MemberName = "P13"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P13" : $"{name}.P13"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A6); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P13, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P14"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P14" : $"{name}.P14"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A7); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P14, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } @@ -175,6 +195,16 @@ file static class __Attributes internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__CompareAttribute A5 = new __OptionValidationGeneratedAttributes.__SourceGen__CompareAttribute( "P5"); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A6 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( + typeof(global::System.TimeSpan), + "00:00:00", + "23:59:59"); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A7 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( + typeof(global::System.TimeSpan), + "01:00:00", + "23:59:59"); } } namespace __OptionValidationStaticInstances @@ -395,19 +425,34 @@ public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); private bool NeedToConvertMinMax { get; } private bool Initialized { get; set; } + private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + public override bool IsValid(object? value) { if (!Initialized) { if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + throw new global::System.InvalidOperationException(c_minMaxError); } if (NeedToConvertMinMax) { System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(c_minMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + } } int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); if (cmp > 0) @@ -429,13 +474,35 @@ public override bool IsValid(object? value) System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; object? convertedValue; - try + if (OperandType == typeof(global::System.TimeSpan)) { - convertedValue = ConvertValue(value, formatProvider); + if (value is global::System.TimeSpan) + { + convertedValue = value; + } + else if (value is string) + { + if (!global::System.TimeSpan.TryParse((string)value, formatProvider, out global::System.TimeSpan timeSpanValue)) + { + return false; + } + convertedValue = timeSpanValue; + } + else + { + throw new global::System.InvalidOperationException($"A value type {value.GetType()} that is not a TimeSpan or a string has been given. This might indicate a problem with the source generator."); + } } - catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + else { - return false; + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } } var min = (global::System.IComparable)Minimum; diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang10.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang10.g.cs index 7f5eb90a202815..4b28eb159d147b 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang10.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang10.g.cs @@ -118,6 +118,26 @@ partial class OptionsUsingGeneratedAttributesValidator (builder ??= new()).AddResults(validationResults); } + context.MemberName = "P13"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P13" : $"{name}.P13"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A5); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P13, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P14"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P14" : $"{name}.P14"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes_2C497155.A6); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P14, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } @@ -139,6 +159,16 @@ internal static class __Attributes_2C497155 internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_CompareAttribute A4 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_CompareAttribute( "P5"); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_RangeAttribute A5 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_RangeAttribute( + typeof(global::System.TimeSpan), + "00:00:00", + "23:59:59"); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__2C497155_RangeAttribute A6 = new __OptionValidationGeneratedAttributes.__SourceGen__2C497155_RangeAttribute( + typeof(global::System.TimeSpan), + "01:00:00", + "23:59:59"); } } namespace __OptionValidationStaticInstances @@ -310,19 +340,34 @@ public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); private bool NeedToConvertMinMax { get; } private bool Initialized { get; set; } + private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + public override bool IsValid(object? value) { if (!Initialized) { if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + throw new global::System.InvalidOperationException(c_minMaxError); } if (NeedToConvertMinMax) { System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(c_minMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + } } int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); if (cmp > 0) @@ -344,13 +389,35 @@ public override bool IsValid(object? value) System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; object? convertedValue; - try + if (OperandType == typeof(global::System.TimeSpan)) { - convertedValue = ConvertValue(value, formatProvider); + if (value is global::System.TimeSpan) + { + convertedValue = value; + } + else if (value is string) + { + if (!global::System.TimeSpan.TryParse((string)value, formatProvider, out global::System.TimeSpan timeSpanValue)) + { + return false; + } + convertedValue = timeSpanValue; + } + else + { + throw new global::System.InvalidOperationException($"A value type {value.GetType()} that is not a TimeSpan or a string has been given. This might indicate a problem with the source generator."); + } } - catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + else { - return false; + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } } var min = (global::System.IComparable)Minimum; diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang11.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang11.g.cs index 3ab56e21320a07..4c300abc6d05bc 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang11.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang11.g.cs @@ -118,6 +118,26 @@ partial class OptionsUsingGeneratedAttributesValidator (builder ??= new()).AddResults(validationResults); } + context.MemberName = "P13"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P13" : $"{name}.P13"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A5); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P13, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P14"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingGeneratedAttributes.P14" : $"{name}.P14"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A6); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P14, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); } } @@ -139,6 +159,16 @@ file static class __Attributes internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__CompareAttribute A4 = new __OptionValidationGeneratedAttributes.__SourceGen__CompareAttribute( "P5"); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A5 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( + typeof(global::System.TimeSpan), + "00:00:00", + "23:59:59"); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A6 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( + typeof(global::System.TimeSpan), + "01:00:00", + "23:59:59"); } } namespace __OptionValidationStaticInstances @@ -310,19 +340,34 @@ public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); private bool NeedToConvertMinMax { get; } private bool Initialized { get; set; } + private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + public override bool IsValid(object? value) { if (!Initialized) { if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + throw new global::System.InvalidOperationException(c_minMaxError); } if (NeedToConvertMinMax) { System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(c_minMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + } } int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); if (cmp > 0) @@ -344,13 +389,35 @@ public override bool IsValid(object? value) System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; object? convertedValue; - try + if (OperandType == typeof(global::System.TimeSpan)) { - convertedValue = ConvertValue(value, formatProvider); + if (value is global::System.TimeSpan) + { + convertedValue = value; + } + else if (value is string) + { + if (!global::System.TimeSpan.TryParse((string)value, formatProvider, out global::System.TimeSpan timeSpanValue)) + { + return false; + } + convertedValue = timeSpanValue; + } + else + { + throw new global::System.InvalidOperationException($"A value type {value.GetType()} that is not a TimeSpan or a string has been given. This might indicate a problem with the source generator."); + } } - catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + else { - return false; + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } } var min = (global::System.IComparable)Minimum; diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs index 623251707f87ba..c72be0d72c2c0a 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs @@ -1731,6 +1731,7 @@ public async Task GeneratedAttributesTest(LanguageVersion languageVersion) #endif //NETCOREAPP string source = $$""" + using System; using System.Collections.Generic; using Microsoft.Extensions.Options; using System.ComponentModel.DataAnnotations; @@ -1782,6 +1783,12 @@ public class OptionsUsingGeneratedAttributes [MaxLengthAttribute(5)] public List? P12 { get; set; } + + [RangeAttribute(typeof(TimeSpan), "00:00:00", "23:59:59")] + public string? P13 { get; set; } + + [RangeAttribute(typeof(TimeSpan), "01:00:00", "23:59:59")] + public TimeSpan P14 { get; set; } } [OptionsValidator] diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs index 956cae26e90f6d..93c101431004ca 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs @@ -1721,6 +1721,68 @@ partial class MultipleAttributeModelValidator } } namespace TestClasses.OptionsValidation +{ + partial class OptionsUsingRangeWithTimeSpanValidator + { + /// + /// Validates a specific named options instance (or all when is ). + /// + /// The name of the options instance being validated. + /// The options instance. + /// Validation result. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", + Justification = "The created ValidationContext object is used in a way that never call reflection")] + public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.OptionsUsingRangeWithTimeSpan options) + { + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; + var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); + var validationResults = new global::System.Collections.Generic.List(); + var validationAttributes = new global::System.Collections.Generic.List(1); + + context.MemberName = "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingRangeWithTimeSpan.P1" : $"{name}.P1"; + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A19); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingRangeWithTimeSpan.P2" : $"{name}.P2"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A19); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingRangeWithTimeSpan.P3" : $"{name}.P3"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A19); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingRangeWithTimeSpan.P4" : $"{name}.P4"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A19); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); + } + } +} +namespace TestClasses.OptionsValidation { partial class RangeAttributeModelDateValidator { @@ -1742,7 +1804,7 @@ partial class RangeAttributeModelDateValidator context.MemberName = "Val"; context.DisplayName = string.IsNullOrEmpty(name) ? "RangeAttributeModelDate.Val" : $"{name}.Val"; - validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A19); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A20); if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { (builder ??= new()).AddResults(validationResults); @@ -1838,7 +1900,7 @@ partial class RegularExpressionAttributeModelValidator context.MemberName = "Val"; context.DisplayName = string.IsNullOrEmpty(name) ? "RegularExpressionAttributeModel.Val" : $"{name}.Val"; - validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A20); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A21); if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { (builder ??= new()).AddResults(validationResults); @@ -2039,6 +2101,11 @@ file static class __Attributes (int)9); internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A19 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( + typeof(global::System.TimeSpan), + "00:00:00", + "00:00:10"); + + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A20 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( typeof(global::System.DateTime), "1/2/2004", "3/4/2004") @@ -2046,7 +2113,7 @@ file static class __Attributes ParseLimitsInInvariantCulture = true }; - internal static readonly global::System.ComponentModel.DataAnnotations.RegularExpressionAttribute A20 = new global::System.ComponentModel.DataAnnotations.RegularExpressionAttribute( + internal static readonly global::System.ComponentModel.DataAnnotations.RegularExpressionAttribute A21 = new global::System.ComponentModel.DataAnnotations.RegularExpressionAttribute( "\\s"); } } @@ -2143,19 +2210,34 @@ public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); private bool NeedToConvertMinMax { get; } private bool Initialized { get; set; } + private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + public override bool IsValid(object? value) { if (!Initialized) { if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + throw new global::System.InvalidOperationException(c_minMaxError); } if (NeedToConvertMinMax) { System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(c_minMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + } } int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); if (cmp > 0) @@ -2177,13 +2259,35 @@ public override bool IsValid(object? value) System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; object? convertedValue; - try + if (OperandType == typeof(global::System.TimeSpan)) { - convertedValue = ConvertValue(value, formatProvider); + if (value is global::System.TimeSpan) + { + convertedValue = value; + } + else if (value is string) + { + if (!global::System.TimeSpan.TryParse((string)value, formatProvider, out global::System.TimeSpan timeSpanValue)) + { + return false; + } + convertedValue = timeSpanValue; + } + else + { + throw new global::System.InvalidOperationException($"A value type {value.GetType()} that is not a TimeSpan or a string has been given. This might indicate a problem with the source generator."); + } } - catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + else { - return false; + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } } var min = (global::System.IComparable)Minimum; diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs index faae7d62d9c410..3c9f86fd84f8a2 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs @@ -1637,6 +1637,66 @@ partial class MultipleAttributeModelValidator } } namespace TestClasses.OptionsValidation +{ + partial class OptionsUsingRangeWithTimeSpanValidator + { + /// + /// Validates a specific named options instance (or all when is ). + /// + /// The name of the options instance being validated. + /// The options instance. + /// Validation result. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Options.SourceGeneration", "42.42.42.42")] + public global::Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, global::TestClasses.OptionsValidation.OptionsUsingRangeWithTimeSpan options) + { + global::Microsoft.Extensions.Options.ValidateOptionsResultBuilder? builder = null; + var context = new global::System.ComponentModel.DataAnnotations.ValidationContext(options); + var validationResults = new global::System.Collections.Generic.List(); + var validationAttributes = new global::System.Collections.Generic.List(1); + + context.MemberName = "P1"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingRangeWithTimeSpan.P1" : $"{name}.P1"; + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A19); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P1, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P2"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingRangeWithTimeSpan.P2" : $"{name}.P2"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A19); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P2, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P3"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingRangeWithTimeSpan.P3" : $"{name}.P3"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A19); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P3, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + context.MemberName = "P4"; + context.DisplayName = string.IsNullOrEmpty(name) ? "OptionsUsingRangeWithTimeSpan.P4" : $"{name}.P4"; + validationResults.Clear(); + validationAttributes.Clear(); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A19); + if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.P4, context, validationResults, validationAttributes)) + { + (builder ??= new()).AddResults(validationResults); + } + + return builder is null ? global::Microsoft.Extensions.Options.ValidateOptionsResult.Success : builder.Build(); + } + } +} +namespace TestClasses.OptionsValidation { partial class RangeAttributeModelDateValidator { @@ -1746,7 +1806,7 @@ partial class RegularExpressionAttributeModelValidator context.MemberName = "Val"; context.DisplayName = string.IsNullOrEmpty(name) ? "RegularExpressionAttributeModel.Val" : $"{name}.Val"; - validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A19); + validationAttributes.Add(global::__OptionValidationStaticInstances.__Attributes.A20); if (!global::System.ComponentModel.DataAnnotations.Validator.TryValidateValue(options.Val, context, validationResults, validationAttributes)) { (builder ??= new()).AddResults(validationResults); @@ -1940,7 +2000,12 @@ file static class __Attributes (int)5, (int)9); - internal static readonly global::System.ComponentModel.DataAnnotations.RegularExpressionAttribute A19 = new global::System.ComponentModel.DataAnnotations.RegularExpressionAttribute( + internal static readonly __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute A19 = new __OptionValidationGeneratedAttributes.__SourceGen__RangeAttribute( + typeof(global::System.TimeSpan), + "00:00:00", + "00:00:10"); + + internal static readonly global::System.ComponentModel.DataAnnotations.RegularExpressionAttribute A20 = new global::System.ComponentModel.DataAnnotations.RegularExpressionAttribute( "\\s"); } } @@ -2037,19 +2102,34 @@ public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); private bool NeedToConvertMinMax { get; } private bool Initialized { get; set; } + private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + public override bool IsValid(object? value) { if (!Initialized) { if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + throw new global::System.InvalidOperationException(c_minMaxError); } if (NeedToConvertMinMax) { System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException("The minimum and maximum values must be set to valid values."); + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(c_minMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + } } int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); if (cmp > 0) @@ -2071,13 +2151,35 @@ public override bool IsValid(object? value) System.Globalization.CultureInfo formatProvider = ConvertValueInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; object? convertedValue; - try + if (OperandType == typeof(global::System.TimeSpan)) { - convertedValue = ConvertValue(value, formatProvider); + if (value is global::System.TimeSpan) + { + convertedValue = value; + } + else if (value is string) + { + if (!global::System.TimeSpan.TryParse((string)value, formatProvider, out global::System.TimeSpan timeSpanValue)) + { + return false; + } + convertedValue = timeSpanValue; + } + else + { + throw new global::System.InvalidOperationException($"A value type {value.GetType()} that is not a TimeSpan or a string has been given. This might indicate a problem with the source generator."); + } } - catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + else { - return false; + try + { + convertedValue = ConvertValue(value, formatProvider); + } + catch (global::System.Exception e) when (e is global::System.FormatException or global::System.InvalidCastException or global::System.NotSupportedException) + { + return false; + } } var min = (global::System.IComparable)Minimum; diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/OptionsValidationTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/OptionsValidationTests.cs index 49941010f1ace6..4f9770ce7a17ca 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/OptionsValidationTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/OptionsValidationTests.cs @@ -4,6 +4,7 @@ using System; using System.ComponentModel.DataAnnotations; using System.Globalization; +using System.Linq; using Microsoft.Extensions.Options; using TestClasses.OptionsValidation; using Xunit; @@ -439,4 +440,41 @@ public void AttributePropertyModelTestOnErrorMessageResource() var modelValidator = new AttributePropertyModelValidator(); Utils.VerifyValidateOptionsResult(modelValidator.Validate(nameof(validModel), validModel), 1); } + + [Fact] + public void OptionsUsingRangeWithTimeSpanValid() + { + var validModel = new OptionsUsingRangeWithTimeSpan + { + P1 = TimeSpan.FromSeconds(1), + P2 = TimeSpan.FromSeconds(2), + P3 = "00:00:03", + P4 = "00:00:04", + }; + + var modelValidator = new OptionsUsingRangeWithTimeSpanValidator(); + ValidateOptionsResult result = modelValidator.Validate(nameof(validModel), validModel); + Assert.Equal(ValidateOptionsResult.Success, result); + + var invalidModel = new OptionsUsingRangeWithTimeSpan + { + P1 = TimeSpan.FromSeconds(11), + P2 = TimeSpan.FromSeconds(-2), + P3 = "01:00:03", + P4 = "02:00:04", + }; + result = modelValidator.Validate(nameof(invalidModel), invalidModel); + Assert.Equal(4, result.Failures.Count()); + + // null values pass the validation! + invalidModel = new OptionsUsingRangeWithTimeSpan + { + P1 = TimeSpan.FromSeconds(100), + P2 = null, + P3 = "00:01:00", + P4 = null, + }; + result = modelValidator.Validate(nameof(invalidModel), invalidModel); + Assert.Equal(2, result.Failures.Count()); + } } diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/TestClasses/Models.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/TestClasses/Models.cs index 240163023eb932..c245ebd783bdcf 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/TestClasses/Models.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/TestClasses/Models.cs @@ -179,6 +179,21 @@ public class ComplexModel public TypeWithoutOptionsValidator? ValWithoutOptionsValidator { get; set; } } + public class OptionsUsingRangeWithTimeSpan + { + [Range(typeof(TimeSpan), "00:00:00", "00:00:10")] + public TimeSpan P1 { get; set; } + + [Range(typeof(TimeSpan), "00:00:00", "00:00:10")] + public TimeSpan? P2 { get; set; } + + [Range(typeof(TimeSpan), "00:00:00", "00:00:10")] + public string P3 { get; set; } + + [Range(typeof(TimeSpan), "00:00:00", "00:00:10")] + public string? P4 { get; set; } + } + [OptionsValidator] public partial class RequiredAttributeModelValidator : IValidateOptions { @@ -248,4 +263,9 @@ public partial class LeafModelValidator : IValidateOptions internal sealed partial class ComplexModelValidator : IValidateOptions { } + + [OptionsValidator] + internal sealed partial class OptionsUsingRangeWithTimeSpanValidator : IValidateOptions + { + } } diff --git a/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/ConfigureTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/ConfigureTests.cs index 7a39d8a8810fd3..90179563300b92 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/ConfigureTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/TrimmingTests/ConfigureTests.cs @@ -46,7 +46,8 @@ optionsC is null || P2 = new List { "1234", "12345" }, P3 = "123456", P4 = "12345", - P5 = 7 + P5 = 7, + P6 = TimeSpan.FromSeconds(5), }; ValidateOptionsResult result = localOptionsValidator.Validate("", optionsUsingValidationAttributes); @@ -113,6 +114,10 @@ public class OptionsUsingValidationAttributes [Range(1, 10, MinimumIsExclusive = true, MaximumIsExclusive = true)] public int P5 { get; set; } + + [Range(typeof(TimeSpan), "00:00:00", "00:00:10")] + public TimeSpan P6 { get; set; } + } [OptionsValidator] From 7681675e831c3282284ce72f5625a3b70d09962f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 17:49:58 -0800 Subject: [PATCH 485/783] Update dependencies from https://github.com/dotnet/roslyn build 20231116.2 (#94877) Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.Net.Compilers.Toolset From Version 4.8.0-7.23558.1 -> To Version 4.8.0-7.23566.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 7ee1f4fa7f1137..ef657e373a85e4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -362,18 +362,18 @@ https://github.com/dotnet/runtime-assets 59430f9a34c6fba965d1941a7eb5df08ed24cc2d - + https://github.com/dotnet/roslyn - e091728607ca0fc9efca55ccfb3e59259c6b5a0a + 7b75981cf3bd520b86ec4ed00ec156c8bc48e4eb - + https://github.com/dotnet/roslyn - e091728607ca0fc9efca55ccfb3e59259c6b5a0a + 7b75981cf3bd520b86ec4ed00ec156c8bc48e4eb - + https://github.com/dotnet/roslyn - e091728607ca0fc9efca55ccfb3e59259c6b5a0a + 7b75981cf3bd520b86ec4ed00ec156c8bc48e4eb https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index ad201088988efe..c03256d63323af 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -44,9 +44,9 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.8.0-7.23558.1 - 4.8.0-7.23558.1 - 4.8.0-7.23558.1 + 4.8.0-7.23566.2 + 4.8.0-7.23566.2 + 4.8.0-7.23566.2 - 8.0.0-beta.23558.5 - 8.0.0-beta.23558.5 - 8.0.0-beta.23558.5 - 8.0.0-beta.23558.5 - 8.0.0-beta.23558.5 - 8.0.0-beta.23558.5 - 8.0.0-beta.23558.5 - 8.0.0-beta.23558.5 - 8.0.0-beta.23558.5 - 8.0.0-beta.23558.5 - 8.0.0-beta.23558.5 - 8.0.0-beta.23558.5 - 8.0.0-beta.23558.5 - 8.0.0-beta.23558.5 + 8.0.0-beta.23566.1 + 8.0.0-beta.23566.1 + 8.0.0-beta.23566.1 + 8.0.0-beta.23566.1 + 8.0.0-beta.23566.1 + 8.0.0-beta.23566.1 + 8.0.0-beta.23566.1 + 8.0.0-beta.23566.1 + 8.0.0-beta.23566.1 + 8.0.0-beta.23566.1 + 8.0.0-beta.23566.1 + 8.0.0-beta.23566.1 + 8.0.0-beta.23566.1 + 8.0.0-beta.23566.1 1.0.0-prerelease.23565.3 1.0.0-prerelease.23565.3 From 4a8e14aeec3f1c1415a920485260e9a5e98f85ca Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 18:20:46 -0800 Subject: [PATCH 487/783] Update dependencies from https://github.com/dotnet/emsdk build 20231116.4 (#94884) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.1-servicing.23563.2 -> To Version 8.0.1-servicing.23566.4 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 2daf70bbead041..579d3b53ca8f20 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + - - - - - - - - + - + 8.0.0-rc.1.23406.6 8.0.0-preview.7.23325.2 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 6.0.0 1.1.1 @@ -222,20 +222,20 @@ 2.2.3 8.0.0-alpha.1.23527.1 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 - 16.0.5-alpha.1.23558.12 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 + 16.0.5-alpha.1.23566.1 3.1.7 1.0.406601 From a8d8771f3d02772f5e5fa1ca1a94a6b952fb7f66 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Lopez Date: Mon, 20 Nov 2023 16:54:14 +0000 Subject: [PATCH 491/783] [8.0] Always build ILLink.Tasks --- src/tools/illink/src/ILLink.Tasks/ILLink.Tasks.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/illink/src/ILLink.Tasks/ILLink.Tasks.csproj b/src/tools/illink/src/ILLink.Tasks/ILLink.Tasks.csproj index 1199101f63825c..33aeb674da6be1 100644 --- a/src/tools/illink/src/ILLink.Tasks/ILLink.Tasks.csproj +++ b/src/tools/illink/src/ILLink.Tasks/ILLink.Tasks.csproj @@ -12,8 +12,8 @@ disable true Microsoft.NET.ILLink.Tasks - - false + + true true - true + + false + true true + + + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 15cfbc281eb892..e9a081259ef472 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -354,9 +354,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 5914dbda1860830a56179692058d94c9f615deda - + https://github.com/dotnet/hotreload-utils - 8e108a21d0c7d8fa2050a1bdd4d4ba50d2b8df13 + 5524f726f92ef862b415793758cebbd2a1950b70 https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index 9f818a66683036..e89c94c55e6275 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -186,7 +186,7 @@ 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 - 8.0.0-alpha.0.23563.1 + 8.0.0-alpha.0.23570.2 2.4.2 1.0.0 2.4.5 From 7dc2e67ca495b479f1081a5e193d10b7a396bae8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:05:17 -0800 Subject: [PATCH 494/783] Re-check for existance of syncblock in HasInteropInfo - in case the syncblock is gone. (#94649) Co-authored-by: vsadov <8218165+VSadov@users.noreply.github.com> --- src/coreclr/vm/weakreferencenative.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/vm/weakreferencenative.cpp b/src/coreclr/vm/weakreferencenative.cpp index f9a7b9a6bfc01b..bb0ac10906ef00 100644 --- a/src/coreclr/vm/weakreferencenative.cpp +++ b/src/coreclr/vm/weakreferencenative.cpp @@ -172,8 +172,7 @@ FCIMPL1(FC_BOOL_RET, ComAwareWeakReferenceNative::HasInteropInfo, Object* pObjec _ASSERTE(pObject != nullptr); SyncBlock* pSyncBlock = pObject->PassiveGetSyncBlock(); - _ASSERTE(pSyncBlock != nullptr); - return pSyncBlock->GetInteropInfoNoCreate() != nullptr; + return pSyncBlock != nullptr && pSyncBlock->GetInteropInfoNoCreate() != nullptr; } FCIMPLEND From b126b9a50434ffb164b1e2db21ba85915db38c8e Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Tue, 21 Nov 2023 11:05:52 -0800 Subject: [PATCH 495/783] Store entry assembly path for easy access for diagnostics (#95045) - Add `g_EntryAssemblyPath` global variable holding the full path to the entry assembly - Set right before loading the entry assembly (so also before startup hooks are run) - NULL if there is no entry assembly - Ensure value is included dumps - For triage dumps, the dumped value is updated to only be the assembly file name instead of the full path --- src/coreclr/debug/daccess/enummem.cpp | 28 +++++++++++++++++++++++++++ src/coreclr/inc/daccess.h | 6 ++++-- src/coreclr/inc/dacvars.h | 2 ++ src/coreclr/vm/corhost.cpp | 9 +++++++++ src/coreclr/vm/vars.cpp | 2 ++ src/coreclr/vm/vars.hpp | 3 +++ 6 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/coreclr/debug/daccess/enummem.cpp b/src/coreclr/debug/daccess/enummem.cpp index 44d98beec2de38..7856a1ff0c096e 100644 --- a/src/coreclr/debug/daccess/enummem.cpp +++ b/src/coreclr/debug/daccess/enummem.cpp @@ -224,6 +224,34 @@ HRESULT ClrDataAccess::EnumMemCLRStatic(IN CLRDataEnumMemoryFlags flags) ReportMem(g_gcDacGlobals.GetAddr(), sizeof(GcDacVars)); + PTR_WSTR entryAssemblyPath = (PTR_WSTR)g_EntryAssemblyPath; + entryAssemblyPath.EnumMem(); + + // Triage dumps must not include full paths (PII data). Replace entry assembly path with file name only. + if (flags == CLRDATA_ENUM_MEM_TRIAGE) + { + WCHAR* path = entryAssemblyPath; + if (path != NULL) + { + size_t pathLen = u16_strlen(path) + 1; + + // Get the file name based on the last directory separator + const WCHAR* name = u16_strrchr(path, DIRECTORY_SEPARATOR_CHAR_W); + if (name != NULL) + { + name += 1; + size_t len = u16_strlen(name) + 1; + wcscpy_s(path, len, name); + + // Null out the rest of the buffer + for (size_t i = len; i < pathLen; ++i) + path[i] = W('\0'); + + DacUpdateMemoryRegion(entryAssemblyPath.GetAddr(), pathLen, (BYTE*)path); + } + } + } + // We need all of the dac variables referenced by the GC DAC global struct. // This struct contains pointers to pointers, so we first dereference the pointers // to obtain the location of the variable that's reported. diff --git a/src/coreclr/inc/daccess.h b/src/coreclr/inc/daccess.h index 3ca0ca40ee42e5..54ce86551caee9 100644 --- a/src/coreclr/inc/daccess.h +++ b/src/coreclr/inc/daccess.h @@ -574,6 +574,8 @@ #include "crosscomp.h" #endif +#include + // Information stored in the DAC table of interest to the DAC implementation // Note that this information is shared between all instantiations of ClrDataAccess, so initialize // it just once in code:ClrDataAccess.GetDacGlobals (rather than use fields in ClrDataAccess); @@ -1493,10 +1495,10 @@ class __Str16Ptr : public __DPtr } void EnumMem(void) const { - char* str = DacInstantiateStringW(m_addr, maxChars, false); + WCHAR* str = DacInstantiateStringW(m_addr, maxChars, false); if (str) { - DacEnumMemoryRegion(m_addr, strlen(str) + 1); + DacEnumMemoryRegion(m_addr, u16_strlen(str) + 1); } } }; diff --git a/src/coreclr/inc/dacvars.h b/src/coreclr/inc/dacvars.h index 8fcc1cced7d439..030c18f0b9db20 100644 --- a/src/coreclr/inc/dacvars.h +++ b/src/coreclr/inc/dacvars.h @@ -231,5 +231,7 @@ DEFINE_DACVAR(SIZE_T, dac__g_clrNotificationArguments, ::g_clrNotificationArgume DEFINE_DACVAR(bool, dac__g_metadataUpdatesApplied, ::g_metadataUpdatesApplied) #endif +DEFINE_DACVAR(PTR_WSTR, dac__g_EntryAssemblyPath, ::g_EntryAssemblyPath) + #undef DEFINE_DACVAR #undef DEFINE_DACVAR_NO_DUMP diff --git a/src/coreclr/vm/corhost.cpp b/src/coreclr/vm/corhost.cpp index bb32e93cd0961a..b85331e00ce8d2 100644 --- a/src/coreclr/vm/corhost.cpp +++ b/src/coreclr/vm/corhost.cpp @@ -310,6 +310,15 @@ HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId, _ASSERTE (!pThread->PreemptiveGCDisabled()); + if (g_EntryAssemblyPath == NULL) + { + // Store the entry assembly path for diagnostic purposes (for example, dumps) + size_t len = u16_strlen(pwzAssemblyPath) + 1; + NewArrayHolder path { new WCHAR[len] }; + wcscpy_s(path, len, pwzAssemblyPath); + g_EntryAssemblyPath = path.Extract(); + } + Assembly *pAssembly = AssemblySpec::LoadAssembly(pwzAssemblyPath); #if defined(FEATURE_MULTICOREJIT) diff --git a/src/coreclr/vm/vars.cpp b/src/coreclr/vm/vars.cpp index 85737057d2f9c2..00840f9195651e 100644 --- a/src/coreclr/vm/vars.cpp +++ b/src/coreclr/vm/vars.cpp @@ -106,6 +106,8 @@ GVAL_IMPL_INIT(DWORD, g_debuggerWordTLSIndex, TLS_OUT_OF_INDEXES); #endif GVAL_IMPL_INIT(DWORD, g_TlsIndex, TLS_OUT_OF_INDEXES); +GVAL_IMPL_INIT(PTR_WSTR, g_EntryAssemblyPath, NULL); + #ifndef DACCESS_COMPILE // @TODO - PROMOTE. diff --git a/src/coreclr/vm/vars.hpp b/src/coreclr/vm/vars.hpp index dd92ee7b12fde3..03762a24e695d7 100644 --- a/src/coreclr/vm/vars.hpp +++ b/src/coreclr/vm/vars.hpp @@ -389,6 +389,9 @@ GVAL_DECL(DWORD, g_debuggerWordTLSIndex); #endif GVAL_DECL(DWORD, g_TlsIndex); +// Full path to the managed entry assembly - stored for ease of identifying the entry asssembly for diagnostics +GVAL_DECL(PTR_WSTR, g_EntryAssemblyPath); + // Global System Information extern SYSTEM_INFO g_SystemInfo; From f7652ef0e03e2795d112580ddc8f6d8a39db4da2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:04:03 -0800 Subject: [PATCH 496/783] [release/8.0-staging] Fix Vector512.CopyTo (#95026) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix Vector512.CopyTo * Also unify Vector * Handle float vectors too * Fix legacy vectors * Simplify the change * Update Vector_1.cs * Add tests * Fix build --------- Co-authored-by: Michał Petryka <35800402+MichalPetryka@users.noreply.github.com> --- .../src/System/Runtime/Intrinsics/Vector512.cs | 6 ++---- .../tests/Vectors/Vector128Tests.cs | 16 ++++++++++++++++ .../tests/Vectors/Vector256Tests.cs | 16 ++++++++++++++++ .../tests/Vectors/Vector512Tests.cs | 16 ++++++++++++++++ .../tests/Vectors/Vector64Tests.cs | 16 ++++++++++++++++ 5 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs index f95c2d34c3c5f1..824440a5bf2a7b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs @@ -441,8 +441,7 @@ public static void CopyTo(this Vector512 vector, T[] destination) ThrowHelper.ThrowArgumentException_DestinationTooShort(); } - ref byte address = ref Unsafe.As(ref MemoryMarshal.GetArrayDataReference(destination)); - Unsafe.WriteUnaligned(ref address, vector); + Unsafe.WriteUnaligned(ref Unsafe.As(ref destination[0]), vector); } /// Copies a to a given array starting at the specified index. @@ -468,8 +467,7 @@ public static void CopyTo(this Vector512 vector, T[] destination, int star ThrowHelper.ThrowArgumentException_DestinationTooShort(); } - ref byte address = ref Unsafe.As(ref MemoryMarshal.GetArrayDataReference(destination)); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref address, startIndex), vector); + Unsafe.WriteUnaligned(ref Unsafe.As(ref destination[startIndex]), vector); } /// Copies a to a given span. diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs index 3894d835a60b08..cf1f6cec9be38d 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs @@ -4517,6 +4517,22 @@ public void Vector128SingleEqualsNonCanonicalNaNTest() } } + [Fact] + public void Vector128SingleCopyToTest() + { + float[] array = new float[4]; + Vector128.Create(2.0f).CopyTo(array); + Assert.True(array.AsSpan().SequenceEqual([2.0f, 2.0f, 2.0f, 2.0f])); + } + + [Fact] + public void Vector128SingleCopyToOffsetTest() + { + float[] array = new float[5]; + Vector128.Create(2.0f).CopyTo(array, 1); + Assert.True(array.AsSpan().SequenceEqual([0.0f, 2.0f, 2.0f, 2.0f, 2.0f])); + } + [Fact] public void IsSupportedByte() => TestIsSupported(); diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs index 6bdc86bc46f437..95c05c50310fe3 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs @@ -5539,6 +5539,22 @@ public void Vector256SingleEqualsNonCanonicalNaNTest() } } + [Fact] + public void Vector256SingleCopyToTest() + { + float[] array = new float[8]; + Vector256.Create(2.0f).CopyTo(array); + Assert.True(array.AsSpan().SequenceEqual([2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f])); + } + + [Fact] + public void Vector256SingleCopyToOffsetTest() + { + float[] array = new float[9]; + Vector256.Create(2.0f).CopyTo(array, 1); + Assert.True(array.AsSpan().SequenceEqual([0.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f])); + } + [Fact] public void IsSupportedByte() => TestIsSupported(); diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs index 4922cf8cab8583..2b97f49d914981 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs @@ -5016,6 +5016,22 @@ public void Vector512SingleEqualsNonCanonicalNaNTest() } } + [Fact] + public void Vector512SingleCopyToTest() + { + float[] array = new float[16]; + Vector512.Create(2.0f).CopyTo(array); + Assert.True(array.AsSpan().SequenceEqual([2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f])); + } + + [Fact] + public void Vector512SingleCopyToOffsetTest() + { + float[] array = new float[17]; + Vector512.Create(2.0f).CopyTo(array, 1); + Assert.True(array.AsSpan().SequenceEqual([0.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f])); + } + [Fact] public void IsSupportedByte() => TestIsSupported(); diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs index 8596f3b0ff7861..46aed6abbb06a8 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs @@ -3937,6 +3937,22 @@ public void Vector64SingleEqualsNonCanonicalNaNTest() } } + [Fact] + public void Vector64SingleCopyToTest() + { + float[] array = new float[2]; + Vector64.Create(2.0f).CopyTo(array); + Assert.True(array.AsSpan().SequenceEqual([2.0f, 2.0f])); + } + + [Fact] + public void Vector64SingleCopyToOffsetTest() + { + float[] array = new float[3]; + Vector64.Create(2.0f).CopyTo(array, 1); + Assert.True(array.AsSpan().SequenceEqual([0.0f, 2.0f, 2.0f])); + } + [Fact] public void IsSupportedByte() => TestIsSupported(); From 07cff1c67827e5a0a37984e6d66ad0c89c9cf59c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:04:52 -0800 Subject: [PATCH 497/783] Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20231115.1 (#95008) Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23556.3 -> To Version 8.0.0-alpha.1.23565.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e9a081259ef472..ab9af74ea01fee 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -99,9 +99,9 @@ d75f77cb8eb87322453288a22ce9b2d880bd1cb1 - + https://github.com/dotnet/source-build-reference-packages - fa4c0e8f53ef2541a23e519af4dfb86cb88e1bae + 95f83e27806330fec09edd96e06bba3acabe3f35 From 9b0f22f6aa2c2ad07312441370ec0ae08fdc63e2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:07:01 -0800 Subject: [PATCH 498/783] [release/8.0-staging] Permit MD5 regardless of FIPS configuration for Linux (#94979) * Re-enable MD5 for FIPS with OpenSSL 3 * Permit MD5 on OpenSSL 1.1.1 regardless of FIPS * Fix build --------- Co-authored-by: Kevin Jones --- .../opensslshim.h | 4 ++ .../osslcompat_30.h | 1 + .../pal_evp.c | 39 ++++++++++++++++++- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index 9abc53338796e0..cf10d2f794987d 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -347,6 +347,8 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len); REQUIRED_FUNCTION(EVP_MD_CTX_copy_ex) \ RENAMED_FUNCTION(EVP_MD_CTX_free, EVP_MD_CTX_destroy) \ RENAMED_FUNCTION(EVP_MD_CTX_new, EVP_MD_CTX_create) \ + REQUIRED_FUNCTION(EVP_MD_CTX_set_flags) \ + LIGHTUP_FUNCTION(EVP_MD_fetch) \ RENAMED_FUNCTION(EVP_MD_get_size, EVP_MD_size) \ REQUIRED_FUNCTION(EVP_PKCS82PKEY) \ REQUIRED_FUNCTION(EVP_PKEY2PKCS8) \ @@ -842,6 +844,8 @@ FOR_ALL_OPENSSL_FUNCTIONS #define EVP_MD_CTX_copy_ex EVP_MD_CTX_copy_ex_ptr #define EVP_MD_CTX_free EVP_MD_CTX_free_ptr #define EVP_MD_CTX_new EVP_MD_CTX_new_ptr +#define EVP_MD_CTX_set_flags EVP_MD_CTX_set_flags_ptr +#define EVP_MD_fetch EVP_MD_fetch_ptr #define EVP_MD_get_size EVP_MD_get_size_ptr #define EVP_PKCS82PKEY EVP_PKCS82PKEY_ptr #define EVP_PKEY2PKCS8 EVP_PKEY2PKCS8_ptr diff --git a/src/native/libs/System.Security.Cryptography.Native/osslcompat_30.h b/src/native/libs/System.Security.Cryptography.Native/osslcompat_30.h index 095dd3176e7aa4..5167f2a0fbcd11 100644 --- a/src/native/libs/System.Security.Cryptography.Native/osslcompat_30.h +++ b/src/native/libs/System.Security.Cryptography.Native/osslcompat_30.h @@ -19,6 +19,7 @@ void ERR_new(void); void ERR_set_debug(const char *file, int line, const char *func); void ERR_set_error(int lib, int reason, const char *fmt, ...); int EVP_CIPHER_get_nid(const EVP_CIPHER *e); +EVP_MD* EVP_MD_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties); int EVP_MD_get_size(const EVP_MD* md); int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX* ctx, int bits); int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX* ctx, const EVP_MD* md); diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp.c b/src/native/libs/System.Security.Cryptography.Native/pal_evp.c index cadc29a67000dd..b623df6b0b1784 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp.c @@ -1,13 +1,41 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#include "openssl.h" #include "pal_evp.h" #include "pal_utilities.h" #include +#include #define SUCCESS 1 +static const EVP_MD* g_evpFetchMd5 = NULL; +static pthread_once_t g_evpFetch = PTHREAD_ONCE_INIT; + +static void EnsureFetchEvpMdAlgorithms(void) +{ + // This is called from a pthread_once - this method should not be called directly. + +#ifdef NEED_OPENSSL_3_0 + if (API_EXISTS(EVP_MD_fetch)) + { + ERR_clear_error(); + + // Try to fetch an MD5 implementation that will work regardless if + // FIPS is enforced or not. + g_evpFetchMd5 = EVP_MD_fetch(NULL, "MD5", "-fips"); + } +#endif + + // No error queue impact. + // If EVP_MD_fetch is unavailable, use the implicit loader. If it failed, use the implicit loader as a last resort. + if (g_evpFetchMd5 == NULL) + { + g_evpFetchMd5 = EVP_md5(); + } +} + EVP_MD_CTX* CryptoNative_EvpMdCtxCreate(const EVP_MD* type) { ERR_clear_error(); @@ -23,6 +51,13 @@ EVP_MD_CTX* CryptoNative_EvpMdCtxCreate(const EVP_MD* type) return NULL; } + // For OpenSSL 1.x, set the non-FIPS allow flag for MD5. OpenSSL 3 does this differently with EVP_MD_fetch + // and no longer has this flag. + if (CryptoNative_OpenSslVersionNumber() < OPENSSL_VERSION_3_0_RTM && type == EVP_md5()) + { + EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + } + int ret = EVP_DigestInit_ex(ctx, type, NULL); if (!ret) { @@ -230,8 +265,8 @@ int32_t CryptoNative_EvpMdSize(const EVP_MD* md) const EVP_MD* CryptoNative_EvpMd5(void) { - // No error queue impact. - return EVP_md5(); + pthread_once(&g_evpFetch, EnsureFetchEvpMdAlgorithms); + return g_evpFetchMd5; } const EVP_MD* CryptoNative_EvpSha1(void) From 3e1f6722fead808a3e9ba41399f334a20eefddfa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:07:30 -0800 Subject: [PATCH 499/783] [release/8.0-staging] [mono][interp] Fix incorrect stack type information (#94966) * [mono][interp] Don't link bblock after rethrow * [mono][interp] Small code refactoring * [mono][interp] Fix incorrect stack type information Assume we have a basic block that it is a forward branch destination, then its stack type information will be initialized at the moment of branching (let's say there is a value of type Obj1). If later in the code we reach this bblock by falling through (let's say the current stack contains a value of Obj2), the current stack state will be copied from the original state, with the type Obj1. If later on we do a virtual call, we will try to devirtualize it as if this is Obj1 which is incorrect, since the fallthrough path would produce an Obj2. This commit adds missing checks for removing type information if we have different types on the execution types on incoming paths. --------- Co-authored-by: Vlad Brezae --- src/mono/mono/mini/interp/transform.c | 41 ++++++++++++++++----------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index d4b7a94d8a4d98..67034e9c59c81c 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -788,28 +788,32 @@ fixup_newbb_stack_locals (TransformData *td, InterpBasicBlock *newbb) } } +static void +merge_stack_type_information (StackInfo *state1, StackInfo *state2, int len) +{ + // Discard type information if we have type conflicts for stack contents + for (int i = 0; i < len; i++) { + if (state1 [i].klass != state2 [i].klass) { + state1 [i].klass = NULL; + state2 [i].klass = NULL; + } + } +} + // Initializes stack state at entry to bb, based on the current stack state static void init_bb_stack_state (TransformData *td, InterpBasicBlock *bb) { - // FIXME If already initialized, then we need to generate mov to the registers in the state. // Check if already initialized if (bb->stack_height >= 0) { - // Discard type information if we have type conflicts for stack contents - for (int i = 0; i < bb->stack_height; i++) { - if (bb->stack_state [i].klass != td->stack [i].klass) { - bb->stack_state [i].klass = NULL; - td->stack [i].klass = NULL; - } + merge_stack_type_information (td->stack, bb->stack_state, bb->stack_height); + } else { + bb->stack_height = GPTRDIFF_TO_INT (td->sp - td->stack); + if (bb->stack_height > 0) { + int size = bb->stack_height * sizeof (td->stack [0]); + bb->stack_state = (StackInfo*)mono_mempool_alloc (td->mempool, size); + memcpy (bb->stack_state, td->stack, size); } - return; - } - - bb->stack_height = GPTRDIFF_TO_INT (td->sp - td->stack); - if (bb->stack_height > 0) { - int size = bb->stack_height * sizeof (td->stack [0]); - bb->stack_state = (StackInfo*)mono_mempool_alloc (td->mempool, size); - memcpy (bb->stack_state, td->stack, size); } } @@ -5010,8 +5014,12 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, td->cbb = new_bb; if (new_bb->stack_height >= 0) { - if (new_bb->stack_height > 0) + if (new_bb->stack_height > 0) { + if (link_bblocks) + merge_stack_type_information (td->stack, new_bb->stack_state, new_bb->stack_height); + // This is relevant only for copying the vars associated with the values on the stack memcpy (td->stack, new_bb->stack_state, new_bb->stack_height * sizeof(td->stack [0])); + } td->sp = td->stack + new_bb->stack_height; } else if (link_bblocks) { /* This bblock is not branched to. Initialize its stack state */ @@ -7550,6 +7558,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, interp_ins_set_sreg (td->last_ins, td->sp [0].local); td->sp = td->stack; ++td->ip; + link_bblocks = FALSE; break; case CEE_MONO_LD_DELEGATE_METHOD_PTR: From adbb6ae8005674b3f85ef1868d1f0593ae547971 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:10:37 -0800 Subject: [PATCH 500/783] [release/8.0-staging] Update dependencies from dotnet/runtime-assets (#94919) * Update dependencies from https://github.com/dotnet/runtime-assets build 20231116.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23558.5 -> To Version 8.0.0-beta.23566.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20231116.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23558.5 -> To Version 8.0.0-beta.23566.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20231116.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23558.5 -> To Version 8.0.0-beta.23566.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20231116.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23558.5 -> To Version 8.0.0-beta.23566.1 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Larry Ewing From fa3da7ef565f448e43c85af00d111d813e91c4c6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:13:29 -0800 Subject: [PATCH 501/783] [release/8.0] Update dependencies from dnceng/internal/dotnet-optimization (#94916) * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231116.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23565.3 -> To Version 1.0.0-prerelease.23566.3 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231116.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23565.3 -> To Version 1.0.0-prerelease.23566.3 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231116.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23565.3 -> To Version 1.0.0-prerelease.23566.3 * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20231116.3 optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime , optimization.PGO.CoreCLR From Version 1.0.0-prerelease.23565.3 -> To Version 1.0.0-prerelease.23566.3 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e4f71acfe69ea3..5d1152d09630bb 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -338,21 +338,21 @@ https://github.com/dotnet/arcade 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 5914dbda1860830a56179692058d94c9f615deda + 67613417f5e1af250e6ddfba79f8f2885d8e90fb - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 5914dbda1860830a56179692058d94c9f615deda + 67613417f5e1af250e6ddfba79f8f2885d8e90fb - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 5914dbda1860830a56179692058d94c9f615deda + 67613417f5e1af250e6ddfba79f8f2885d8e90fb - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 5914dbda1860830a56179692058d94c9f615deda + 67613417f5e1af250e6ddfba79f8f2885d8e90fb https://github.com/dotnet/hotreload-utils @@ -392,13 +392,13 @@ e9d13cbe7e8c1d52ce276a8655f52a87e1017c46 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 5914dbda1860830a56179692058d94c9f615deda + 67613417f5e1af250e6ddfba79f8f2885d8e90fb - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 5914dbda1860830a56179692058d94c9f615deda + 67613417f5e1af250e6ddfba79f8f2885d8e90fb diff --git a/eng/Versions.props b/eng/Versions.props index 9f818a66683036..2dd0c6b66cff66 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23566.1 8.0.0-beta.23566.1 - 1.0.0-prerelease.23565.3 - 1.0.0-prerelease.23565.3 - 1.0.0-prerelease.23565.3 - 1.0.0-prerelease.23565.3 - 1.0.0-prerelease.23565.3 - 1.0.0-prerelease.23565.3 + 1.0.0-prerelease.23566.3 + 1.0.0-prerelease.23566.3 + 1.0.0-prerelease.23566.3 + 1.0.0-prerelease.23566.3 + 1.0.0-prerelease.23566.3 + 1.0.0-prerelease.23566.3 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From 1aa09ef4ec76baf24c5fc3371e2c83cd1607413b Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Tue, 21 Nov 2023 21:15:03 +0100 Subject: [PATCH 502/783] [release/8.0-staging] Use live M.Bcl.AsyncInterfaces dependency (#94459) * [release/8.0-staging] Use live M.Bcl.AsyncInterfaces dependency Manual backport of https://github.com/dotnet/runtime/pull/94451 * Update Microsoft.Bcl.TimeProvider.csproj * Update Microsoft.Bcl.TimeProvider.csproj * Update Microsoft.Bcl.TimeProvider.csproj --- .../ref/Microsoft.Bcl.TimeProvider.csproj | 2 +- .../src/Microsoft.Bcl.TimeProvider.csproj | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Bcl.TimeProvider/ref/Microsoft.Bcl.TimeProvider.csproj b/src/libraries/Microsoft.Bcl.TimeProvider/ref/Microsoft.Bcl.TimeProvider.csproj index 11d55537a3a3b3..45eebd41ee4e3f 100644 --- a/src/libraries/Microsoft.Bcl.TimeProvider/ref/Microsoft.Bcl.TimeProvider.csproj +++ b/src/libraries/Microsoft.Bcl.TimeProvider/ref/Microsoft.Bcl.TimeProvider.csproj @@ -13,6 +13,6 @@ - + diff --git a/src/libraries/Microsoft.Bcl.TimeProvider/src/Microsoft.Bcl.TimeProvider.csproj b/src/libraries/Microsoft.Bcl.TimeProvider/src/Microsoft.Bcl.TimeProvider.csproj index 95e508e6f0d2ba..fbc46e4552c673 100644 --- a/src/libraries/Microsoft.Bcl.TimeProvider/src/Microsoft.Bcl.TimeProvider.csproj +++ b/src/libraries/Microsoft.Bcl.TimeProvider/src/Microsoft.Bcl.TimeProvider.csproj @@ -14,6 +14,8 @@ System.TimeProvider System.ITimer false + true + 1 @@ -31,7 +33,7 @@ System.ITimer - + From 4609a7b7c680177839577e52927777d2c1a872c9 Mon Sep 17 00:00:00 2001 From: Matt Mitchell Date: Tue, 21 Nov 2023 12:15:54 -0800 Subject: [PATCH 503/783] Revert "Downgrade 6 & 7 per tactics (#94863)" (#95075) This reverts commit 656f461c50a46971fb5e6273bbe57d46f713a3e2. --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 2dd0c6b66cff66..799ab19e9a8af6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,7 +7,7 @@ 0 1 8.0.100 - 7.0.$([MSBuild]::Add($(PatchVersion),13)) + 7.0.$([MSBuild]::Add($(PatchVersion),14)) 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) servicing From ed566543bb1156d96f582fd8e2c3e224151492ae Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 15:51:13 -0800 Subject: [PATCH 504/783] [release/8.0-staging] Update dependencies from dotnet/source-build-externals (#94918) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/dotnet/source-build-externals build 20231116.2 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.23518.1 -> To Version 8.0.0-alpha.1.23566.2 * Update dependencies from https://github.com/dotnet/source-build-externals build 20231116.2 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.23518.1 -> To Version 8.0.0-alpha.1.23566.2 * Update dependencies from https://github.com/dotnet/source-build-externals build 20231116.2 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.23518.1 -> To Version 8.0.0-alpha.1.23566.2 * Update dependencies from https://github.com/dotnet/source-build-externals build 20231116.2 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.23518.1 -> To Version 8.0.0-alpha.1.23566.2 * Update dependencies from https://github.com/dotnet/source-build-externals build 20231120.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.23518.1 -> To Version 8.0.0-alpha.1.23570.1 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- NuGet.config | 1 + eng/Version.Details.xml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NuGet.config b/NuGet.config index ceec57bb70dfce..a9123a91e4272c 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,6 +9,7 @@ + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ab9af74ea01fee..ccf2f5e57c8e1a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -104,9 +104,9 @@ 95f83e27806330fec09edd96e06bba3acabe3f35 - + https://github.com/dotnet/source-build-externals - 3dc05150cf234f76f6936dcb2853d31a0da1f60e + e844aa02a05b90d8cbe499676ec6ee0f19ec4980 From 2fc961435c8a1f9ad950c1918294de8538658c4a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 18:02:59 -0800 Subject: [PATCH 505/783] Update dependencies from https://github.com/dotnet/emsdk build 20231121.1 (#95091) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.1-servicing.23567.1 -> To Version 8.0.1-servicing.23571.1 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 676fe8d8352762..963019c74b9b49 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ccf2f5e57c8e1a..8fbbd47bfd2d06 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - d75f77cb8eb87322453288a22ce9b2d880bd1cb1 + 201f4dae9d1a1e105d8ba86d7ece61eed1f665e0 - + https://github.com/dotnet/emsdk - d75f77cb8eb87322453288a22ce9b2d880bd1cb1 + 201f4dae9d1a1e105d8ba86d7ece61eed1f665e0 From 4fc3df22ddcebcea46fc2727ef3a51870ec1ec38 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Wed, 22 Nov 2023 17:55:28 +0100 Subject: [PATCH 508/783] Fix incremental servicing condition (#95119) * Fix incremental servicing condition Makes non shipping packages always ship during servicing * Update packaging.targets * Update Directory.Build.props * Update Microsoft.Internal.Runtime.AspNetCore.Transport.proj * Update Microsoft.Internal.Runtime.WindowsDesktop.Transport.proj * Update packaging.targets --- eng/packaging.targets | 13 ++++++++++--- ...osoft.Internal.Runtime.AspNetCore.Transport.proj | 6 ------ ...t.Internal.Runtime.WindowsDesktop.Transport.proj | 6 ------ 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/eng/packaging.targets b/eng/packaging.targets index a1fbe07ed2a570..67405cb51aeff0 100644 --- a/eng/packaging.targets +++ b/eng/packaging.targets @@ -21,13 +21,20 @@ true $(MSBuildThisFileDirectory)useSharedDesignerContext.txt PACKAGE.md + + false true - true - true - $(PatchVersion) - - $(NoWarn);NU5131;NU5128 - - - true - $(PatchVersion) - - From a20ee6f80ceb86e010802ae77559d096a0f7bc37 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 22 Nov 2023 09:01:45 -0800 Subject: [PATCH 509/783] [release/8.0-staging] Fix JsonArray.Add and ReplaceWith regressions. (#94882) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix JsonArray.Add and ReplaceWith regressions. * Add comment * Address feedback. * Update packaging metadata * Bring back removed using statement * Fix the build error that was showing up after bumping the ServicingVersion prop: Assembly 'System.Text.Json.TestLibrary.Roslyn3.11' with identity 'System.Text.Json.TestLibrary.Roslyn3.11, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' uses 'System.Text.Json, Version=8.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' which has a higher version than referenced assembly 'System.Text.Json' with identity 'System.Text.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' * Update src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.TestLibrary/System.Text.Json.TestLibrary.targets * Fix incremental servicing props ordering issue --------- Co-authored-by: Eirik Tsarpalis Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> Co-authored-by: Viktor Hofer --- src/libraries/Directory.Build.targets | 20 +++--- .../src/System.Text.Json.csproj | 2 + .../src/System/Text/Json/Nodes/JsonArray.cs | 8 +-- .../src/System/Text/Json/Nodes/JsonNode.cs | 41 +++++++++-- .../JsonNode/JsonArrayTests.cs | 69 +++++++++++++++++++ 5 files changed, 119 insertions(+), 21 deletions(-) diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index cb644757a2d95a..348a71ba8da893 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -7,6 +7,18 @@ $(TestStrongNameKeyId) + + + + true + true + true + + @@ -47,14 +59,6 @@ --> $(WarningsAsErrors.Replace('NU1605', '')) - - true - true - true false diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index 5765b6cdbee865..3e867457e45ba6 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -8,6 +8,8 @@ CS8969 true true + true + 1 Provides high-performance and low-allocating types that serialize objects to JavaScript Object Notation (JSON) text and deserialize JSON text to objects, with UTF-8 support built-in. Also provides types to read and write JSON text encoded as UTF-8, and to create an in-memory document object model (DOM), that is read-only, for random access of the JSON elements within a structured view of the data. The System.Text.Json library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs index 8dc0924ad36e61..32096972d6df75 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs @@ -174,13 +174,7 @@ internal JsonArray(JsonElement element, JsonNodeOptions? options = null) : base( [RequiresDynamicCode(JsonValue.CreateDynamicCodeMessage)] public void Add(T? value) { - JsonNode? nodeToAdd = value switch - { - null => null, - JsonNode node => node, - _ => JsonValue.Create(value, Options) - }; - + JsonNode? nodeToAdd = ConvertFromValue(value, Options); Add(nodeToAdd); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.cs index a06fc47cfc1c42..43b6048828a84d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization.Converters; +using System.Text.Json.Serialization.Metadata; namespace System.Text.Json.Nodes { @@ -316,17 +318,16 @@ public static bool DeepEquals(JsonNode? node1, JsonNode? node2) [RequiresDynamicCode(JsonValue.CreateDynamicCodeMessage)] public void ReplaceWith(T value) { + JsonNode? node; switch (_parent) { - case null: - return; case JsonObject jsonObject: - JsonValue? jsonValue = JsonValue.Create(value); - jsonObject.SetItem(GetPropertyName(), jsonValue); + node = ConvertFromValue(value); + jsonObject.SetItem(GetPropertyName(), node); return; case JsonArray jsonArray: - JsonValue? jValue = JsonValue.Create(value); - jsonArray.SetItem(GetElementIndex(), jValue); + node = ConvertFromValue(value); + jsonArray.SetItem(GetElementIndex(), node); return; } } @@ -351,5 +352,33 @@ internal void AssignParent(JsonNode parent) Parent = parent; } + + /// + /// Adaptation of the equivalent JsonValue.Create factory method extended + /// to support arbitrary and values. + /// TODO consider making public cf. https://github.com/dotnet/runtime/issues/70427 + /// + [RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)] + [RequiresDynamicCode(JsonSerializer.SerializationRequiresDynamicCodeMessage)] + internal static JsonNode? ConvertFromValue(T? value, JsonNodeOptions? options = null) + { + if (value is null) + { + return null; + } + + if (value is JsonNode node) + { + return node; + } + + if (value is JsonElement element) + { + return JsonNodeConverter.Create(element, options); + } + + var jsonTypeInfo = (JsonTypeInfo)JsonSerializerOptions.Default.GetTypeInfo(typeof(T)); + return new JsonValueCustomized(value, jsonTypeInfo, options); + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonArrayTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonArrayTests.cs index 8f115d44b211fb..ef51703958151c 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonArrayTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonArrayTests.cs @@ -680,5 +680,74 @@ public static void ReplaceWith() Assert.Null(jValue.Parent); Assert.Equal("[5]", jArray.ToJsonString()); } + + [Theory] + [InlineData("null")] + [InlineData("1")] + [InlineData("false")] + [InlineData("\"str\"")] + [InlineData("""{"test":"hello world"}""")] + [InlineData("[1,2,3]")] + public static void AddJsonElement(string json) + { + // Regression test for https://github.com/dotnet/runtime/issues/94842 + using var jdoc = JsonDocument.Parse(json); + var array = new JsonArray(); + + array.Add(jdoc.RootElement); + + JsonNode arrayElement = Assert.Single(array); + switch (jdoc.RootElement.ValueKind) + { + case JsonValueKind.Object: + Assert.IsAssignableFrom(arrayElement); + break; + case JsonValueKind.Array: + Assert.IsAssignableFrom(arrayElement); + break; + case JsonValueKind.Null: + Assert.Null(arrayElement); + break; + default: + Assert.IsAssignableFrom(arrayElement); + break; + } + Assert.Equal($"[{json}]", array.ToJsonString()); + } + + [Theory] + [InlineData("null")] + [InlineData("1")] + [InlineData("false")] + [InlineData("\"str\"")] + [InlineData("""{"test":"hello world"}""")] + [InlineData("[1,2,3]")] + public static void ReplaceWithJsonElement(string json) + { + // Regression test for https://github.com/dotnet/runtime/issues/94842 + using var jdoc = JsonDocument.Parse(json); + var array = new JsonArray { 1 }; + + array[0].ReplaceWith(jdoc.RootElement); + + JsonNode arrayElement = Assert.Single(array); + switch (jdoc.RootElement.ValueKind) + { + case JsonValueKind.Object: + Assert.IsAssignableFrom(arrayElement); + break; + case JsonValueKind.Array: + Assert.IsAssignableFrom(arrayElement); + break; + case JsonValueKind.Null: + Assert.Null(arrayElement); + break; + default: + Assert.IsAssignableFrom(arrayElement); + break; + } + + Assert.Equal($"[{json}]", array.ToJsonString()); + } } } From 72e5ae975785990e904372573c93dd661279f662 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Wed, 22 Nov 2023 22:29:35 +0000 Subject: [PATCH 510/783] X509Chain.Build should throw when an internal error occurs Chain building can sometimes return nonsensical values when an internal error is encountered. This changes the behavior so that chain building will throw instead of returning nonsensical values. A compat switch is provided so apps can opt out of this behavior. Fixes CVE-2024-0057. --- .../TestUtilities/System/AssertExtensions.cs | 14 ++++ .../SignedCms/SignedCmsTests.netcoreapp.cs | 13 +++- .../src/Resources/Strings.resx | 3 + .../LocalAppContextSwitches.cs | 9 +++ .../X509Certificates/X509Chain.cs | 66 ++++++++++++++----- .../tests/X509Certificates/ChainTests.cs | 52 +++++++++++++++ .../tests/X509Certificates/TestData.cs | 49 ++++++++++++++ 7 files changed, 188 insertions(+), 18 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs index 230e4cb4276a42..f2a9fa6333ca66 100644 --- a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs +++ b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs @@ -397,6 +397,20 @@ public static void GreaterThanOrEqualTo(T actual, T greaterThanOrEqualTo, str throw new XunitException(AddOptionalUserMessage($"Expected: {actual} to be greater than or equal to {greaterThanOrEqualTo}", userMessage)); } + /// + /// Validate that a given enum value has the expected flag set. + /// + /// The enum type. + /// The flag which should be present in . + /// The value which should contain the flag . + public static void HasFlag(T expected, T actual, string userMessage = null) where T : Enum + { + if (!actual.HasFlag(expected)) + { + throw new XunitException(AddOptionalUserMessage($"Expected: Value {actual} (of enum type {typeof(T).FullName}) to have the flag {expected} set.", userMessage)); + } + } + // NOTE: Consider using SequenceEqual below instead, as it will give more useful information about what // the actual differences are, especially for large arrays/spans. /// diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.netcoreapp.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.netcoreapp.cs index e5ef61d996a88b..2e1911ba11d3ea 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.netcoreapp.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.netcoreapp.cs @@ -399,7 +399,10 @@ public static void AddSigner_RSA_EphemeralKey() { ContentInfo content = new ContentInfo(new byte[] { 1, 2, 3 }); SignedCms cms = new SignedCms(content, false); - CmsSigner signer = new CmsSigner(certWithEphemeralKey); + CmsSigner signer = new CmsSigner(certWithEphemeralKey) + { + IncludeOption = X509IncludeOption.EndCertOnly + }; cms.ComputeSignature(signer); } } @@ -429,7 +432,8 @@ public static void AddSigner_DSA_EphemeralKey() SignedCms cms = new SignedCms(content, false); CmsSigner signer = new CmsSigner(certWithEphemeralKey) { - DigestAlgorithm = new Oid(Oids.Sha1, Oids.Sha1) + DigestAlgorithm = new Oid(Oids.Sha1, Oids.Sha1), + IncludeOption = X509IncludeOption.EndCertOnly }; cms.ComputeSignature(signer); } @@ -458,7 +462,10 @@ public static void AddSigner_ECDSA_EphemeralKey() { ContentInfo content = new ContentInfo(new byte[] { 1, 2, 3 }); SignedCms cms = new SignedCms(content, false); - CmsSigner signer = new CmsSigner(certWithEphemeralKey); + CmsSigner signer = new CmsSigner(certWithEphemeralKey) + { + IncludeOption = X509IncludeOption.EndCertOnly + }; cms.ComputeSignature(signer); } } diff --git a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx index e447937b7b6c39..1bd529a087a6ac 100644 --- a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx @@ -834,4 +834,7 @@ There was a problem with the PKCS12 (PFX) without a supplied password. See https://go.microsoft.com/fwlink/?linkid=2233907 for more information. + + An unknown chain building error occurred. + diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/LocalAppContextSwitches.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/LocalAppContextSwitches.cs index 0af05ab604b677..be8c3d44bf8fb4 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/LocalAppContextSwitches.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/LocalAppContextSwitches.cs @@ -11,6 +11,8 @@ internal static partial class LocalAppContextSwitches internal static long Pkcs12UnspecifiedPasswordIterationLimit { get; } = InitializePkcs12UnspecifiedPasswordIterationLimit(); + internal static bool X509ChainBuildThrowOnInternalError { get; } = InitializeX509ChainBuildThrowOnInternalError(); + private static long InitializePkcs12UnspecifiedPasswordIterationLimit() { object? data = AppContext.GetData("System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit"); @@ -29,5 +31,12 @@ private static long InitializePkcs12UnspecifiedPasswordIterationLimit() return DefaultPkcs12UnspecifiedPasswordIterationLimit; } } + + private static bool InitializeX509ChainBuildThrowOnInternalError() + { + // n.b. the switch defaults to TRUE if it has not been explicitly set. + return AppContext.TryGetSwitch("System.Security.Cryptography.ThrowOnX509ChainBuildInternalError", out bool isEnabled) + ? isEnabled : true; + } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Chain.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Chain.cs index 50eaba6eb91b95..fdc0b02b2d6e37 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Chain.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Chain.cs @@ -137,26 +137,62 @@ internal bool Build(X509Certificate2 certificate, bool throwOnException) chainPolicy.UrlRetrievalTimeout, chainPolicy.DisableCertificateDownloads); - if (_pal == null) - return false; - - _chainElements = new X509ChainElementCollection(_pal.ChainElements!); - - Exception? verificationException; - bool? verified = _pal.Verify(chainPolicy.VerificationFlags, out verificationException); - if (!verified.HasValue) + bool success = false; + if (_pal is not null) { - if (throwOnException) - { - throw verificationException!; - } - else + _chainElements = new X509ChainElementCollection(_pal.ChainElements!); + + Exception? verificationException; + bool? verified = _pal.Verify(chainPolicy.VerificationFlags, out verificationException); + if (!verified.HasValue) { - verified = false; + if (throwOnException) + { + throw verificationException!; + } + else + { + verified = false; + } } + + success = verified.Value; + } + + // There are two reasons success might be false here. + // + // The most common reason is that we built the chain but the chain appears to run + // afoul of policy. This is represented by BuildChain returning a non-null object + // and storing potential policy violations in the chain structure. The public Build + // method returns false to the caller, and the caller can inspect the ChainStatus + // and ChainElements properties and evaluate the failure reason against app-level + // policies. If the caller does not care about these policy violations, they can + // choose to ignore them and to treat chain building as successful. + // + // The other type of failure is that BuildChain simply can't build the chain at all. + // Perhaps something within the certificate is not valid or is unsupported, or perhaps + // there's an internal failure within the OS layer we're invoking, etc. Whatever the + // reason, we're not meaningfully able to initialize the ChainStatus property, which + // means callers may observe a non-empty list of policy violations. Depending on the + // caller's logic, they might incorrectly interpret this as there being no policy + // violations at all, which means they might treat this condition as success. + // + // To avoid callers misinterpeting this latter condition as success, we'll throw an + // exception, which matches general .NET API behavior when a method cannot complete + // its objective. A compat switch is provided to normalize this back to a 'false' + // return value for callers who cannot handle an exception here. If throwOnException + // is false, it means the caller explicitly wants to suppress exceptions and normalize + // them to a false return value. + + if (!success + && throwOnException + && _pal?.ChainStatus is not { Length: > 0 } + && LocalAppContextSwitches.X509ChainBuildThrowOnInternalError) + { + throw new CryptographicException(SR.Cryptography_X509_ChainBuildingFailed); } - return verified.Value; + return success; } } diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs index 23bef2b46c250a..92cc1abb1b6292 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs @@ -1269,6 +1269,58 @@ public static void BuildChainForSelfSignedSha3Certificate() } } + [Fact] + public static void BuildChainForSelfSignedCertificate_WithSha256RsaSignature() + { + using (ChainHolder chainHolder = new ChainHolder()) + using (X509Certificate2 cert = new X509Certificate2(TestData.SelfSignedCertSha256RsaBytes)) + { + X509Chain chain = chainHolder.Chain; + chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + chain.ChainPolicy.VerificationTime = cert.NotBefore.AddHours(2); + + // No custom root of trust store means that this self-signed cert will at + // minimum be marked UntrustedRoot. + + Assert.False(chain.Build(cert)); + AssertExtensions.HasFlag(X509ChainStatusFlags.UntrustedRoot, chain.AllStatusFlags()); + } + } + + [Fact] + public static void BuildChainForSelfSignedCertificate_WithUnknownOidSignature() + { + using (ChainHolder chainHolder = new ChainHolder()) + using (X509Certificate2 cert = new X509Certificate2(TestData.SelfSignedCertDummyOidBytes)) + { + X509Chain chain = chainHolder.Chain; + chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + chain.ChainPolicy.VerificationTime = cert.NotBefore.AddHours(2); + + // This tests a self-signed cert whose signature block contains a garbage signing alg OID. + // Some platforms return NotSignatureValid to indicate that they cannot understand the + // signature block. Other platforms return PartialChain to indicate that they think the + // bad signature block might correspond to some unknown, untrusted signer. Yet other + // platforms simply fail the operation; e.g., Windows's CertGetCertificateChain API returns + // NTE_BAD_ALGID, which we bubble up as CryptographicException. + + if (PlatformDetection.UsesAppleCrypto) + { + Assert.False(chain.Build(cert)); + AssertExtensions.HasFlag(X509ChainStatusFlags.PartialChain, chain.AllStatusFlags()); + } + else if (PlatformDetection.IsOpenSslSupported) + { + Assert.False(chain.Build(cert)); + AssertExtensions.HasFlag(X509ChainStatusFlags.NotSignatureValid, chain.AllStatusFlags()); + } + else + { + Assert.ThrowsAny(() => chain.Build(cert)); + } + } + } + internal static X509ChainStatusFlags AllStatusFlags(this X509Chain chain) { return chain.ChainStatus.Aggregate( diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs index e3deb00b354d06..cf14136eb6e058 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs @@ -4224,5 +4224,54 @@ internal static DSAParameters GetDSA1024Params() "09463C6E50BCA36EB3F8BCB00D8A415D2D0DB5AE08303B301F300706052B0E03" + "021A0414A57105D833610A6D07EBFBE51E5486CD3F8BCE0D0414DB32290CC077" + "37E9D9446E37F104FA876C861C0102022710").HexToByteArray(); + + // Used for chain building tests (CN=Test chain building) + internal static readonly byte[] SelfSignedCertSha256RsaBytes = ( + "308202BD308201A5A003020102020900EF79C10DFD657168300D06092A864886F70D0101" + + "0B0500301E311C301A060355040313135465737420636861696E206275696C64696E6730" + + "1E170D3231313031333231353735335A170D3232313031333231353735335A301E311C30" + + "1A060355040313135465737420636861696E206275696C64696E6730820122300D06092A" + + "864886F70D01010105000382010F003082010A0282010100E3B5BBF862313DEAA9172788" + + "278B26A3EAB61B9B0326F5CEA91B1A6C6DFD156836A2363BFAC5B0F4A78F4CFF5A11F35A" + + "831C6D7935D1DFD13DD81DA29AA0645CBA9F4D20BF991C625E6D61CF396C15914DEE41F6" + + "1190E97B52BFF7AE52B79FD0E2EEE3319EC23C30D27A52A2E8A963557B12BEC0664ADEF9" + + "3C520B587EC5DABFBC70980DB7473414B4B6BF982EA9AA0969F2A76AA085464AE78DFB2B" + + "F04BDE7192874679193119C2AABEC04D360F61925921660BF09A0489B7C53464F5FC35B8" + + "612F5B993D544475C20AC46CD350A34551FEA0ACBD138D8B72F79052BF0EB3BD794A426C" + + "0117CB77B4F311FFD1C628F8E438E5474509AD51FA035558771546310203010001300D06" + + "092A864886F70D01010B050003820101000A12CE2FC3DC854113D179725E9D9ADD013A42" + + "D66340CEA7A465D54EC357AD8FED1828862D8B5C32EB3D21FC8B26A7CFA9D9FB36F593CC" + + "6AD30C25C96E8100C3F07B1B51430245EE995864749C53B409260B4040705654710C236F" + + "D9B7DE3F3BE5E6E5047712C5E506419106A57C5290BB206A97F6A3FCC4B4C83E25C3FC6D" + + "2BAB03B941374086265EE08A90A8C72A63A4053044B9FA3ABD5ED5785CFDDB15A6A327BD" + + "C0CC2B115B9D33BD6E528E35670E5A6A8D9CF52199F8D693315C60D9ADAD54EF7FDCED36" + + "0C8C79E84D42AB5CB6355A70951B1ABF1F2B3FB8BEB7E3A8D6BA2293C0DB8C86B0BB060F" + + "0D6DB9939E88B998662A27F092634BBF21F58EEAAA").HexToByteArray(); + + // This is nearly identical to the cert in Pkcs7SelfSignedCertSha256RsaBytes, + // but we've replaced the OID (1.2.840.113549.1.1.11 sha256RSA) with a dummy OID + // 1.3.9999.1234.5678.1234. The cert should load properly into an X509Certificate2 + // object but will cause chain building to fail. + internal static readonly byte[] SelfSignedCertDummyOidBytes = ( + "308202BD308201A5A003020102020900EF79C10DFD657168300D06092A864886F70D0101" + + "0B0500301E311C301A060355040313135465737420636861696E206275696C64696E6730" + + "1E170D3231313031333231353735335A170D3232313031333231353735335A301E311C30" + + "1A060355040313135465737420636861696E206275696C64696E6730820122300D06092A" + + "864886F70D01010105000382010F003082010A0282010100E3B5BBF862313DEAA9172788" + + "278B26A3EAB61B9B0326F5CEA91B1A6C6DFD156836A2363BFAC5B0F4A78F4CFF5A11F35A" + + "831C6D7935D1DFD13DD81DA29AA0645CBA9F4D20BF991C625E6D61CF396C15914DEE41F6" + + "1190E97B52BFF7AE52B79FD0E2EEE3319EC23C30D27A52A2E8A963557B12BEC0664ADEF9" + + "3C520B587EC5DABFBC70980DB7473414B4B6BF982EA9AA0969F2A76AA085464AE78DFB2B" + + "F04BDE7192874679193119C2AABEC04D360F61925921660BF09A0489B7C53464F5FC35B8" + + "612F5B993D544475C20AC46CD350A34551FEA0ACBD138D8B72F79052BF0EB3BD794A426C" + + "0117CB77B4F311FFD1C628F8E438E5474509AD51FA035558771546310203010001300D06" + + "092BCE0F8952AC2E8952050003820101000A12CE2FC3DC854113D179725E9D9ADD013A42" + + "D66340CEA7A465D54EC357AD8FED1828862D8B5C32EB3D21FC8B26A7CFA9D9FB36F593CC" + + "6AD30C25C96E8100C3F07B1B51430245EE995864749C53B409260B4040705654710C236F" + + "D9B7DE3F3BE5E6E5047712C5E506419106A57C5290BB206A97F6A3FCC4B4C83E25C3FC6D" + + "2BAB03B941374086265EE08A90A8C72A63A4053044B9FA3ABD5ED5785CFDDB15A6A327BD" + + "C0CC2B115B9D33BD6E528E35670E5A6A8D9CF52199F8D693315C60D9ADAD54EF7FDCED36" + + "0C8C79E84D42AB5CB6355A70951B1ABF1F2B3FB8BEB7E3A8D6BA2293C0DB8C86B0BB060F" + + "0D6DB9939E88B998662A27F092634BBF21F58EEAAA").HexToByteArray(); } } From 803201d1408646664bb1aaca4a607a174d5ff473 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:58:38 -0600 Subject: [PATCH 511/783] Update dependencies from https://github.com/dotnet/hotreload-utils build 20231127.1 (#95279) Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23570.2 -> To Version 8.0.0-alpha.0.23577.1 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 -- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/NuGet.config b/NuGet.config index f34253e5b0e2fe..ae4e5f1d8764d4 100644 --- a/NuGet.config +++ b/NuGet.config @@ -10,8 +10,6 @@ - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c8a893de7d463b..04ddf837a06a2d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -354,9 +354,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 67613417f5e1af250e6ddfba79f8f2885d8e90fb - + https://github.com/dotnet/hotreload-utils - 5524f726f92ef862b415793758cebbd2a1950b70 + e12b15aff28e365850ffa713b5b5afdc24470a04 https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index da037c2c7ca922..6c001d0ac032e0 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -186,7 +186,7 @@ 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 - 8.0.0-alpha.0.23570.2 + 8.0.0-alpha.0.23577.1 2.4.2 1.0.0 2.4.5 From 89a236434ec0064b8b4425b0ea89e8ecdf834538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Tue, 28 Nov 2023 11:34:27 -0600 Subject: [PATCH 512/783] [release/8.0] Downgrade ServicingVersion for Microsoft.Extensions.Options to 1 (#95348) --- .../src/Microsoft.Extensions.Options.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj index e35606898e3914..abbc5d2329c5c1 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj +++ b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj @@ -5,7 +5,7 @@ true true true - 2 + 1 Provides a strongly typed way of specifying and accessing settings using dependency injection. From fc006d0cf4b5cfebae8cc7f542d45afd755e82aa Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Wed, 29 Nov 2023 17:39:39 -0800 Subject: [PATCH 513/783] [8.0] Remove jit-format job in .NET 8.0 branch (#95423) Remove jit-format from outerloop pipeline in .NET 8 branch. jit-format currently only works well in main. It is also not useful in servicing branches. --- eng/pipelines/coreclr/ci.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/eng/pipelines/coreclr/ci.yml b/eng/pipelines/coreclr/ci.yml index 209314a136702f..adf052b014f455 100644 --- a/eng/pipelines/coreclr/ci.yml +++ b/eng/pipelines/coreclr/ci.yml @@ -155,13 +155,3 @@ extends: readyToRun: true displayNameArgs: R2R_CG2 liveLibrariesBuildConfig: Release - - # - # Formatting - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/coreclr/templates/format-job.yml - platforms: - - linux_x64 - - windows_x64 From a6e4834d53ac591a4b3d4a213a8928ad685f7ad8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 29 Nov 2023 23:54:17 -0800 Subject: [PATCH 514/783] [release/8.0] Free the tls memory on thread termination (#95439) * Free the tls memory * zero the size variables * fix linux build errors * Move ThreadStaticBlockInfo definition in jitinterface.h * cleanup and consolidate TLS variables * Address review feedback * reset t_NonGCThreadStaticBlocksSize and conditional check the nullptr * Delete tls memory from detach thread * Call DeleteThreadLocalMemory() from TlsDestructionMonitor --------- Co-authored-by: Kunal Pathak --- src/coreclr/vm/ceemain.cpp | 30 ++++++++++++++++++++++++++++++ src/coreclr/vm/ceemain.h | 2 ++ src/coreclr/vm/jithelpers.cpp | 21 +++++---------------- src/coreclr/vm/jitinterface.cpp | 19 ++----------------- src/coreclr/vm/jitinterface.h | 19 +++++++++++++++++++ 5 files changed, 58 insertions(+), 33 deletions(-) diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index 1fd898684cf1c1..1c58c941fb21ac 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -1752,6 +1752,7 @@ struct TlsDestructionMonitor GCX_COOP_NO_DTOR_END(); } thread->DetachThread(TRUE); + DeleteThreadLocalMemory(); } ThreadDetaching(); @@ -1768,6 +1769,35 @@ void EnsureTlsDestructionMonitor() tls_destructionMonitor.Activate(); } +#ifdef _MSC_VER +__declspec(thread) ThreadStaticBlockInfo t_ThreadStatics; +#else +__thread ThreadStaticBlockInfo t_ThreadStatics; +#endif // _MSC_VER + +// Delete the thread local memory only if we the current thread +// is the one executing this code. If we do not guard it, it will +// end up deleting the thread local memory of the calling thread. +void DeleteThreadLocalMemory() +{ + t_NonGCThreadStaticBlocksSize = 0; + t_GCThreadStaticBlocksSize = 0; + + t_ThreadStatics.NonGCMaxThreadStaticBlocks = 0; + t_ThreadStatics.GCMaxThreadStaticBlocks = 0; + + if (t_ThreadStatics.NonGCThreadStaticBlocks != nullptr) + { + delete[] t_ThreadStatics.NonGCThreadStaticBlocks; + t_ThreadStatics.NonGCThreadStaticBlocks = nullptr; + } + if (t_ThreadStatics.GCThreadStaticBlocks != nullptr) + { + delete[] t_ThreadStatics.GCThreadStaticBlocks; + t_ThreadStatics.GCThreadStaticBlocks = nullptr; + } +} + #ifdef DEBUGGING_SUPPORTED // // InitializeDebugger initialized the Runtime-side COM+ Debugging Services diff --git a/src/coreclr/vm/ceemain.h b/src/coreclr/vm/ceemain.h index 1404a5a04237ff..85efc8d0a9c783 100644 --- a/src/coreclr/vm/ceemain.h +++ b/src/coreclr/vm/ceemain.h @@ -47,6 +47,8 @@ void ThreadDetaching(); void EnsureTlsDestructionMonitor(); +void DeleteThreadLocalMemory(); + void SetLatchedExitCode (INT32 code); INT32 GetLatchedExitCode (void); diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index e225a6e3834b76..744d80eb34971c 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -1777,24 +1777,13 @@ HCIMPL1(void*, JIT_GetGCThreadStaticBase_Helper, MethodTable * pMT) } HCIMPLEND -struct ThreadStaticBlockInfo -{ - uint32_t NonGCMaxThreadStaticBlocks; - void** NonGCThreadStaticBlocks; - - uint32_t GCMaxThreadStaticBlocks; - void** GCThreadStaticBlocks; -}; - #ifdef _MSC_VER -__declspec(selectany) __declspec(thread) ThreadStaticBlockInfo t_ThreadStatics; -__declspec(selectany) __declspec(thread) uint32_t t_NonGCThreadStaticBlocksSize; -__declspec(selectany) __declspec(thread) uint32_t t_GCThreadStaticBlocksSize; +__declspec(thread) uint32_t t_NonGCThreadStaticBlocksSize; +__declspec(thread) uint32_t t_GCThreadStaticBlocksSize; #else -EXTERN_C __thread ThreadStaticBlockInfo t_ThreadStatics; -EXTERN_C __thread uint32_t t_NonGCThreadStaticBlocksSize; -EXTERN_C __thread uint32_t t_GCThreadStaticBlocksSize; -#endif +__thread uint32_t t_NonGCThreadStaticBlocksSize; +__thread uint32_t t_GCThreadStaticBlocksSize; +#endif // !_MSC_VER // *** This helper corresponds to both CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE and // CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR. Even though we always check diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 74ee2f7482e747..1cc6c37e09c227 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -69,24 +69,9 @@ EXTERN_C uint32_t _tls_index; #endif -struct ThreadStaticBlockInfo -{ - uint32_t NonGCMaxThreadStaticBlocks; - void** NonGCThreadStaticBlocks; - - uint32_t GCMaxThreadStaticBlocks; - void** GCThreadStaticBlocks; -}; -#ifdef _MSC_VER -__declspec(selectany) __declspec(thread) ThreadStaticBlockInfo t_ThreadStatics; -__declspec(selectany) __declspec(thread) uint32_t t_NonGCThreadStaticBlocksSize; -__declspec(selectany) __declspec(thread) uint32_t t_GCThreadStaticBlocksSize; -#else +#ifndef _MSC_VER extern "C" void* __tls_get_addr(void* ti); -__thread ThreadStaticBlockInfo t_ThreadStatics; -__thread uint32_t t_NonGCThreadStaticBlocksSize; -__thread uint32_t t_GCThreadStaticBlocksSize; -#endif // _MSC_VER +#endif // !_MSC_VER // The Stack Overflow probe takes place in the COOPERATIVE_TRANSITION_BEGIN() macro // diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index b6e5eff8ff427d..fa92a18501df27 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -101,6 +101,25 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, #endif // TARGET_X86 +// thread local struct to store the "thread static blocks" +struct ThreadStaticBlockInfo +{ + uint32_t NonGCMaxThreadStaticBlocks; + void** NonGCThreadStaticBlocks; + + uint32_t GCMaxThreadStaticBlocks; + void** GCThreadStaticBlocks; +}; + +#ifdef _MSC_VER +EXTERN_C __declspec(thread) ThreadStaticBlockInfo t_ThreadStatics; +EXTERN_C __declspec(thread) uint32_t t_NonGCThreadStaticBlocksSize; +EXTERN_C __declspec(thread) uint32_t t_GCThreadStaticBlocksSize; +#else +EXTERN_C __thread ThreadStaticBlockInfo t_ThreadStatics; +EXTERN_C __thread uint32_t t_NonGCThreadStaticBlocksSize; +EXTERN_C __thread uint32_t t_GCThreadStaticBlocksSize; +#endif // _MSC_VER // // JIT HELPER ALIASING FOR PORTABILITY. From 80c6593490f7900f9675ba207f95944e504c324d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 07:52:14 -0500 Subject: [PATCH 515/783] [release/8.0-staging] Add JSON null support for the built-in (ReadOnly)Memory converters. (#95325) * Add JSON null support for the built-in (ReadOnly)Memory converters. * Address feedback --------- Co-authored-by: Eirik Tsarpalis --- .../Converters/Collection/MemoryConverter.cs | 18 ++++++++++++++++++ .../Collection/ReadOnlyMemoryConverter.cs | 18 ++++++++++++++++++ .../JsonMetadataServicesConverter.cs | 11 ++++++++++- .../Converters/Value/MemoryByteConverter.cs | 4 +++- .../Value/ReadOnlyMemoryByteConverter.cs | 4 +++- .../Serialization/JsonResumableConverterOfT.cs | 4 ++-- .../CollectionTests/CollectionTests.Memory.cs | 17 ++++++++++++++++- 7 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/MemoryConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/MemoryConverter.cs index 55f145e5354798..670ab037367a83 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/MemoryConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/MemoryConverter.cs @@ -2,12 +2,30 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { internal sealed class MemoryConverter : JsonCollectionConverter, T> { internal override bool CanHaveMetadata => false; + public override bool HandleNull => true; + + internal override bool OnTryRead( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options, + scoped ref ReadStack state, + out Memory value) + { + if (reader.TokenType is JsonTokenType.Null) + { + value = default; + return true; + } + + return base.OnTryRead(ref reader, typeToConvert, options, ref state, out value); + } protected override void Add(in T value, ref ReadStack state) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ReadOnlyMemoryConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ReadOnlyMemoryConverter.cs index b8778c7736baab..8ca1ef71db3fb3 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ReadOnlyMemoryConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ReadOnlyMemoryConverter.cs @@ -2,12 +2,30 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { internal sealed class ReadOnlyMemoryConverter : JsonCollectionConverter, T> { internal override bool CanHaveMetadata => false; + public override bool HandleNull => true; + + internal override bool OnTryRead( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options, + scoped ref ReadStack state, + out ReadOnlyMemory value) + { + if (reader.TokenType is JsonTokenType.Null) + { + value = default; + return true; + } + + return base.OnTryRead(ref reader, typeToConvert, options, ref state, out value); + } protected override void Add(in T value, ref ReadStack state) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonMetadataServicesConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonMetadataServicesConverter.cs index debb3f0d77c09d..88303c6284d1f9 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonMetadataServicesConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonMetadataServicesConverter.cs @@ -20,6 +20,7 @@ internal sealed class JsonMetadataServicesConverter : JsonResumableConverter< internal override Type? KeyType => Converter.KeyType; internal override Type? ElementType => Converter.ElementType; + public override bool HandleNull { get; } internal override bool ConstructorIsParameterized => Converter.ConstructorIsParameterized; internal override bool SupportsCreateObjectDelegate => Converter.SupportsCreateObjectDelegate; @@ -29,8 +30,16 @@ internal sealed class JsonMetadataServicesConverter : JsonResumableConverter< public JsonMetadataServicesConverter(JsonConverter converter) { - ConverterStrategy = converter.ConverterStrategy; Converter = converter; + ConverterStrategy = converter.ConverterStrategy; + IsInternalConverter = converter.IsInternalConverter; + IsInternalConverterForNumberType = converter.IsInternalConverterForNumberType; + CanBePolymorphic = converter.CanBePolymorphic; + + // Ensure HandleNull values reflect the exact configuration of the source converter + HandleNullOnRead = converter.HandleNullOnRead; + HandleNullOnWrite = converter.HandleNullOnWrite; + HandleNull = converter.HandleNullOnWrite; } internal override bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, scoped ref ReadStack state, out T? value) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/MemoryByteConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/MemoryByteConverter.cs index 20536c81b3627e..0efa7e71a13ac7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/MemoryByteConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/MemoryByteConverter.cs @@ -5,9 +5,11 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class MemoryByteConverter : JsonConverter> { + public override bool HandleNull => true; + public override Memory Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - return reader.GetBytesFromBase64(); + return reader.TokenType is JsonTokenType.Null ? default : reader.GetBytesFromBase64(); } public override void Write(Utf8JsonWriter writer, Memory value, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ReadOnlyMemoryByteConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ReadOnlyMemoryByteConverter.cs index 68b7c1f0333540..48eddafefba200 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ReadOnlyMemoryByteConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ReadOnlyMemoryByteConverter.cs @@ -5,9 +5,11 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class ReadOnlyMemoryByteConverter : JsonConverter> { + public override bool HandleNull => true; + public override ReadOnlyMemory Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - return reader.GetBytesFromBase64(); + return reader.TokenType is JsonTokenType.Null ? default : reader.GetBytesFromBase64(); } public override void Write(Utf8JsonWriter writer, ReadOnlyMemory value, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs index fcf782a2e4fe78..81bceda8d8404c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs @@ -12,6 +12,8 @@ namespace System.Text.Json.Serialization /// internal abstract class JsonResumableConverter : JsonConverter { + public override bool HandleNull => false; + public sealed override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (options is null) @@ -51,7 +53,5 @@ public sealed override void Write(Utf8JsonWriter writer, T value, JsonSerializer throw; } } - - public sealed override bool HandleNull => false; } } diff --git a/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Memory.cs b/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Memory.cs index bf6e148cde18c5..58525300624be0 100644 --- a/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Memory.cs +++ b/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Memory.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Text.Json.Tests; using System.Threading.Tasks; using Xunit; @@ -104,6 +103,22 @@ public async Task DeserializeMemoryByteAsync() AssertExtensions.SequenceEqual(s_testData, readOnlyMemory.Span); } + [Fact] + public async Task DeserializeNullAsMemory() + { + ReadOnlyMemory readOnlyMemOfInt = await Serializer.DeserializeWrapper>("null"); + Assert.True(readOnlyMemOfInt.IsEmpty); + + Memory memOfInt = await Serializer.DeserializeWrapper>("null"); + Assert.True(memOfInt.IsEmpty); + + ReadOnlyMemory readOnlyMemOfByte = await Serializer.DeserializeWrapper>("null"); + Assert.True(readOnlyMemOfByte.IsEmpty); + + Memory memOfByte = await Serializer.DeserializeWrapper>("null"); + Assert.True(memOfByte.IsEmpty); + } + [Fact] public async Task SerializeMemoryByteClassAsync() { From d13cc84237ef4bd8030bcea7e83fe5dba38a0349 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Thu, 30 Nov 2023 09:27:32 -0800 Subject: [PATCH 516/783] Fix FormatException message argument (#95356) --- .../src/System/Globalization/DateTimeParse.cs | 7 +++---- .../System.Runtime/tests/System/DateTimeTests.cs | 11 +++++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs index a8f68fb94ebf98..80d963c89da202 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs @@ -1547,7 +1547,7 @@ private static void GetDefaultYear(ref DateTimeResult result, scoped ref DateTim result.flags |= ParseFlags.YearDefault; } - // Processing teriminal case: DS.DX_NN + // Processing terminal case: DS.DX_NN private static bool GetDayOfNN(ref DateTimeResult result, scoped ref DateTimeStyles styles, scoped ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) { if ((result.flags & ParseFlags.HaveDate) != 0) @@ -1589,7 +1589,7 @@ private static bool GetDayOfNN(ref DateTimeResult result, scoped ref DateTimeSty return false; } - // Processing teriminal case: DS.DX_NNN + // Processing terminal case: DS.DX_NNN private static bool GetDayOfNNN(ref DateTimeResult result, scoped ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) { if ((result.flags & ParseFlags.HaveDate) != 0) @@ -5183,7 +5183,7 @@ private static Exception GetDateTimeParseException(scoped ref DateTimeResult res case ParseFailureKind.Format_BadDatePattern: return new FormatException(SR.Format(SR.Format_BadDatePattern, result.failureMessageFormatArgument)); case ParseFailureKind.Format_BadDateTime: - return new FormatException(SR.Format(SR.Format_BadDateTime, result.failureMessageFormatArgument)); + return new FormatException(SR.Format(SR.Format_BadDateTime, new string(result.originalDateTimeString))); case ParseFailureKind.Format_BadDateTimeCalendar: return new FormatException(SR.Format(SR.Format_BadDateTimeCalendar, new string(result.originalDateTimeString), result.calendar)); case ParseFailureKind.Format_BadDayOfWeek: @@ -6124,7 +6124,6 @@ internal void SetBadFormatSpecifierFailure(ReadOnlySpan failedFormatSpecif internal void SetBadDateTimeFailure() { this.failure = ParseFailureKind.Format_BadDateTime; - this.failureMessageFormatArgument = null; } internal void SetFailure(ParseFailureKind failure) diff --git a/src/libraries/System.Runtime/tests/System/DateTimeTests.cs b/src/libraries/System.Runtime/tests/System/DateTimeTests.cs index 362354f2b545e8..9ecfcdf47e63f0 100644 --- a/src/libraries/System.Runtime/tests/System/DateTimeTests.cs +++ b/src/libraries/System.Runtime/tests/System/DateTimeTests.cs @@ -114,7 +114,7 @@ public void Ctor_DateOnly_TimeOnly(int year, int month, int day, int hour, int m var date = new DateOnly(year, month, day); var time = new TimeOnly(hour, minute, second, millisecond); var dateTime = new DateTime(date, time); - + Assert.Equal(new DateTime(year, month, day, hour, minute, second, millisecond), dateTime); } @@ -125,7 +125,7 @@ public void Ctor_DateOnly_TimeOnly_DateTimeKind(int year, int month, int day, in var date = new DateOnly(year, month, day); var time = new TimeOnly(hour, minute, second, millisecond); var dateTime = new DateTime(date, time, DateTimeKind.Local); - + Assert.Equal(new DateTime(year, month, day, hour, minute, second, millisecond, DateTimeKind.Local), dateTime); } @@ -2984,5 +2984,12 @@ public void TestDateTimeCalculationPrecision(double value, DateTime initialValue break; } } + + [Fact] + public void TestBadFormatException() + { + FormatException ex = Assert.Throws(() => DateTime.ParseExact("11.2023", "dd.mm.yyyy", System.Globalization.CultureInfo.InvariantCulture)); + Assert.Contains("11.2023", ex.Message, StringComparison.Ordinal); + } } } From 25fbafa056a90ee473ab52cef9a3260991ed0330 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 09:31:09 -0800 Subject: [PATCH 517/783] [release/8.0-staging] Correct time zone name creation when generated lazily. (#95364) Co-authored-by: Tarek Mahmoud Sayed --- .../src/System/TimeZoneInfo.cs | 18 +++++++------ .../tests/System/TimeZoneInfoTests.cs | 26 +++++++++++++++++++ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs index f564a12398cdc5..b76ed8f165ff52 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs @@ -108,7 +108,7 @@ public DateTimeKind GetCorrespondingKind(TimeZoneInfo? timeZone) // We check reference equality to see if 'this' is the same as // TimeZoneInfo.Local or TimeZoneInfo.Utc. This check is needed to // support setting the DateTime Kind property to 'Local' or - // 'Utc' on the ConverTime(...) return value. + // 'Utc' on the ConvertTime(...) return value. // // Using reference equality instead of value equality was a // performance based design compromise. The reference equality @@ -1011,9 +1011,9 @@ private TimeZoneInfo( _id = id; _baseUtcOffset = baseUtcOffset; - _displayName = displayName ?? string.Empty; - _standardDisplayName = standardDisplayName ?? string.Empty; - _daylightDisplayName = disableDaylightSavingTime ? string.Empty : daylightDisplayName ?? string.Empty; + _displayName = displayName; + _standardDisplayName = standardDisplayName; + _daylightDisplayName = disableDaylightSavingTime ? null : daylightDisplayName; _supportsDaylightSavingTime = adjustmentRulesSupportDst && !disableDaylightSavingTime; _adjustmentRules = adjustmentRules; @@ -1031,10 +1031,12 @@ public static TimeZoneInfo CreateCustomTimeZone( { bool hasIanaId = TryConvertIanaIdToWindowsId(id, allocate: false, out _); + standardDisplayName ??= string.Empty; + return new TimeZoneInfo( id, baseUtcOffset, - displayName, + displayName ?? string.Empty, standardDisplayName, standardDisplayName, adjustmentRules: null, @@ -1085,9 +1087,9 @@ public static TimeZoneInfo CreateCustomTimeZone( return new TimeZoneInfo( id, baseUtcOffset, - displayName, - standardDisplayName, - daylightDisplayName, + displayName ?? string.Empty, + standardDisplayName ?? string.Empty, + daylightDisplayName ?? string.Empty, adjustmentRules, disableDaylightSavingTime, hasIanaId); diff --git a/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs b/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs index 7efe9c0cde1dcf..286e18ba3410c7 100644 --- a/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs +++ b/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs @@ -3185,6 +3185,32 @@ public static void LocalTzIsNotUtc() Assert.NotEqual(TimeZoneInfo.Utc.StandardName, TimeZoneInfo.Local.StandardName); } + private static bool SupportICUAndRemoteExecution => PlatformDetection.IsIcuGlobalization && RemoteExecutor.IsSupported; + + [InlineData("Pacific Standard Time")] + [InlineData("America/Los_Angeles")] + [ConditionalTheory(nameof(SupportICUAndRemoteExecution))] + public static void TestZoneNamesUsingAlternativeId(string zoneId) + { + RemoteExecutor.Invoke(id => + { + TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(id); + Assert.False(string.IsNullOrEmpty(tzi.StandardName), $"StandardName for '{id}' is null or empty."); + Assert.False(string.IsNullOrEmpty(tzi.DaylightName), $"DaylightName for '{id}' is null or empty."); + Assert.False(string.IsNullOrEmpty(tzi.DisplayName), $"DisplayName for '{id}' is null or empty."); + }, zoneId).Dispose(); + } + + [Fact] + public static void TestCustomTimeZonesWithNullNames() + { + TimeZoneInfo custom = TimeZoneInfo.CreateCustomTimeZone("Custom Time Zone With Null Names", TimeSpan.FromHours(-8), null, null); + Assert.Equal("Custom Time Zone With Null Names", custom.Id); + Assert.Equal(string.Empty, custom.StandardName); + Assert.Equal(string.Empty, custom.DaylightName); + Assert.Equal(string.Empty, custom.DisplayName); + } + private static bool IsEnglishUILanguage => CultureInfo.CurrentUICulture.Name.Length == 0 || CultureInfo.CurrentUICulture.TwoLetterISOLanguageName == "en"; private static bool IsEnglishUILanguageAndRemoteExecutorSupported => IsEnglishUILanguage && RemoteExecutor.IsSupported; From 015e954c06a0972071e4afd1fbee89361eb5b3cc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 19:33:14 +0100 Subject: [PATCH 518/783] Revert "Pin the Alpine Arm32 image to previous tag (#94683)" (#95410) This reverts commit 46c8a668eb4bbc66d9eb988d2988ecc84074be10. Co-authored-by: Natalia Kondratyeva --- eng/pipelines/coreclr/templates/helix-queues-setup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml index 240c010b8c9da5..e264588ee78c91 100644 --- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml +++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml @@ -86,9 +86,9 @@ jobs: # Linux musl arm32 - ${{ if eq(parameters.platform, 'linux_musl_arm') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - (Alpine.315.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7-20230807201723-7ea784e + - (Alpine.315.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7 - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - (Alpine.315.Arm32)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7-20230807201723-7ea784e + - (Alpine.315.Arm32)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7 # Linux musl arm64 - ${{ if eq(parameters.platform, 'linux_musl_arm64') }}: From e9590aa685447f2aa3f80a8f4028e7e629b78910 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Dec 2023 14:35:57 -0300 Subject: [PATCH 519/783] Fixing wrong check (#95270) Co-authored-by: Thays Grazia --- src/mono/mono/component/debugger-agent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index 9a6906f6e272ef..1e8e27686a287e 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -11087,7 +11087,7 @@ bool mono_debugger_agent_receive_and_process_command (void) if (command_set == CMD_SET_VM && (command == CMD_VM_DISPOSE || command == CMD_VM_EXIT)) break; } - return !(command_set == CMD_SET_VM && command == CMD_VM_DISPOSE); + return (command_set == CMD_SET_VM && command == CMD_VM_DISPOSE); } static gboolean From e6210c570948db521374fe99543b430fb76cab8a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 12:52:33 +0100 Subject: [PATCH 520/783] [release/8.0-staging] Fix missing symbols for mono-aot-cross (#95505) * Fix missing symbols for mono-aot-cross With https://github.com/dotnet/runtime/pull/83903 the path to the .pdb symbol file changed to include a `PDB` subdirectory. We didn't adjust the path in mono.proj and didn't notice it because of an `Exists()` check that made this a no-op. While doing this I noticed we were also not including the .dwarf/.dbg symbols for non-Windows platforms. Fix the path and added the missing non-Windows symbols * Exclude .dwarf/.dbg when generating UnixFilePermissions.xml These files are split out from the main .nupkg so they won't exist there which causes issues when nuget tries to apply the permissions during workload install. --- ...Microsoft.NETCore.App.MonoCrossAOT.sfxproj | 3 ++- src/mono/mono.proj | 24 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.MonoCrossAOT.sfxproj b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.MonoCrossAOT.sfxproj index e01f2a6ed73b66..18fe686588392b 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.MonoCrossAOT.sfxproj +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.MonoCrossAOT.sfxproj @@ -29,6 +29,7 @@ <_ToolFile Include="$(AotCompilerPath)**" /> + <_ToolFileExcludingSymbols Include="@(_ToolFile)" Condition="'%(Extension)' != '.dwarf' and '%(Extension)' != '.dbg'" /> <_SdkPropsProperties Condition="!$([MSBuild]::IsOsPlatform('Windows'))" Include="ExeSuffix" Value="" /> @@ -36,7 +37,7 @@ <_SdkPropsProperties Include="TargetRid" Value="$(TargetCrossRid)" /> - <_PermissionsFiles>@(_ToolFile -> '<File Path="tools/%(RecursiveDir)%(FileName)%(Extension)" Permission="755" />', ' ') + <_PermissionsFiles>@(_ToolFileExcludingSymbols -> '<File Path="tools/%(RecursiveDir)%(FileName)%(Extension)" Permission="755" />', ' ') <_PermissionsProperties Include="PermissionsProperties" Value="$(_PermissionsFiles)" /> diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 6f15a31d94dca4..3122cdf153cd17 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -28,8 +28,7 @@ $(LibPrefix)$(MonoLibName)$(StaticLibSuffix) $(MonoStaticLibFileName) $(MonoSharedLibFileName) - mono-aot-cross$(ExeSuffix) - mono-aot-cross.pdb + mono-aot-cross $(Configuration) $(Configuration) $([MSBuild]::NormalizeDirectory('$(ArtifactsDir)', 'tests', 'coreclr', '$(TargetOS).$(Platform).$(CoreClrTestConfig)', 'Tests', 'Core_Root')) @@ -933,8 +932,7 @@ <_MonoIncludeInterpStaticFiles Condition="'$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true'">true - <_MonoAotCrossFilePath>$(MonoObjCrossDir)out\bin\$(MonoAotCrossFileName) - <_MonoAotCrossPdbFilePath>$(MonoObjCrossDir)out\bin\$(MonoAotCrossPdbFileName) + <_MonoAotCrossFilePath>$(MonoObjCrossDir)out\bin\$(MonoAotCrossName)$(ExeSuffix) <_MonoLLVMHostArchitecture>$(AotHostArchitecture) @@ -961,6 +959,18 @@ <_MonoRuntimeArtifacts Include="$(_MonoRuntimeStaticFilePath)" Condition="Exists($(_MonoRuntimeStaticFilePath)) and '$(_MonoRuntimeStaticFilePath)' != '$(_MonoRuntimeFilePath)'"> $(RuntimeBinDir)$(MonoStaticLibFileName) + <_MonoRuntimeArtifacts Include="$(_MonoAotCrossFilePath)" Condition="Exists($(_MonoAotCrossFilePath))"> + $(RuntimeBinDir)cross\$(OutputRID)\$(MonoAotCrossName)$(ExeSuffix) + + <_MonoRuntimeArtifacts Include="$(_MonoAotCrossFilePath).dbg" Condition="Exists('$(_MonoAotCrossFilePath).dbg')"> + $(RuntimeBinDir)cross\$(OutputRID)\$(MonoAotCrossName).dbg + + <_MonoRuntimeArtifacts Include="$(_MonoAotCrossFilePath).dwarf" Condition="Exists('$(_MonoAotCrossFilePath).dwarf')"> + $(RuntimeBinDir)cross\$(OutputRID)\$(MonoAotCrossName).dwarf + + <_MonoRuntimeArtifacts Include="$(MonoObjCrossDir)out\bin\PDB\$(MonoAotCrossName).pdb" Condition="Exists('$(MonoObjCrossDir)out\bin\PDB\$(MonoAotCrossName).pdb')"> + $(RuntimeBinDir)cross\$(OutputRID)\$(MonoAotCrossName).pdb + <_MonoRuntimeArtifacts Include="@(_MonoRuntimeComponentsStaticFilePath)"> $(RuntimeBinDir)%(_MonoRuntimeComponentsStaticFilePath.Filename)%(_MonoRuntimeComponentsStaticFilePath.Extension) @@ -968,9 +978,6 @@ <_MonoRuntimeArtifacts Include="@(_MonoRuntimeComponentsSharedFilePath)"> $(RuntimeBinDir)%(_MonoRuntimeComponentsSharedFilePath.Filename)%(_MonoRuntimeComponentsSharedFilePath.Extension) - <_MonoRuntimeArtifacts Include="$(_MonoAotCrossFilePath)"> - $(RuntimeBinDir)cross\$(OutputRID)\$(MonoAotCrossFileName) - <_MonoRuntimeArtifacts Condition="'$(HostOS)' == 'Linux' and ('$(MonoBundleLLVMOptimizer)' == 'true' or '$(MonoEnableLLVM)' == 'true') and '$(TargetArchitecture)' != 'wasm' and '$(MonoUseLibCxx)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMTargetArchitecture)\lib\libc++.so.1"> $(RuntimeBinDir)libc++.so.1 @@ -983,9 +990,6 @@ <_MonoRuntimeArtifacts Condition="'$(HostOS)' == 'Linux' and ((('$(MonoAOTBundleLLVMOptimizer)' == 'true' or '$(MonoAOTEnableLLVM)' == 'true') and '$(MonoUseLibCxx)' == 'true') or '$(TargetArchitecture)' == 'wasm')" Include="$(MonoLLVMDir)\$(_MonoLLVMHostArchitecture)\lib\libc++abi.so.1"> $(RuntimeBinDir)cross\$(OutputRID)\libc++abi.so.1 - <_MonoRuntimeArtifacts Include="$(_MonoAotCrossPdbFilePath)" Condition="Exists('$(_MonoAotCrossPdbFilePath)')"> - $(RuntimeBinDir)cross\$(OutputRID)\$(MonoAotCrossPdbFileName) - <_MonoRuntimeArtifacts Condition="'$(MonoBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\$(_MonoLLVMHostArchitecture)\bin\llc$(ExeSuffix)"> $(RuntimeBinDir)\llc$(ExeSuffix) From 54fb1218c97fd01e7cb0cbc39a7ab052c37db1d1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 12:04:05 -0800 Subject: [PATCH 521/783] Update Perf Android jobs to use the Windows 11 Pixel Queue. Co-authored-by: Parker Bibus --- eng/testing/performance/performance-setup.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/testing/performance/performance-setup.ps1 b/eng/testing/performance/performance-setup.ps1 index 8a8cd269dbe454..c18445bff8aaec 100644 --- a/eng/testing/performance/performance-setup.ps1 +++ b/eng/testing/performance/performance-setup.ps1 @@ -51,7 +51,7 @@ if ($Internal) { "perftiger_crossgen" { $Queue = "Windows.10.Amd64.19H1.Tiger.Perf" } "perfowl" { $Queue = "Windows.10.Amd64.20H2.Owl.Perf" } "perfsurf" { $Queue = "Windows.10.Arm64.Perf.Surf" } - "perfpixel4a" { $Queue = "Windows.10.Amd64.Pixel.Perf" } + "perfpixel4a" { $Queue = "Windows.11.Amd64.Pixel.Perf" } "perfampere" { $Queue = "Windows.Server.Arm64.Perf" } "cloudvm" { $Queue = "Windows.10.Amd64" } Default { $Queue = "Windows.10.Amd64.19H1.Tiger.Perf" } From 07b5d817a73ed6fad76d1c824a898b67c1b975f4 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 01:08:28 +0100 Subject: [PATCH 522/783] Update dependencies from https://github.com/dotnet/emsdk build 20231205.4 (#95661) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.1-servicing.23571.1 -> To Version 8.0.1-servicing.23605.4 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index ae4e5f1d8764d4..7082a11bd40d58 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 04ddf837a06a2d..a9e29707085353 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - 201f4dae9d1a1e105d8ba86d7ece61eed1f665e0 + c76a13a917239098265f26ecb03203e16dd70e8a - + https://github.com/dotnet/emsdk - 201f4dae9d1a1e105d8ba86d7ece61eed1f665e0 + c76a13a917239098265f26ecb03203e16dd70e8a From 953a9f3e80075043cefb4105b3fb80b64f66885b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 01:11:21 +0100 Subject: [PATCH 523/783] Bump WasmBuildTests timeout to 180min (#95662) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Looking at the data for the last 30 days a successful or failed WasmBuildTests job took between 70-90 minutes. When Helix queues are overloaded the 120min timeout can result in canceled builds which is especially true on servicing queues which first need to spin up VMs so bump the timeout to 180mins. Co-authored-by: Alexander Köplinger --- eng/pipelines/common/templates/browser-wasm-build-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/common/templates/browser-wasm-build-tests.yml b/eng/pipelines/common/templates/browser-wasm-build-tests.yml index 28d659e1607f48..742ad88de1c80a 100644 --- a/eng/pipelines/common/templates/browser-wasm-build-tests.yml +++ b/eng/pipelines/common/templates/browser-wasm-build-tests.yml @@ -110,7 +110,7 @@ jobs: /p:InstallWorkloadForTesting=true /p:WasmSkipMissingRuntimePackBuild=true /p:PreparePackagesForWorkloadInstall=false - timeoutInMinutes: 120 + timeoutInMinutes: 180 condition: >- or( eq(variables['alwaysRunVar'], true), From 97242c43427de648f60ebbf39b49d298bec3d22a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:11:33 +0100 Subject: [PATCH 524/783] Add optimized property to the Native AOT sample app (#95640) Co-authored-by: Milos Kotlar --- src/mono/sample/iOS-NativeAOT/Program.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mono/sample/iOS-NativeAOT/Program.csproj b/src/mono/sample/iOS-NativeAOT/Program.csproj index 45b0a262bdea77..4bf35ce171a195 100644 --- a/src/mono/sample/iOS-NativeAOT/Program.csproj +++ b/src/mono/sample/iOS-NativeAOT/Program.csproj @@ -9,6 +9,7 @@ $(TargetOS)-$(TargetArchitecture) HelloiOS true + true true false static From 26e7d2d9f387a7acf1fcbd5bffadfd56d16340a0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:19:50 +0100 Subject: [PATCH 525/783] [release/8.0-staging] Catch exception when subscribing to NetworkChange (#95123) * Catch exception when subscribing to NetworkChange * Code review feedback --------- Co-authored-by: Radek Zikmund --- .../HttpConnectionPoolManager.cs | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs index a2a39db41aaaad..75b27b6b3b1efe 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs @@ -174,9 +174,29 @@ public void StartMonitoringNetworkChanges() return; } - using (ExecutionContext.SuppressFlow()) + // RFC: https://tools.ietf.org/html/rfc7838#section-2.2 + // When alternative services are used to send a client to the most + // optimal server, a change in network configuration can result in + // cached values becoming suboptimal. Therefore, clients SHOULD remove + // from cache all alternative services that lack the "persist" flag with + // the value "1" when they detect such a change, when information about + // network state is available. + try + { + using (ExecutionContext.SuppressFlow()) + { + NetworkChange.NetworkAddressChanged += networkChangedDelegate; + } + } + catch (NetworkInformationException e) { - NetworkChange.NetworkAddressChanged += networkChangedDelegate; + if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, $"Exception when subscribing to NetworkChange.NetworkAddressChanged: {e}"); + + // We can't monitor network changes, so technically "information + // about network state is not available" and we can just keep + // all Alt-Svc entries until their expiration time. + // + // keep the _networkChangeCleanup field assigned so we don't try again needlessly } } From 3e8927fbe5e883398e1834bd78c027eddd036ad7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 17:19:48 +0100 Subject: [PATCH 526/783] [mono][System.Reflection.Emit] Fix explicitly setting the return type on a dynamic method (#95271) Co-authored-by: Ivan Povazan --- .../tests/MethodBuilder/MethodBuilderSetReturnType.cs | 1 - .../src/System/Reflection/Emit/RuntimeMethodBuilder.Mono.cs | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Reflection.Emit/tests/MethodBuilder/MethodBuilderSetReturnType.cs b/src/libraries/System.Reflection.Emit/tests/MethodBuilder/MethodBuilderSetReturnType.cs index 6245fbb2dccf26..7fe59ee9b09da2 100644 --- a/src/libraries/System.Reflection.Emit/tests/MethodBuilder/MethodBuilderSetReturnType.cs +++ b/src/libraries/System.Reflection.Emit/tests/MethodBuilder/MethodBuilderSetReturnType.cs @@ -132,7 +132,6 @@ public void SetReturnType_TypeCreated_Works() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] public void SetReturnType_NullReturnType_ReturnsVoid() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Abstract); diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.Mono.cs index 8e4503ce9934f9..4083d7378ac1a8 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.Mono.cs @@ -603,7 +603,9 @@ protected override void SetSignatureCore(Type? returnType, Type[]? returnTypeReq Array.Copy(parameterTypes, this.parameters, parameterTypes.Length); } - rtype = returnType; + if (returnType != null) + rtype = returnType; + returnModReq = returnTypeRequiredCustomModifiers; returnModOpt = returnTypeOptionalCustomModifiers; paramModReq = parameterTypeRequiredCustomModifiers; From 287e3e25097e54bfdcf18505421b97fb285abb77 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:19:37 -0500 Subject: [PATCH 527/783] [mono][jit] Fix the bblock check in the box+callvirt optimization. (#95500) Fixes https://github.com/dotnet/runtime/issues/95347. Co-authored-by: Zoltan Varga --- src/mono/mono/mini/method-to-ir.c | 5 ++--- .../JitBlue/Runtime_95347/Runtime_95347.cs | 16 ++++++++++++++++ .../JitBlue/Runtime_95347/Runtime_95347.csproj | 8 ++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_95347/Runtime_95347.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_95347/Runtime_95347.csproj diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index dedc6804c3cbd8..eb0ab5f4e296c9 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -9707,12 +9707,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b // callvirt instance ISomeIface::Method() // TO // call SomeStruct::Method() - guchar* callvirt_ip; guint32 callvirt_proc_token; if (!((cfg->compile_aot || cfg->compile_llvm) && !mono_class_is_def(klass)) && // we cannot devirtualize in AOT when using generics next_ip < end && - (callvirt_ip = il_read_callvirt (next_ip, end, &callvirt_proc_token)) && - ip_in_bb (cfg, cfg->cbb, callvirt_ip) ) { + il_read_callvirt (next_ip, end, &callvirt_proc_token) && + ip_in_bb (cfg, cfg->cbb, next_ip) ) { MonoMethod* iface_method; MonoMethodSignature* iface_method_sig; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_95347/Runtime_95347.cs b/src/tests/JIT/Regression/JitBlue/Runtime_95347/Runtime_95347.cs new file mode 100644 index 00000000000000..594d61a4773620 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_95347/Runtime_95347.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Xunit; + +public static class Runtime_95347 +{ + [Fact] + public static int Test() + { + object? n = "abcd"; + var s = (n ?? false).ToString(); + return (s == "abcd") ? 100 : -1; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_95347/Runtime_95347.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_95347/Runtime_95347.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_95347/Runtime_95347.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From a78ff1ac1bc27d2edc7740f1aba85d442a00396e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 12:24:01 +0100 Subject: [PATCH 528/783] [release/8.0-staging] [browser] Fix debug URL in lauchSettings.json in wasmbrowser template (#95418) --- .../templates/templates/browser/Properties/launchSettings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/templates/templates/browser/Properties/launchSettings.json b/src/mono/wasm/templates/templates/browser/Properties/launchSettings.json index 4807594b8f5fa2..79ae7c71629403 100644 --- a/src/mono/wasm/templates/templates/browser/Properties/launchSettings.json +++ b/src/mono/wasm/templates/templates/browser/Properties/launchSettings.json @@ -7,7 +7,7 @@ "ASPNETCORE_ENVIRONMENT": "Development" }, "applicationUrl": "https://localhost:5001;http://localhost:5000", - "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/debug?browser={browserInspectUri}" + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", } } } From 2b516fb055c4dc846210a3403d9f7edf1b749fcf Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 18:30:56 +0100 Subject: [PATCH 529/783] [release/8.0-staging] Update dependencies from dotnet/runtime-assets (#95788) * Update dependencies from https://github.com/dotnet/runtime-assets build 20231207.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23566.1 -> To Version 8.0.0-beta.23607.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20231207.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23566.1 -> To Version 8.0.0-beta.23607.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20231207.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23566.1 -> To Version 8.0.0-beta.23607.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20231207.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23566.1 -> To Version 8.0.0-beta.23607.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20231207.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23566.1 -> To Version 8.0.0-beta.23607.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20231207.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23566.1 -> To Version 8.0.0-beta.23607.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20231207.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23566.1 -> To Version 8.0.0-beta.23607.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20231207.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23566.1 -> To Version 8.0.0-beta.23607.1 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 56 ++++++++++++++++++++--------------------- eng/Versions.props | 28 ++++++++++----------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a9e29707085353..d0cf4f052ff9ed 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -185,57 +185,57 @@ https://github.com/dotnet/arcade 0aaeafef60933f87b0b50350313bb2fd77defb5d - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa https://github.com/dotnet/llvm-project @@ -358,9 +358,9 @@ https://github.com/dotnet/hotreload-utils e12b15aff28e365850ffa713b5b5afdc24470a04 - + https://github.com/dotnet/runtime-assets - 57ca3048e3bf7c0755add6569809270290040f5d + dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index 6c001d0ac032e0..29c7ca9eb6e028 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -143,20 +143,20 @@ 4.5.0 8.0.0-rc.1.23406.6 - 8.0.0-beta.23566.1 - 8.0.0-beta.23566.1 - 8.0.0-beta.23566.1 - 8.0.0-beta.23566.1 - 8.0.0-beta.23566.1 - 8.0.0-beta.23566.1 - 8.0.0-beta.23566.1 - 8.0.0-beta.23566.1 - 8.0.0-beta.23566.1 - 8.0.0-beta.23566.1 - 8.0.0-beta.23566.1 - 8.0.0-beta.23566.1 - 8.0.0-beta.23566.1 - 8.0.0-beta.23566.1 + 8.0.0-beta.23607.1 + 8.0.0-beta.23607.1 + 8.0.0-beta.23607.1 + 8.0.0-beta.23607.1 + 8.0.0-beta.23607.1 + 8.0.0-beta.23607.1 + 8.0.0-beta.23607.1 + 8.0.0-beta.23607.1 + 8.0.0-beta.23607.1 + 8.0.0-beta.23607.1 + 8.0.0-beta.23607.1 + 8.0.0-beta.23607.1 + 8.0.0-beta.23607.1 + 8.0.0-beta.23607.1 1.0.0-prerelease.23566.3 1.0.0-prerelease.23566.3 From de3f0c77f02a8dec67821243b38922759ab3fbc4 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 18:35:13 +0100 Subject: [PATCH 530/783] [release/8.0-staging] Update dependencies from dotnet/roslyn-analyzers (#95821) * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231208.1 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23525.2 -> To Version 3.11.0-beta1.23608.1 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231208.1 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23525.2 -> To Version 3.11.0-beta1.23608.1 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231208.1 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23525.2 -> To Version 3.11.0-beta1.23608.1 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231208.1 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23525.2 -> To Version 3.11.0-beta1.23608.1 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231208.1 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23525.2 -> To Version 3.11.0-beta1.23608.1 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231208.1 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23525.2 -> To Version 3.11.0-beta1.23608.1 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231208.1 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23525.2 -> To Version 3.11.0-beta1.23608.1 * Update dependencies from https://github.com/dotnet/roslyn-analyzers build 20231214.1 Microsoft.CodeAnalysis.Analyzers , Microsoft.CodeAnalysis.NetAnalyzers From Version 3.11.0-beta1.23525.2 -> To Version 3.11.0-beta1.23614.1 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d0cf4f052ff9ed..3027b3381e799b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -375,13 +375,13 @@ https://github.com/dotnet/roslyn 7b75981cf3bd520b86ec4ed00ec156c8bc48e4eb - + https://github.com/dotnet/roslyn-analyzers - b4d9a1334d5189172977ba8fddd00bda70161e4a + abef8ced132657943b7150f01a308e2199a17d5d - + https://github.com/dotnet/roslyn-analyzers - b4d9a1334d5189172977ba8fddd00bda70161e4a + abef8ced132657943b7150f01a308e2199a17d5d https://github.com/dotnet/sdk diff --git a/eng/Versions.props b/eng/Versions.props index 29c7ca9eb6e028..1b969eeba87e52 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -36,8 +36,8 @@ - 3.11.0-beta1.23525.2 - 8.0.0-preview.23525.2 + 3.11.0-beta1.23614.1 + 8.0.0-preview.23614.1 - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e517c860cb1767..8dfbf4b746988e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - c76a13a917239098265f26ecb03203e16dd70e8a + 9be4a716fd007be9be89d6acea302bd15bfb165d - + https://github.com/dotnet/emsdk - c76a13a917239098265f26ecb03203e16dd70e8a + 9be4a716fd007be9be89d6acea302bd15bfb165d From a9dcde851da3767c9c5744939b2beae6d62af24e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 09:16:01 +0100 Subject: [PATCH 533/783] [release/8.0-staging] [browser][fix] maxParallelDownloads (#95870) * fix https://github.com/dotnet/runtime/issues/95491 * Remove change to sample --------- Co-authored-by: pavelsavara Co-authored-by: Larry Ewing --- src/mono/wasm/runtime/loader/assets.ts | 2 -- src/mono/wasm/runtime/loader/config.ts | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/runtime/loader/assets.ts b/src/mono/wasm/runtime/loader/assets.ts index be7c0e4592938b..02e05b1f8a9622 100644 --- a/src/mono/wasm/runtime/loader/assets.ts +++ b/src/mono/wasm/runtime/loader/assets.ts @@ -146,8 +146,6 @@ export function resolve_single_asset_path(behavior: SingleAssetBehaviors): Asset export async function mono_download_assets(): Promise { mono_log_debug("mono_download_assets"); - loaderHelpers.maxParallelDownloads = loaderHelpers.config.maxParallelDownloads || loaderHelpers.maxParallelDownloads; - loaderHelpers.enableDownloadRetry = loaderHelpers.config.enableDownloadRetry || loaderHelpers.enableDownloadRetry; try { const promises_of_assets: Promise[] = []; diff --git a/src/mono/wasm/runtime/loader/config.ts b/src/mono/wasm/runtime/loader/config.ts index 097f6d1ca2cb15..d9bcccd4ed933c 100644 --- a/src/mono/wasm/runtime/loader/config.ts +++ b/src/mono/wasm/runtime/loader/config.ts @@ -212,6 +212,9 @@ export function normalizeConfig() { runtimeHelpers.enablePerfMeasure = !!config.browserProfilerOptions && globalThis.performance && typeof globalThis.performance.measure === "function"; + + loaderHelpers.maxParallelDownloads = config.maxParallelDownloads || loaderHelpers.maxParallelDownloads; + loaderHelpers.enableDownloadRetry = config.enableDownloadRetry !== undefined ? config.enableDownloadRetry : loaderHelpers.enableDownloadRetry; } let configLoaded = false; From 5f88db2abe61cf2b926b5c43bc5e0b29128ab297 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 08:21:24 -0800 Subject: [PATCH 534/783] Update osx.1015 to osx.13. (#96148) Co-authored-by: Parker Bibus --- eng/testing/performance/performance-setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/testing/performance/performance-setup.sh b/eng/testing/performance/performance-setup.sh index c53ca6924b97b4..4853f0e6fb3bdb 100755 --- a/eng/testing/performance/performance-setup.sh +++ b/eng/testing/performance/performance-setup.sh @@ -275,7 +275,7 @@ if [[ "$internal" == true ]]; then extra_benchmark_dotnet_arguments= if [[ "$logical_machine" == "perfiphone12mini" ]]; then - queue=OSX.1015.Amd64.Iphone.Perf + queue=OSX.13.Amd64.Iphone.Perf elif [[ "$logical_machine" == "perfampere" ]]; then queue=Ubuntu.2004.Arm64.Perf elif [[ "$logical_machine" == "cloudvm" ]]; then From 5ab6c2f32900db0873f3788c1ee825e57cc1b30f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 27 Dec 2023 09:48:12 +0100 Subject: [PATCH 535/783] Update dependencies from https://github.com/dotnet/hotreload-utils build 20231218.2 (#96135) Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23611.2 -> To Version 8.0.0-alpha.0.23618.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8dfbf4b746988e..ffd224e565faf1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -354,9 +354,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 67613417f5e1af250e6ddfba79f8f2885d8e90fb - + https://github.com/dotnet/hotreload-utils - d1d735fd0cac6b08578861b3b43183ba3eed29ca + 4fb0eb65850bcfed5b6bdb171b447f9da2945a11 https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index 12c2830965c014..77645744dfd548 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -186,7 +186,7 @@ 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 - 8.0.0-alpha.0.23611.2 + 8.0.0-alpha.0.23618.2 2.4.2 1.0.0 2.4.5 From 947da187a9e6d703a33aa0be73a89db97e73b05f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 09:16:48 -0800 Subject: [PATCH 536/783] Improve the hash function used in the `InstMethodHashTable` (#95285) Instead of using the TypeDef token of the MethodTable, use the TypeHandle pointer instead. This is both faster to compute, and is more unique, as the TypeDef token could be shared across multiple types in different assemblies, and if the type is generic itself, it could be shared across multiple different instantiations of the type. Improves the benchmark mentioned in isseu #94936 such that the cost is about 24 seconds, and the time in spent is spent almost entirely in the JIT, as should be expected. Fixes #94936 Co-authored-by: David Wrighton --- src/coreclr/vm/instmethhash.cpp | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/coreclr/vm/instmethhash.cpp b/src/coreclr/vm/instmethhash.cpp index 2cb27b86fa9df4..cdb8b8617dec88 100644 --- a/src/coreclr/vm/instmethhash.cpp +++ b/src/coreclr/vm/instmethhash.cpp @@ -96,30 +96,19 @@ static DWORD Hash(TypeHandle declaringType, mdMethodDef token, Instantiation ins DWORD dwHash = 0x87654321; #define INST_HASH_ADD(_value) dwHash = ((dwHash << 5) + dwHash) ^ (_value) +#ifdef TARGET_64BIT +#define INST_HASH_ADDPOINTER(_value) INST_HASH_ADD((uint32_t)(uintptr_t)_value); INST_HASH_ADD((uint32_t)(((uintptr_t)_value) >> 32)) +#else +#define INST_HASH_ADDPOINTER(_value) INST_HASH_ADD((uint32_t)(uintptr_t)_value); +#endif - INST_HASH_ADD(declaringType.GetCl()); + INST_HASH_ADDPOINTER(declaringType.AsPtr()); INST_HASH_ADD(token); for (DWORD i = 0; i < inst.GetNumArgs(); i++) { TypeHandle thArg = inst[i]; - - if (thArg.GetMethodTable()) - { - INST_HASH_ADD(thArg.GetCl()); - - Instantiation sArgInst = thArg.GetInstantiation(); - for (DWORD j = 0; j < sArgInst.GetNumArgs(); j++) - { - TypeHandle thSubArg = sArgInst[j]; - if (thSubArg.GetMethodTable()) - INST_HASH_ADD(thSubArg.GetCl()); - else - INST_HASH_ADD(thSubArg.GetSignatureCorElementType()); - } - } - else - INST_HASH_ADD(thArg.GetSignatureCorElementType()); + INST_HASH_ADDPOINTER(thArg.AsPtr()); } return dwHash; From a29f2fad4c56a985e11394bef1f727f7a8bcd80d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 09:17:29 -0800 Subject: [PATCH 537/783] Fixes for Bionic on x64 (#95382) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #93942. Works around #95223 (a better but more risky fix is in #95312, so I'm not going to resolve that with this PR). The first issue is that we don't consider x64 Windows (or x64 Linux) to x64 Bionic build a crossbuild. The crossbuild detection only looks at architecture, not at the OS. The fix is very conservative so that we can backport to 8.0. Bionic is always a crossbuild. The second part is a port of https://github.com/dotnet/corert/pull/8323 to x64. It is a lot less work than on arm64 because x64 Linux already has to assume `INLINE_GETTHREAD` could be a call so everything is setup for it. I tested this all on a x64 Bionic hello world. I also ran all of smoke tests on x64 Linux with `FEATURE_EMULATED_TLS` enabled. All of this looks very non-risky so I'm going to ask for a backport. Co-authored-by: Michal Strehovský --- .../BuildIntegration/Microsoft.NETCore.Native.Unix.targets | 1 + src/coreclr/nativeaot/Runtime/amd64/InteropThunksHelpers.S | 6 ++++++ src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 1f5b2cd681095c..28a140c17592a3 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -33,6 +33,7 @@ The .NET Foundation licenses this file to you under the MIT license. $(RuntimeIdentifier) + $(RuntimeIdentifier) x86_64 diff --git a/src/coreclr/nativeaot/Runtime/amd64/InteropThunksHelpers.S b/src/coreclr/nativeaot/Runtime/amd64/InteropThunksHelpers.S index 5c0b6f631ef539..a53dd3c63624f6 100644 --- a/src/coreclr/nativeaot/Runtime/amd64/InteropThunksHelpers.S +++ b/src/coreclr/nativeaot/Runtime/amd64/InteropThunksHelpers.S @@ -14,7 +14,11 @@ LEAF_ENTRY RhCommonStub, _TEXT alloc_stack SIZEOF_FP_REGS SAVE_FLOAT_ARGUMENT_REGISTERS 0 +#ifdef FEATURE_EMULATED_TLS + call C_FUNC(RhpGetThunkData) +#else INLINE_GET_TLS_VAR tls_thunkData +#endif RESTORE_FLOAT_ARGUMENT_REGISTERS 0 free_stack SIZEOF_FP_REGS @@ -36,6 +40,7 @@ LEAF_ENTRY RhGetCommonStubAddress, _TEXT LEAF_END RhGetCommonStubAddress, _TEXT +#ifndef FEATURE_EMULATED_TLS LEAF_ENTRY RhGetCurrentThunkContext, _TEXT INLINE_GET_TLS_VAR tls_thunkData @@ -43,3 +48,4 @@ LEAF_ENTRY RhGetCurrentThunkContext, _TEXT mov rax, qword ptr [rax] ret LEAF_END RhGetCurrentThunkContext, _TEXT +#endif //FEATURE_EMULATED_TLS diff --git a/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc b/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc index ab64ef9ce92b49..11225c0ad5ed2b 100644 --- a/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc +++ b/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc @@ -300,8 +300,12 @@ C_FUNC(\Name): .macro INLINE_GETTHREAD +#ifdef FEATURE_EMULATED_TLS + call C_FUNC(RhpGetThread) +#else // Inlined version of call C_FUNC(RhpGetThread) INLINE_GET_TLS_VAR tls_CurrentThread +#endif .endm .macro INLINE_THREAD_UNHIJACK threadReg, trashReg1, trashReg2 From 10bf9a05a1413d6bc54d50ff63581e5daaa074c3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 09:17:36 -0800 Subject: [PATCH 538/783] Avoid handing out duplicate `CORINFO_MODULE_STRUCT_*` handles (#95499) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RyuJIT depends on never seeing two different `CORINFO_MODULE_STRUCT` for the same thing. Fixes #93843. Co-authored-by: Michal Strehovský --- .../tools/Common/JitInterface/CorInfoImpl.cs | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 9d98650b91bbb9..01d2d15fc2997e 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -707,9 +707,15 @@ private void CompileMethodCleanup() _instantiationToJitVisibleInstantiation = null; _pgoResults.Clear(); + + // We need to clear out this cache because the next compilation could actually come up + // with a different MethodIL for the same MethodDesc. This happens when we need to replace + // a MethodIL with a throw helper. + _methodILScopeToHandle.Clear(); } private Dictionary _objectToHandle = new Dictionary(new JitObjectComparer()); + private Dictionary _methodILScopeToHandle = new Dictionary(new JitObjectComparer()); private List _handleToObject = new List(); private const int handleMultiplier = 8; @@ -720,6 +726,13 @@ private void CompileMethodCleanup() #endif private IntPtr ObjectToHandle(object obj) + { + // MethodILScopes need to go through ObjectToHandle(MethodILScope methodIL). + Debug.Assert(obj is not MethodILScope); + return ObjectToHandleUnchecked(obj); + } + + private IntPtr ObjectToHandleUnchecked(object obj) { // SuperPMI relies on the handle returned from this function being stable for the lifetime of the crossgen2 process // If handle deletion is implemented, please update SuperPMI @@ -752,10 +765,19 @@ private object HandleToObject(void* handle) private FieldDesc HandleToObject(CORINFO_FIELD_STRUCT_* field) => (FieldDesc)HandleToObject((void*)field); private CORINFO_FIELD_STRUCT_* ObjectToHandle(FieldDesc field) => (CORINFO_FIELD_STRUCT_*)ObjectToHandle((object)field); private MethodILScope HandleToObject(CORINFO_MODULE_STRUCT_* module) => (MethodIL)HandleToObject((void*)module); - private CORINFO_MODULE_STRUCT_* ObjectToHandle(MethodILScope methodIL) => (CORINFO_MODULE_STRUCT_*)ObjectToHandle((object)methodIL); private MethodSignature HandleToObject(MethodSignatureInfo* method) => (MethodSignature)HandleToObject((void*)method); private MethodSignatureInfo* ObjectToHandle(MethodSignature method) => (MethodSignatureInfo*)ObjectToHandle((object)method); + private CORINFO_MODULE_STRUCT_* ObjectToHandle(MethodILScope methodIL) + { + // RyuJIT requires CORINFO_MODULE_STRUCT to be unique. MethodILScope might not be unique + // due to ILProvider cache purging. See https://github.com/dotnet/runtime/issues/93843. + MethodDesc owningMethod = methodIL.OwningMethod; + if (!_methodILScopeToHandle.TryGetValue(owningMethod, out IntPtr handle)) + _methodILScopeToHandle[owningMethod] = handle = ObjectToHandleUnchecked((object)methodIL); + return (CORINFO_MODULE_STRUCT_*)handle; + } + private bool Get_CORINFO_METHOD_INFO(MethodDesc method, MethodIL methodIL, CORINFO_METHOD_INFO* methodInfo) { if (methodIL == null) From 14a32f88bfd3b90c6d491d08df088bd58fd61d87 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 09:17:46 -0800 Subject: [PATCH 539/783] JIT: fix issue with out of order importer spilling around some calls (#95587) If we have a call that returns a struct that is immediately assigned to some local, the call is a GDV inline candidate, and the call is invoked with a copy of the same local on the evaluation stack, the spill of that local into a temp will appear in the IR stream between the call and the ret expr, instead of before the call. As part of our IR resolution the store to the local gets "sunk" into the call as the hidden return buffer, so the importer ordering is manifestly incorrect: ``` call &retbuf, ... tmp = retbuf ...ret-expr ...tmp ``` For normal inline candidates this mis-ordering gets fixed up either by swapping the call back into the ret expr's position, or for successful inlines by swapping the return value store into the ret expr's position. The JIT has behaved this way for a very long time, and the transient mis-ordering has not lead to any noticble problem. For GDV calls the return value stores are done earlier, just after the call, and so the spill picks up the wrong value. GDV calls normally only happen with PGO data. This persistent mis-ordering has been the behavior since at least 6.0, but now that PGO is enabled by default a much wider set of programs are at risk of running into it. The fix here is to reorder the IR in the importer at the point the store to the local is appended to the IR stream, as we are processing spills for the local. If the source of the store is a GT_RET_EXPR we keep track of these spills, find the associated GT_CALL statement, and move the spills before the call. There was a similar fix made for boxes in #60335, where once again the splitting of the inline candidate call and the subsequent modification of the call to write directly to the return buffer local led to similar problems with GDV calls. Fixes #95394. Co-authored-by: Andy Ayers --- src/coreclr/jit/importer.cpp | 39 ++++++++++++ .../JitBlue/Runtime_95349/Runtime_95349.cs | 61 +++++++++++++++++++ .../Runtime_95349/Runtime_95349.csproj | 9 +++ 3 files changed, 109 insertions(+) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_95349/Runtime_95349.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_95349/Runtime_95349.csproj diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index e8fa8a3db39eeb..b621f7822997b6 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -453,6 +453,11 @@ void Compiler::impAppendStmt(Statement* stmt, unsigned chkLevel, bool checkConsu } } + // In the case of GT_RET_EXPR any subsequent spills will appear in the wrong place -- after + // the call. We need to move them to before the call + // + Statement* lastStmt = impLastStmt; + if ((dstVarDsc != nullptr) && !dstVarDsc->IsAddressExposed() && !dstVarDsc->lvHasLdAddrOp) { impSpillLclRefs(lvaGetLclNum(dstVarDsc), chkLevel); @@ -480,6 +485,40 @@ void Compiler::impAppendStmt(Statement* stmt, unsigned chkLevel, bool checkConsu { impSpillSpecialSideEff(); } + + if ((lastStmt != impLastStmt) && expr->OperIs(GT_RET_EXPR)) + { + GenTree* const call = expr->AsRetExpr()->gtInlineCandidate; + JITDUMP("\nimpAppendStmt: after sinking a local struct store into inline candidate [%06u], we need to " + "reorder subsequent spills.\n", + dspTreeID(call)); + + // Move all newly appended statements to just before the call's statement. + // First, find the statement containing the call. + // + Statement* insertBeforeStmt = lastStmt; + + while (insertBeforeStmt->GetRootNode() != call) + { + assert(insertBeforeStmt != impStmtList); + insertBeforeStmt = insertBeforeStmt->GetPrevStmt(); + } + + Statement* movingStmt = lastStmt->GetNextStmt(); + + JITDUMP("Moving " FMT_STMT " through " FMT_STMT " before " FMT_STMT "\n", movingStmt->GetID(), + impLastStmt->GetID(), insertBeforeStmt->GetID()); + + // We move these backwards, so must keep moving the insert + // point to keep them in order. + // + while (impLastStmt != lastStmt) + { + Statement* movingStmt = impExtractLastStmt(); + impInsertStmtBefore(movingStmt, insertBeforeStmt); + insertBeforeStmt = movingStmt; + } + } } impAppendStmtCheck(stmt, chkLevel); diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_95349/Runtime_95349.cs b/src/tests/JIT/Regression/JitBlue/Runtime_95349/Runtime_95349.cs new file mode 100644 index 00000000000000..95cb943a4f6d05 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_95349/Runtime_95349.cs @@ -0,0 +1,61 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Issues with stack spill ordering around some GDVs +// Compile with None + +using System; +using System.Runtime.CompilerServices; +using System.Threading; +using Xunit; + +class P +{ + virtual public (double x, double y) XY() => (0, 0); +} + +class P1 : P +{ + override public (double x, double y) XY() => (1, 2); +} + +public class Runtime_95349 +{ + [MethodImpl(MethodImplOptions.NoInlining)] + static int Problem(P p, int n, (double x, double y) tuple) + { + int wn = 0; + for (int i = 0; i < n; i++) + { + (double x, double y) tupleTmp = tuple; + tuple = p.XY(); + (_, double f) = tupleTmp; + wn = Wn(wn, f, tuple.y); + } + + return wn; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static int Wn(int wn, double f, double y) + { + wn += (f == -1) ? 1 : 0; + return wn; + } + + [Fact] + public static void Test() + { + P p = new P1(); + int n = 100_000; + for (int i = 0; i < 100; i++) + { + _ = Problem(p, n, (-1, -1)); + Thread.Sleep(30); + } + + int r = Problem(p, n, (-1, -1)); + Console.WriteLine($"r = {r} (expected 1)"); + Assert.Equal(1, r); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_95349/Runtime_95349.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_95349/Runtime_95349.csproj new file mode 100644 index 00000000000000..1bb887ea34b0fc --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_95349/Runtime_95349.csproj @@ -0,0 +1,9 @@ + + + True + None + + + + + \ No newline at end of file From 758ae990a99322a088b976d2c1ca3eb25bec308d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 09:17:55 -0800 Subject: [PATCH 540/783] [release/8.0-staging] Add CFG build for EventPipe enabled (#95721) * Add a CFG build for eventpipe-enabled library * Add an EventPipe test with Control flow guard * restrict control flow to windows --------- Co-authored-by: Andy Gocke Co-authored-by: Lakshan Fernando --- src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt | 3 +++ .../simpleruntimeeventvalidation.csproj | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt index cedb910ac093ea..27f07197287994 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt @@ -158,12 +158,15 @@ add_library(eventpipe-enabled STATIC ${EVENTPIPE_SOURCES}) add_library(eventpipe-disabled STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES}) if (CLR_CMAKE_TARGET_WIN32) + add_library(eventpipe-enabled.GuardCF STATIC ${EVENTPIPE_SOURCES}) add_library(eventpipe-disabled.GuardCF STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES}) + target_compile_options(eventpipe-enabled.GuardCF PRIVATE $<$,$>:/guard:cf>) target_compile_options(eventpipe-disabled.GuardCF PRIVATE $<$,$>:/guard:cf>) endif (CLR_CMAKE_TARGET_WIN32) install_static_library(eventpipe-enabled aotsdk nativeaot) install_static_library(eventpipe-disabled aotsdk nativeaot) if (CLR_CMAKE_TARGET_WIN32) + install_static_library(eventpipe-enabled.GuardCF aotsdk nativeaot) install_static_library(eventpipe-disabled.GuardCF aotsdk nativeaot) endif (CLR_CMAKE_TARGET_WIN32) diff --git a/src/tests/tracing/eventpipe/simpleruntimeeventvalidation/simpleruntimeeventvalidation.csproj b/src/tests/tracing/eventpipe/simpleruntimeeventvalidation/simpleruntimeeventvalidation.csproj index 18068018243a0b..77d69f8280dcd5 100644 --- a/src/tests/tracing/eventpipe/simpleruntimeeventvalidation/simpleruntimeeventvalidation.csproj +++ b/src/tests/tracing/eventpipe/simpleruntimeeventvalidation/simpleruntimeeventvalidation.csproj @@ -8,6 +8,11 @@ true true + + + guard + + From 8931c136c7f4ffcdb2414b06da7b96442d837ca0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 09:18:04 -0800 Subject: [PATCH 541/783] clean up the thread local memory regardless of managed thread's is around (#95722) Co-authored-by: Kunal Pathak --- src/coreclr/vm/ceemain.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index 1c58c941fb21ac..218cda11d7f0e2 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -1752,9 +1752,9 @@ struct TlsDestructionMonitor GCX_COOP_NO_DTOR_END(); } thread->DetachThread(TRUE); - DeleteThreadLocalMemory(); } + DeleteThreadLocalMemory(); ThreadDetaching(); } } @@ -1786,16 +1786,11 @@ void DeleteThreadLocalMemory() t_ThreadStatics.NonGCMaxThreadStaticBlocks = 0; t_ThreadStatics.GCMaxThreadStaticBlocks = 0; - if (t_ThreadStatics.NonGCThreadStaticBlocks != nullptr) - { - delete[] t_ThreadStatics.NonGCThreadStaticBlocks; - t_ThreadStatics.NonGCThreadStaticBlocks = nullptr; - } - if (t_ThreadStatics.GCThreadStaticBlocks != nullptr) - { - delete[] t_ThreadStatics.GCThreadStaticBlocks; - t_ThreadStatics.GCThreadStaticBlocks = nullptr; - } + delete[] t_ThreadStatics.NonGCThreadStaticBlocks; + t_ThreadStatics.NonGCThreadStaticBlocks = nullptr; + + delete[] t_ThreadStatics.GCThreadStaticBlocks; + t_ThreadStatics.GCThreadStaticBlocks = nullptr; } #ifdef DEBUGGING_SUPPORTED From b51b8a5ec0bcdaaae3a3047d131770435b56b658 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 09:18:12 -0800 Subject: [PATCH 542/783] [NativeAOT/Apple] Map the thunks using vm_allocate/vm_map to avoid need for specific executable segment layout (#95964) Co-authored-by: Filip Navara --- .../Microsoft.NETCore.Native.Unix.targets | 4 -- src/coreclr/nativeaot/Runtime/PalRedhawk.h | 2 +- .../nativeaot/Runtime/ThunksMapping.cpp | 6 +- .../nativeaot/Runtime/amd64/ThunkPoolThunks.S | 11 +-- .../nativeaot/Runtime/arm64/ThunkPoolThunks.S | 11 +-- .../nativeaot/Runtime/unix/PalRedhawkUnix.cpp | 69 ++++++++++--------- .../Runtime/windows/PalRedhawkMinWin.cpp | 2 +- 7 files changed, 45 insertions(+), 60 deletions(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 28a140c17592a3..71acdacdadd10a 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -123,10 +123,6 @@ The .NET Foundation licenses this file to you under the MIT license. - - - - diff --git a/src/coreclr/nativeaot/Runtime/PalRedhawk.h b/src/coreclr/nativeaot/Runtime/PalRedhawk.h index d15969eab3784b..581fbf29d12e9f 100644 --- a/src/coreclr/nativeaot/Runtime/PalRedhawk.h +++ b/src/coreclr/nativeaot/Runtime/PalRedhawk.h @@ -752,7 +752,7 @@ REDHAWK_PALIMPORT uint32_t REDHAWK_PALAPI PalEventWrite(REGHANDLE arg1, const EV #endif REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalAllocateThunksFromTemplate(_In_ HANDLE hTemplateModule, uint32_t templateRva, size_t templateSize, _Outptr_result_bytebuffer_(templateSize) void** newThunksOut); -REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(_In_ void *pBaseAddress); +REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(_In_ void *pBaseAddress, size_t templateSize); REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalMarkThunksAsValidCallTargets( void *virtualAddress, diff --git a/src/coreclr/nativeaot/Runtime/ThunksMapping.cpp b/src/coreclr/nativeaot/Runtime/ThunksMapping.cpp index 2b877fc9bfd226..68a346596b529f 100644 --- a/src/coreclr/nativeaot/Runtime/ThunksMapping.cpp +++ b/src/coreclr/nativeaot/Runtime/ThunksMapping.cpp @@ -329,6 +329,7 @@ EXTERN_C NATIVEAOT_API void* __cdecl RhAllocateThunksMapping() int thunkBlockSize = RhpGetThunkBlockSize(); int templateSize = thunkBlocksPerMapping * thunkBlockSize; +#ifndef TARGET_APPLE // Apple platforms cannot use the initial template if (pThunksTemplateAddress == NULL) { // First, we use the thunks directly from the thunks template sections in the module until all @@ -337,12 +338,13 @@ EXTERN_C NATIVEAOT_API void* __cdecl RhAllocateThunksMapping() pThunkMap = pThunksTemplateAddress; } else +#endif { // We've already used the thunks template in the module for some previous thunks, and we // cannot reuse it here. Now we need to create a new mapping of the thunks section in order to have // more thunks - uint8_t* pModuleBase = (uint8_t*)PalGetModuleHandleFromPointer(pThunksTemplateAddress); + uint8_t* pModuleBase = (uint8_t*)PalGetModuleHandleFromPointer(RhpGetThunksBase()); int templateRva = (int)((uint8_t*)RhpGetThunksBase() - pModuleBase); if (!PalAllocateThunksFromTemplate((HANDLE)pModuleBase, templateRva, templateSize, &pThunkMap)) @@ -357,7 +359,7 @@ EXTERN_C NATIVEAOT_API void* __cdecl RhAllocateThunksMapping() thunkBlocksPerMapping)) { if (pThunkMap != pThunksTemplateAddress) - PalFreeThunksFromTemplate(pThunkMap); + PalFreeThunksFromTemplate(pThunkMap, templateSize); return NULL; } diff --git a/src/coreclr/nativeaot/Runtime/amd64/ThunkPoolThunks.S b/src/coreclr/nativeaot/Runtime/amd64/ThunkPoolThunks.S index 259d698002b490..f79ace1ca4996a 100644 --- a/src/coreclr/nativeaot/Runtime/amd64/ThunkPoolThunks.S +++ b/src/coreclr/nativeaot/Runtime/amd64/ThunkPoolThunks.S @@ -38,11 +38,8 @@ .endm #ifdef TARGET_APPLE - // Create two segments in the Mach-O file: - // __THUNKS with executable permissions - // __THUNKS_DATA with read/write permissions - - .section __THUNKS,__thunks,regular,pure_instructions +// Thunk pool + .text .p2align PAGE_SIZE_LOG2 PATCH_LABEL ThunkPool .rept (THUNKS_MAP_SIZE / PAGE_SIZE) @@ -50,10 +47,6 @@ PATCH_LABEL ThunkPool THUNKS_PAGE_BLOCK .endr .p2align PAGE_SIZE_LOG2 - .section __THUNKS_DATA,__thunks,regular - .p2align PAGE_SIZE_LOG2 - .space THUNKS_MAP_SIZE - .p2align PAGE_SIZE_LOG2 #else #error Unsupported OS #endif diff --git a/src/coreclr/nativeaot/Runtime/arm64/ThunkPoolThunks.S b/src/coreclr/nativeaot/Runtime/arm64/ThunkPoolThunks.S index d93d9f959506e5..1b0ea7e0291166 100644 --- a/src/coreclr/nativeaot/Runtime/arm64/ThunkPoolThunks.S +++ b/src/coreclr/nativeaot/Runtime/arm64/ThunkPoolThunks.S @@ -46,11 +46,8 @@ .endm #ifdef TARGET_APPLE - // Create two segments in the Mach-O file: - // __THUNKS with executable permissions - // __THUNKS_DATA with read/write permissions - - .section __THUNKS,__thunks,regular,pure_instructions +// Thunk pool + .text .p2align PAGE_SIZE_LOG2 PATCH_LABEL ThunkPool .rept (THUNKS_MAP_SIZE / PAGE_SIZE) @@ -58,10 +55,6 @@ PATCH_LABEL ThunkPool THUNKS_PAGE_BLOCK .endr .p2align PAGE_SIZE_LOG2 - .section __THUNKS_DATA,__thunks,regular - .p2align PAGE_SIZE_LOG2 - .space THUNKS_MAP_SIZE - .p2align PAGE_SIZE_LOG2 #else #error Unsupported OS #endif diff --git a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp index 5b184882830a80..9d6f45c8fee8a0 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp @@ -56,8 +56,7 @@ #endif #ifdef TARGET_APPLE -#include -#include +#include #endif using std::nullptr_t; @@ -520,59 +519,61 @@ extern "C" bool PalDetachThread(void* thread) #if !defined(USE_PORTABLE_HELPERS) && !defined(FEATURE_RX_THUNKS) -#ifdef TARGET_APPLE -static const struct section_64 *thunks_section; -static const struct section_64 *thunks_data_section; -#endif - REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalAllocateThunksFromTemplate(HANDLE hTemplateModule, uint32_t templateRva, size_t templateSize, void** newThunksOut) { #ifdef TARGET_APPLE - int f; - Dl_info info; + vm_address_t addr, taddr; + vm_prot_t prot, max_prot; + kern_return_t ret; - int st = dladdr((const void*)hTemplateModule, &info); - if (st == 0) + // Allocate two contiguous ranges of memory: the first range will contain the trampolines + // and the second range will contain their data. + do { - return UInt32_FALSE; - } + ret = vm_allocate(mach_task_self(), &addr, templateSize * 2, VM_FLAGS_ANYWHERE); + } while (ret == KERN_ABORTED); - f = open(info.dli_fname, O_RDONLY); - if (f < 0) + if (ret != KERN_SUCCESS) { return UInt32_FALSE; } - // NOTE: We ignore templateRva since we would need to convert it to file offset - // and templateSize is useless too. Instead we read the sections from the - // executable and determine the size from them. - if (thunks_section == NULL) + do + { + ret = vm_remap( + mach_task_self(), &addr, templateSize, 0, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, + mach_task_self(), ((vm_address_t)hTemplateModule + templateRva), FALSE, &prot, &max_prot, VM_INHERIT_SHARE); + } while (ret == KERN_ABORTED); + + if (ret != KERN_SUCCESS) { - const struct mach_header_64 *hdr = (const struct mach_header_64 *)hTemplateModule; - thunks_section = getsectbynamefromheader_64(hdr, "__THUNKS", "__thunks"); - thunks_data_section = getsectbynamefromheader_64(hdr, "__THUNKS_DATA", "__thunks"); + do + { + ret = vm_deallocate(mach_task_self(), addr, templateSize * 2); + } while (ret == KERN_ABORTED); + + return UInt32_FALSE; } - *newThunksOut = mmap( - NULL, - thunks_section->size + thunks_data_section->size, - PROT_READ | PROT_EXEC, - MAP_PRIVATE, - f, - thunks_section->offset); - close(f); + *newThunksOut = (void*)addr; - return *newThunksOut == NULL ? UInt32_FALSE : UInt32_TRUE; + return UInt32_TRUE; #else PORTABILITY_ASSERT("UNIXTODO: Implement this function"); #endif } -REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(void *pBaseAddress) +REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(void *pBaseAddress, size_t templateSize) { #ifdef TARGET_APPLE - int ret = munmap(pBaseAddress, thunks_section->size + thunks_data_section->size); - return ret == 0 ? UInt32_TRUE : UInt32_FALSE; + kern_return_t ret; + + do + { + ret = vm_deallocate(mach_task_self(), (vm_address_t)pBaseAddress, templateSize * 2); + } while (ret == KERN_ABORTED); + + return ret == KERN_SUCCESS ? UInt32_TRUE : UInt32_FALSE; #else PORTABILITY_ASSERT("UNIXTODO: Implement this function"); #endif diff --git a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp index 964a3b52b09e42..9850fed10b11a2 100644 --- a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp +++ b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp @@ -259,7 +259,7 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalAllocateThunksFromTemplate(_In_ #endif } -REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(_In_ void *pBaseAddress) +REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(_In_ void *pBaseAddress, size_t templateSize) { #ifdef XBOX_ONE return TRUE; From 0a509788c77c21ebfe36ee28c98fe65f6201911e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 09:18:21 -0800 Subject: [PATCH 543/783] [release/8.0-staging] Change Native AOT ThreadBuffer.m_threadId to OS thread id (#96120) * Change Native AOT ThreadBuffer.m_threadId to OS thread id. * Remove the unused IsCurrentThread() --------- Co-authored-by: Mike McLaughlin --- src/coreclr/nativeaot/Runtime/thread.cpp | 9 ++------- src/coreclr/nativeaot/Runtime/thread.h | 3 +-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/thread.cpp b/src/coreclr/nativeaot/Runtime/thread.cpp index 4c924524fd4d73..53b86b4e3d0b2b 100644 --- a/src/coreclr/nativeaot/Runtime/thread.cpp +++ b/src/coreclr/nativeaot/Runtime/thread.cpp @@ -263,7 +263,7 @@ void Thread::Construct() m_pDeferredTransitionFrame = TOP_OF_STACK_MARKER; m_hPalThread = INVALID_HANDLE_VALUE; - m_threadId.SetToCurrentThread(); + m_threadId = PalGetCurrentOSThreadId(); HANDLE curProcessPseudo = PalGetCurrentProcess(); HANDLE curThreadPseudo = PalGetCurrentThread(); @@ -328,12 +328,7 @@ bool Thread::CatchAtSafePoint() uint64_t Thread::GetPalThreadIdForLogging() { - return *(uint64_t*)&m_threadId; -} - -bool Thread::IsCurrentThread() -{ - return m_threadId.IsCurrentThread(); + return m_threadId; } void Thread::Detach() diff --git a/src/coreclr/nativeaot/Runtime/thread.h b/src/coreclr/nativeaot/Runtime/thread.h index 7aa473eb6763d4..688a84c30340ee 100644 --- a/src/coreclr/nativeaot/Runtime/thread.h +++ b/src/coreclr/nativeaot/Runtime/thread.h @@ -102,7 +102,7 @@ struct ThreadBuffer GCFrameRegistration* m_pGCFrameRegistrations; PTR_VOID m_pStackLow; PTR_VOID m_pStackHigh; - EEThreadId m_threadId; // OS thread ID + uint64_t m_threadId; // OS thread ID PTR_VOID m_pThreadStressLog; // pointer to head of thread's StressLogChunks NATIVE_CONTEXT* m_interruptedContext; // context for an asynchronously interrupted thread. #ifdef FEATURE_SUSPEND_REDIRECTION @@ -209,7 +209,6 @@ class Thread : private ThreadBuffer #ifndef DACCESS_COMPILE uint64_t GetPalThreadIdForLogging(); - bool IsCurrentThread(); void GcScanRoots(void * pfnEnumCallback, void * pvCallbackData); #else From 3001c75d396b23f5f0fbf52186e5c5ad52c1c678 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 2 Jan 2024 09:19:47 -0800 Subject: [PATCH 544/783] Fix ILLink/ILC hang when tracking too many hoisted local values (#95041) (#95302) https://github.com/dotnet/runtime/pull/87634 introduced a limit on the number of values tracked in dataflow analysis, but this approach was incorrect because resetting the set of tracked values was effectively moving up the dataflow lattice, breaking the invariant and causing potential hangs. The hang was observed in https://github.com/dotnet/runtime/issues/94831, where (as found by @vitek-karas) the hoisted local `state` field of an async method with many await points was getting a large number of tracked values, hitting the limit, being reset to "empty", but then growing again, causing the analysis not to converge. The fix is to instead introduce a special value `ValueSet.Unknown` that is used for this case. It acts like "bottom" in the lattice, so that it destroys any other inputs on meet ("bottom" meet anything else is "bottom"). In this testcase the `state` field isn't involved in dataflow warnings, so this actually allows the method to be analyzed correctly, producing the expected warning for the `Type` local that flows across all of the await points. Fixes https://github.com/dotnet/runtime/issues/94831 --- .../Compiler/Dataflow/ArrayValue.cs | 6 +- .../Compiler/Dataflow/InterproceduralState.cs | 3 +- .../Compiler/Dataflow/MethodBodyScanner.cs | 18 ++-- .../Dataflow/ReflectionMethodBodyScanner.cs | 10 +- .../Dataflow/TrimAnalysisAssignmentPattern.cs | 4 +- .../DataFlow/InterproceduralState.cs | 4 +- .../DataFlow/LocalDataFlowAnalysis.cs | 3 +- .../DataFlow/LocalDataFlowVisitor.cs | 10 +- .../TrimAnalysis/ArrayValue.cs | 4 +- .../TrimAnalysisAssignmentPattern.cs | 4 +- .../TrimAnalysis/TrimAnalysisVisitor.cs | 12 +-- .../src/ILLink.Shared/DataFlow/ValueSet.cs | 97 ++++++++++++++----- .../ILLink.Shared/TrimAnalysis/ArrayValue.cs | 4 +- .../TrimAnalysis/HandleCallAction.cs | 70 ++++++------- ...RequireDynamicallyAccessedMembersAction.cs | 2 +- .../TrimAnalysis/ValueExtensions.cs | 16 ++- .../src/linker/Linker.Dataflow/ArrayValue.cs | 6 +- .../Linker.Dataflow/InterproceduralState.cs | 3 +- .../Linker.Dataflow/MethodBodyScanner.cs | 17 ++-- .../ReflectionMethodBodyScanner.cs | 4 +- .../TrimAnalysisAssignmentPattern.cs | 4 +- .../DataFlow/ExponentialDataFlow.cs | 82 +++++++++++++++- 22 files changed, 267 insertions(+), 116 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ArrayValue.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ArrayValue.cs index 2676873572dc14..beb0d60d4799af 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ArrayValue.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ArrayValue.cs @@ -19,7 +19,7 @@ internal partial record ArrayValue public static MultiValue Create(MultiValue size, TypeDesc elementType) { MultiValue result = MultiValueLattice.Top; - foreach (var sizeValue in size) + foreach (var sizeValue in size.AsEnumerable ()) { result = MultiValueLattice.Meet(result, new MultiValue(new ArrayValue(sizeValue, elementType))); } @@ -92,7 +92,7 @@ public override SingleValue DeepCopy() // Since it's possible to store a reference to array as one of its own elements // simple deep copy could lead to endless recursion. // So instead we simply disallow arrays as element values completely - and treat that case as "too complex to analyze". - foreach (SingleValue v in kvp.Value.Value) + foreach (SingleValue v in kvp.Value.Value.AsEnumerable ()) { System.Diagnostics.Debug.Assert(v is not ArrayValue); } @@ -123,7 +123,7 @@ public override string ToString() result.Append(element.Key); result.Append(",("); bool firstValue = true; - foreach (var v in element.Value.Value) + foreach (var v in element.Value.Value.AsEnumerable ()) { if (firstValue) { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/InterproceduralState.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/InterproceduralState.cs index 6a322caa148db5..7627312e81550a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/InterproceduralState.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/InterproceduralState.cs @@ -67,7 +67,8 @@ public void TrackMethod(MethodIL methodBody) methodBody = GetInstantiatedMethodIL(methodBody); // Work around the fact that ValueSet is readonly - var methodsList = new List(MethodBodies); + Debug.Assert (!MethodBodies.IsUnknown ()); + var methodsList = new List(MethodBodies.GetKnownValues ()); methodsList.Add(new MethodBodyValue(methodBody)); // For state machine methods, also scan the state machine members. diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs index deb9474117f478..fa6378f7361315 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs @@ -210,7 +210,7 @@ private static void ValidateNoReferenceToReference(ValueBasicBlockPair?[] locals continue; MultiValue localValue = localVariable.Value.Value; - foreach (var val in localValue) + foreach (var val in localValue.AsEnumerable ()) { if (val is LocalVariableReferenceValue localReference && localReference.ReferencedType.IsByRefOrPointer()) { @@ -309,7 +309,8 @@ public virtual void InterproceduralScan(MethodIL startingMethodBody) // Flow state through all methods encountered so far, as long as there // are changes discovered in the hoisted local state on entry to any method. - foreach (var methodBodyValue in oldInterproceduralState.MethodBodies) + Debug.Assert (!oldInterproceduralState.MethodBodies.IsUnknown ()); + foreach (var methodBodyValue in oldInterproceduralState.MethodBodies.GetKnownValues ()) Scan(methodBodyValue.MethodBody, ref interproceduralState); } @@ -327,7 +328,8 @@ public virtual void InterproceduralScan(MethodIL startingMethodBody) } else { - Debug.Assert(interproceduralState.MethodBodies.Count() == 1); + Debug.Assert (!interproceduralState.MethodBodies.IsUnknown ()); + Debug.Assert(interproceduralState.MethodBodies.GetKnownValues ().Count() == 1); } #endif } @@ -1018,7 +1020,7 @@ private void ScanIndirectStore( /// Throws if is not a valid target for an indirect store. protected void StoreInReference(MultiValue target, MultiValue source, MethodIL method, int offset, ValueBasicBlockPair?[] locals, int curBasicBlock, ref InterproceduralState ipState) { - foreach (var value in target) + foreach (var value in target.AsEnumerable ()) { switch (value) { @@ -1137,7 +1139,7 @@ private void ScanStfld( return; } - foreach (var value in HandleGetField(methodBody, offset, field)) + foreach (var value in HandleGetField(methodBody, offset, field).AsEnumerable ()) { // GetFieldValue may return different node types, in which case they can't be stored to. // At least not yet. @@ -1189,7 +1191,7 @@ internal MultiValue DereferenceValue( ref InterproceduralState interproceduralState) { MultiValue dereferencedValue = MultiValueLattice.Top; - foreach (var value in maybeReferenceValue) + foreach (var value in maybeReferenceValue.AsEnumerable ()) { switch (value) { @@ -1324,7 +1326,7 @@ private void HandleCall( foreach (var param in methodArguments) { - foreach (var v in param) + foreach (var v in param.AsEnumerable ()) { if (v is ArrayValue arr) { @@ -1366,7 +1368,7 @@ private void ScanStelem( StackSlot indexToStoreAt = PopUnknown(currentStack, 1, methodBody, offset); StackSlot arrayToStoreIn = PopUnknown(currentStack, 1, methodBody, offset); int? indexToStoreAtInt = indexToStoreAt.Value.AsConstInt(); - foreach (var array in arrayToStoreIn.Value) + foreach (var array in arrayToStoreIn.Value.AsEnumerable ()) { if (array is ArrayValue arrValue) { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs index d11569a98d5681..9c1fe23f8db18e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs @@ -431,7 +431,7 @@ public static bool HandleCall( // type instead). // // At least until we have shared enum code, this needs extra handling to get it right. - foreach (var value in argumentValues[0]) + foreach (var value in argumentValues[0].AsEnumerable ()) { if (value is SystemTypeValue systemTypeValue && !systemTypeValue.RepresentedType.Type.IsGenericDefinition @@ -466,7 +466,7 @@ public static bool HandleCall( ? 0 : 1; // We need the data to do struct marshalling. - foreach (var value in argumentValues[paramIndex]) + foreach (var value in argumentValues[paramIndex].AsEnumerable ()) { if (value is SystemTypeValue systemTypeValue && !systemTypeValue.RepresentedType.Type.IsGenericDefinition @@ -497,7 +497,7 @@ public static bool HandleCall( case IntrinsicId.Marshal_GetDelegateForFunctionPointer: { // We need the data to do delegate marshalling. - foreach (var value in argumentValues[1]) + foreach (var value in argumentValues[1].AsEnumerable ()) { if (value is SystemTypeValue systemTypeValue && !systemTypeValue.RepresentedType.Type.IsGenericDefinition @@ -521,7 +521,7 @@ public static bool HandleCall( // case IntrinsicId.Object_GetType: { - foreach (var valueNode in instanceValue) + foreach (var valueNode in instanceValue.AsEnumerable ()) { // Note that valueNode can be statically typed in IL as some generic argument type. // For example: @@ -619,7 +619,7 @@ public static bool HandleCall( // Validate that the return value has the correct annotations as per the method return value annotations if (annotatedMethodReturnValue.DynamicallyAccessedMemberTypes != 0) { - foreach (var uniqueValue in methodReturnValue) + foreach (var uniqueValue in methodReturnValue.AsEnumerable ()) { if (uniqueValue is ValueWithDynamicallyAccessedMembers methodReturnValueWithMemberTypes) { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisAssignmentPattern.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisAssignmentPattern.cs index e9ce2078896cca..cbf83266e144e7 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisAssignmentPattern.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisAssignmentPattern.cs @@ -48,9 +48,9 @@ public void MarkAndProduceDiagnostics(ReflectionMarker reflectionMarker, Logger logger.ShouldSuppressAnalysisWarningsForRequires(Origin.MemberDefinition, DiagnosticUtilities.RequiresAssemblyFilesAttribute), logger); - foreach (var sourceValue in Source) + foreach (var sourceValue in Source.AsEnumerable ()) { - foreach (var targetValue in Target) + foreach (var targetValue in Target.AsEnumerable ()) { if (targetValue is not ValueWithDynamicallyAccessedMembers targetWithDynamicallyAccessedMembers) throw new NotImplementedException(); diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/InterproceduralState.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/InterproceduralState.cs index 875f4e1e0acf9f..2fac8f0540adc2 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/InterproceduralState.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/InterproceduralState.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using ILLink.Shared.DataFlow; @@ -50,7 +51,8 @@ public InterproceduralState Clone () public void TrackMethod (MethodBodyValue method) { - var methodsList = new List (Methods); + Debug.Assert (!Methods.IsUnknown ()); + var methodsList = new List (Methods.GetKnownValues ()); methodsList.Add (method); Methods = new ValueSet (methodsList); } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs index 80629aee5b10f6..741b0a31a49c13 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs @@ -62,7 +62,8 @@ public void InterproceduralAnalyze () while (!interproceduralState.Equals (oldInterproceduralState)) { oldInterproceduralState = interproceduralState.Clone (); - foreach (var method in oldInterproceduralState.Methods) { + Debug.Assert (!oldInterproceduralState.Methods.IsUnknown ()); + foreach (var method in oldInterproceduralState.Methods.GetKnownValues ()) { if (method.Method.IsInRequiresUnreferencedCodeAttributeScope (out _)) continue; diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs index 80ce7a66f4d231..2c6c74db554884 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs @@ -253,7 +253,7 @@ TValue ProcessSingleTargetAssignment (IOperation targetOperation, ISimpleAssignm // Single captured reference. Treat this as an overwriting assignment, // unless the caller already told us to merge values because this is an // assignment to one of multiple captured array element references. - var enumerator = capturedReferences.GetEnumerator (); + var enumerator = capturedReferences.GetKnownValues ().GetEnumerator (); enumerator.MoveNext (); var capture = enumerator.Current; arrayRef = Visit (capture.Reference, state); @@ -266,7 +266,8 @@ TValue ProcessSingleTargetAssignment (IOperation targetOperation, ISimpleAssignm // We treat this as possible write to each of the captured references, // which requires merging with the previous values of each. - foreach (var capture in state.Current.CapturedReferences.Get (captureReference.Id)) { + Debug.Assert (!capturedReferences.IsUnknown ()); + foreach (var capture in capturedReferences.GetKnownValues ()) { arrayRef = Visit (capture.Reference, state); HandleArrayElementWrite (arrayRef, index, value, operation, merge: true); } @@ -330,9 +331,10 @@ public override TValue VisitSimpleAssignment (ISimpleAssignmentOperation operati Debug.Assert (IsLValueFlowCapture (flowCaptureReference.Id)); Debug.Assert (!flowCaptureReference.GetValueUsageInfo (Method).HasFlag (ValueUsageInfo.Read)); var capturedReferences = state.Current.CapturedReferences.Get (flowCaptureReference.Id); + Debug.Assert (!capturedReferences.IsUnknown ()); if (!capturedReferences.HasMultipleValues) { // Single captured reference. Treat this as an overwriting assignment. - var enumerator = capturedReferences.GetEnumerator (); + var enumerator = capturedReferences.GetKnownValues ().GetEnumerator (); enumerator.MoveNext (); targetOperation = enumerator.Current.Reference; return ProcessSingleTargetAssignment (targetOperation, operation, state, merge: false); @@ -349,7 +351,7 @@ public override TValue VisitSimpleAssignment (ISimpleAssignmentOperation operati // if the RHS has dataflow warnings. TValue value = TopValue; - foreach (var capturedReference in capturedReferences) { + foreach (var capturedReference in capturedReferences.GetKnownValues ()) { targetOperation = capturedReference.Reference; var singleValue = ProcessSingleTargetAssignment (targetOperation, operation, state, merge: true); value = LocalStateLattice.Lattice.ValueLattice.Meet (value, singleValue); diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ArrayValue.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ArrayValue.cs index 58ebbff0bc1f0a..5a4bb0f5559659 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ArrayValue.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ArrayValue.cs @@ -14,7 +14,7 @@ internal partial record ArrayValue public static MultiValue Create (MultiValue size) { MultiValue result = MultiValueLattice.Top; - foreach (var sizeValue in size) { + foreach (var sizeValue in size.AsEnumerable ()) { result = MultiValueLattice.Meet (result, new MultiValue (new ArrayValue (sizeValue))); } @@ -73,7 +73,7 @@ public override SingleValue DeepCopy () // Since it's possible to store a reference to array as one of its own elements // simple deep copy could lead to endless recursion. // So instead we simply disallow arrays as element values completely - and treat that case as "too complex to analyze". - foreach (SingleValue v in kvp.Value) { + foreach (SingleValue v in kvp.Value.AsEnumerable ()) { System.Diagnostics.Debug.Assert (v is not ArrayValue); } #endif diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs index 9a41f47cd9a525..2c2f94d8b2aa04 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs @@ -38,8 +38,8 @@ public TrimAnalysisAssignmentPattern Merge (ValueSetLattice lattice public IEnumerable CollectDiagnostics () { var diagnosticContext = new DiagnosticContext (Operation.Syntax.GetLocation ()); - foreach (var sourceValue in Source) { - foreach (var targetValue in Target) { + foreach (var sourceValue in Source.AsEnumerable ()) { + foreach (var targetValue in Target.AsEnumerable ()) { // The target should always be an annotated value, but the visitor design currently prevents // declaring this in the type system. if (targetValue is not ValueWithDynamicallyAccessedMembers targetWithDynamicallyAccessedMembers) diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs index 04c7b06fa048e6..b960e2a461f97d 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs @@ -77,7 +77,7 @@ public override MultiValue VisitArrayCreation (IArrayCreationOperation operation var arrayValue = ArrayValue.Create (Visit (operation.DimensionSizes[0], state)); var elements = operation.Initializer?.ElementValues.Select (val => Visit (val, state)).ToArray () ?? System.Array.Empty (); - foreach (var array in arrayValue.Cast ()) { + foreach (var array in arrayValue.AsEnumerable ().Cast ()) { for (int i = 0; i < elements.Length; i++) { array.IndexValues.Add (i, ArrayValue.SanitizeArrayElementValue(elements[i])); } @@ -155,11 +155,11 @@ operation.OperatorMethod is null && MultiValue rightValue = Visit (operation.RightOperand, argument); MultiValue result = TopValue; - foreach (var left in leftValue) { + foreach (var left in leftValue.AsEnumerable ()) { if (left is UnknownValue) result = _multiValueLattice.Meet (result, left); else if (left is ConstIntValue leftConstInt) { - foreach (var right in rightValue) { + foreach (var right in rightValue.AsEnumerable ()) { if (right is UnknownValue) result = _multiValueLattice.Meet (result, right); else if (right is ConstIntValue rightConstInt) { @@ -210,7 +210,7 @@ public override MultiValue HandleArrayElementRead (MultiValue arrayValue, MultiV return UnknownValue.Instance; MultiValue result = TopValue; - foreach (var value in arrayValue) { + foreach (var value in arrayValue.AsEnumerable ()) { if (value is ArrayValue arr && arr.TryGetValueByIndex (index, out var elementValue)) result = _multiValueLattice.Meet (result, elementValue); else @@ -222,7 +222,7 @@ public override MultiValue HandleArrayElementRead (MultiValue arrayValue, MultiV public override void HandleArrayElementWrite (MultiValue arrayValue, MultiValue indexValue, MultiValue valueToWrite, IOperation operation, bool merge) { int? index = indexValue.AsConstInt (); - foreach (var arraySingleValue in arrayValue) { + foreach (var arraySingleValue in arrayValue.AsEnumerable ()) { if (arraySingleValue is ArrayValue arr) { if (index == null) { // Reset the array to all unknowns - since we don't know which index is being assigned @@ -282,7 +282,7 @@ public override MultiValue HandleMethodCall (IMethodSymbol calledMethod, MultiVa Method)); foreach (var argument in arguments) { - foreach (var argumentValue in argument) { + foreach (var argumentValue in argument.AsEnumerable ()) { if (argumentValue is ArrayValue arrayValue) arrayValue.IndexValues.Clear (); } diff --git a/src/tools/illink/src/ILLink.Shared/DataFlow/ValueSet.cs b/src/tools/illink/src/ILLink.Shared/DataFlow/ValueSet.cs index d538d358e8cea3..f8229a4173e9f9 100644 --- a/src/tools/illink/src/ILLink.Shared/DataFlow/ValueSet.cs +++ b/src/tools/illink/src/ILLink.Shared/DataFlow/ValueSet.cs @@ -4,6 +4,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; @@ -12,11 +13,21 @@ namespace ILLink.Shared.DataFlow { - public readonly struct ValueSet : IEquatable>, IEnumerable, IDeepCopyValue> + public readonly struct ValueSet : IEquatable>, IDeepCopyValue> where TValue : notnull { const int MaxValuesInSet = 256; + public static readonly ValueSet Empty; + + private sealed class ValueSetSentinel + { + } + + private static readonly ValueSetSentinel UnknownSentinel = new (); + + public static readonly ValueSet Unknown = new (UnknownSentinel); + // Since we're going to do lot of type checks for this class a lot, it is much more efficient // if the class is sealed (as then the runtime can do a simple method table pointer comparison) private sealed class EnumerableValues : HashSet @@ -117,11 +128,25 @@ public void Reset () } } + public readonly struct Enumerable : IEnumerable + { + private readonly object? _values; + + public Enumerable (object? values) => _values = values; + + public Enumerator GetEnumerator () => new (_values); + + IEnumerator IEnumerable.GetEnumerator () => GetEnumerator (); + + IEnumerator IEnumerable.GetEnumerator () => GetEnumerator (); + } + // This stores the values. By far the most common case will be either no values, or a single value. // Cases where there are multiple values stored are relatively very rare. // null - no values (empty set) // TValue - single value itself // EnumerableValues typed object - multiple values, stored in the hashset + // ValueSetSentinel.Unknown - unknown value, or "any possible value" private readonly object? _values; public ValueSet (TValue value) => _values = value; @@ -130,8 +155,11 @@ public void Reset () private ValueSet (EnumerableValues values) => _values = values; + private ValueSet (ValueSetSentinel sentinel) => _values = sentinel; + public static implicit operator ValueSet (TValue value) => new (value); + // Note: returns false for Unknown public bool HasMultipleValues => _values is EnumerableValues; public override bool Equals (object? obj) => obj is ValueSet other && Equals (other); @@ -146,14 +174,24 @@ public bool Equals (ValueSet other) if (_values is EnumerableValues enumerableValues) { if (other._values is EnumerableValues otherValuesSet) { return enumerableValues.Equals (otherValuesSet); - } else - return enumerableValues.Equals ((TValue) other._values); - } else { + } else if (other._values is TValue otherValue) { + return enumerableValues.Equals (otherValue); + } else { + Debug.Assert (other._values == UnknownSentinel); + return false; + } + } else if (_values is TValue value) { if (other._values is EnumerableValues otherEnumerableValues) { - return otherEnumerableValues.Equals ((TValue) _values); + return otherEnumerableValues.Equals (value); + } else if (other._values is TValue otherValue) { + return EqualityComparer.Default.Equals (value, otherValue); + } else { + Debug.Assert (other._values == UnknownSentinel); + return false; } - - return EqualityComparer.Default.Equals ((TValue) _values, (TValue) other._values); + } else { + Debug.Assert (_values == UnknownSentinel); + return other._values == UnknownSentinel; } } @@ -171,17 +209,20 @@ public override int GetHashCode () return _values.GetHashCode (); } - public Enumerator GetEnumerator () => new (_values); - - IEnumerator IEnumerable.GetEnumerator () => GetEnumerator (); - - IEnumerator IEnumerable.GetEnumerator () => GetEnumerator (); + public Enumerable GetKnownValues () => new Enumerable (_values == UnknownSentinel ? null : _values); - public bool Contains (TValue value) => _values is null - ? false - : _values is EnumerableValues valuesSet - ? valuesSet.Contains (value) - : EqualityComparer.Default.Equals (value, (TValue) _values); + // Note: returns false for Unknown + public bool Contains (TValue value) + { + if (_values is null) + return false; + if (_values is EnumerableValues valuesSet) + return valuesSet.Contains (value); + if (_values is TValue thisValue) + return EqualityComparer.Default.Equals (value, thisValue); + Debug.Assert (_values == UnknownSentinel); + return false; + } internal static ValueSet Meet (ValueSet left, ValueSet right) { @@ -190,28 +231,35 @@ internal static ValueSet Meet (ValueSet left, ValueSet r if (right._values == null) return left.DeepCopy (); + if (left._values == UnknownSentinel || right._values == UnknownSentinel) + return Unknown; + if (left._values is not EnumerableValues && right.Contains ((TValue) left._values)) return right.DeepCopy (); if (right._values is not EnumerableValues && left.Contains ((TValue) right._values)) return left.DeepCopy (); - var values = new EnumerableValues (left.DeepCopy ()); - values.UnionWith (right.DeepCopy ()); + var values = new EnumerableValues (left.DeepCopy ().GetKnownValues ()); + values.UnionWith (right.DeepCopy ().GetKnownValues ()); // Limit the number of values we track, to prevent hangs in case of patterns that - // create exponentially many possible values. This will result in analysis holes. + // create exponentially many possible values. if (values.Count > MaxValuesInSet) - return default; + return Unknown; return new ValueSet (values); } public bool IsEmpty () => _values == null; + public bool IsUnknown () => _values == UnknownSentinel; + public override string ToString () { + if (IsUnknown ()) + return "Unknown"; StringBuilder sb = new (); sb.Append ('{'); - sb.Append (string.Join (",", this.Select (v => v.ToString ()))); + sb.Append (string.Join (",", GetKnownValues ().Select (v => v.ToString ()))); sb.Append ('}'); return sb.ToString (); } @@ -223,6 +271,9 @@ public ValueSet DeepCopy () if (_values is null) return this; + if (_values == UnknownSentinel) + return this; + // Optimize for the most common case with only a single value if (_values is not EnumerableValues) { if (_values is IDeepCopyValue copyValue) @@ -231,7 +282,7 @@ public ValueSet DeepCopy () return this; } - return new ValueSet (this.Select (value => value is IDeepCopyValue copyValue ? copyValue.DeepCopy () : value)); + return new ValueSet (GetKnownValues ().Select (value => value is IDeepCopyValue copyValue ? copyValue.DeepCopy () : value)); } } } diff --git a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/ArrayValue.cs b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/ArrayValue.cs index 9c699baea9125b..417091915dfef1 100644 --- a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/ArrayValue.cs +++ b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/ArrayValue.cs @@ -34,7 +34,7 @@ public static MultiValue SanitizeArrayElementValue (MultiValue input) // So we will simply treat array value as an element value as "too complex to analyze" and give up by storing Unknown instead bool needSanitization = false; - foreach (var v in input) { + foreach (var v in input.AsEnumerable ()) { if (v is ArrayValue) needSanitization = true; } @@ -42,7 +42,7 @@ public static MultiValue SanitizeArrayElementValue (MultiValue input) if (!needSanitization) return input; - return new(input.Select (v => v is ArrayValue ? UnknownValue.Instance : v)); + return new(input.AsEnumerable ().Select (v => v is ArrayValue ? UnknownValue.Instance : v)); } } } diff --git a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs index 1191e3cc1c304f..6e2f42a2dba1ee 100644 --- a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs +++ b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs @@ -68,7 +68,7 @@ public bool Invoke (MethodProxy calledMethod, MultiValue instanceValue, IReadOnl break; } - foreach (var value in argumentValues[0]) { + foreach (var value in argumentValues[0].AsEnumerable ()) { AddReturnValue (value switch { RuntimeTypeHandleForNullableSystemTypeValue nullableSystemType => new NullableSystemTypeValue (nullableSystemType.NullableType, nullableSystemType.UnderlyingTypeValue), @@ -94,7 +94,7 @@ RuntimeTypeHandleForGenericParameterValue genericParam break; } - foreach (var value in instanceValue) { + foreach (var value in instanceValue.AsEnumerable ()) { if (value != NullValue.Instance) AddReturnValue (value switch { NullableSystemTypeValue nullableSystemType @@ -123,7 +123,7 @@ GenericParameterValue genericParam } // Infrastructure piece to support "ldtoken method -> GetMethodFromHandle" - foreach (var value in argumentValues[0]) { + foreach (var value in argumentValues[0].AsEnumerable ()) { if (value is RuntimeMethodHandleValue methodHandle) AddReturnValue (new SystemReflectionMethodBaseValue (methodHandle.RepresentedMethod)); else @@ -138,7 +138,7 @@ GenericParameterValue genericParam break; } - foreach (var value in instanceValue) { + foreach (var value in instanceValue.AsEnumerable ()) { if (value is SystemReflectionMethodBaseValue methodBaseValue) AddReturnValue (new RuntimeMethodHandleValue (methodBaseValue.RepresentedMethod)); else @@ -166,8 +166,8 @@ GenericParameterValue genericParam } var targetValue = _annotations.GetMethodThisParameterValue (calledMethod, DynamicallyAccessedMemberTypes.Interfaces); - foreach (var value in instanceValue) { - foreach (var interfaceName in argumentValues[0]) { + foreach (var value in instanceValue.AsEnumerable ()) { + foreach (var interfaceName in argumentValues[0].AsEnumerable ()) { if (interfaceName == NullValue.Instance) { // Throws on null string, so no return value. AddReturnValue (MultiValueLattice.Top); @@ -204,7 +204,7 @@ GenericParameterValue genericParam break; } - foreach (var value in instanceValue) { + foreach (var value in instanceValue.AsEnumerable ()) { if (value is ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers) { // Currently we don't need to track the difference between Type and String annotated values // that only matters when we use them, so Type.GetType is the difference really. @@ -232,7 +232,7 @@ GenericParameterValue genericParam break; } - foreach (var typeHandleValue in argumentValues[0]) { + foreach (var typeHandleValue in argumentValues[0].AsEnumerable ()) { if (typeHandleValue is RuntimeTypeHandleValue runtimeTypeHandleValue) { MarkStaticConstructor (runtimeTypeHandleValue.RepresentedType); } else { @@ -330,9 +330,9 @@ GenericParameterValue genericParam }; var targetValue = _annotations.GetMethodThisParameterValue (calledMethod, memberTypes); - foreach (var value in instanceValue) { + foreach (var value in instanceValue.AsEnumerable ()) { if (value is SystemTypeValue systemTypeValue) { - foreach (var stringParam in argumentValues[0]) { + foreach (var stringParam in argumentValues[0].AsEnumerable ()) { if (stringParam is KnownStringValue stringValue && !BindingFlagsAreUnsupported (bindingFlags)) { switch (intrinsicId) { case IntrinsicId.Type_GetEvent: @@ -396,7 +396,7 @@ GenericParameterValue genericParam var targetValue = _annotations.GetMethodThisParameterValue (calledMethod, requiredMemberTypes); // Go over all types we've seen - foreach (var value in instanceValue) { + foreach (var value in instanceValue.AsEnumerable ()) { // Mark based on bitfield requirements _requireDynamicallyAccessedMembersAction.Invoke (value, targetValue); } @@ -432,9 +432,9 @@ GenericParameterValue genericParam bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public; var targetValue = _annotations.GetMethodThisParameterValue (calledMethod, GetDynamicallyAccessedMemberTypesFromBindingFlagsForMethods (bindingFlags)); - foreach (var value in instanceValue) { + foreach (var value in instanceValue.AsEnumerable ()) { if (value is SystemTypeValue systemTypeValue) { - foreach (var stringParam in argumentValues[0]) { + foreach (var stringParam in argumentValues[0].AsEnumerable ()) { if (stringParam is KnownStringValue stringValue && !BindingFlagsAreUnsupported (bindingFlags)) { AddReturnValue (MultiValueLattice.Top); ; // Initialize return value (so that it's not autofilled if there are no matching methods) foreach (var methodValue in ProcessGetMethodByName (systemTypeValue.RepresentedType, stringValue.Contents, bindingFlags)) @@ -478,9 +478,9 @@ GenericParameterValue genericParam bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public; var targetValue = _annotations.GetMethodThisParameterValue (calledMethod, GetDynamicallyAccessedMemberTypesFromBindingFlagsForNestedTypes (bindingFlags)); - foreach (var value in instanceValue) { + foreach (var value in instanceValue.AsEnumerable ()) { if (value is SystemTypeValue systemTypeValue) { - foreach (var stringParam in argumentValues[0]) { + foreach (var stringParam in argumentValues[0].AsEnumerable ()) { if (stringParam is KnownStringValue stringValue && !BindingFlagsAreUnsupported (bindingFlags)) { AddReturnValue (MultiValueLattice.Top); foreach (var nestedTypeValue in GetNestedTypesOnType (systemTypeValue.RepresentedType, stringValue.Contents, bindingFlags)) { @@ -546,9 +546,9 @@ GenericParameterValue genericParam var targetValue = _annotations.GetMethodParameterValue (new (calledMethod, (ParameterIndex) 1), requiredMemberTypes); - foreach (var value in argumentValues[0]) { + foreach (var value in argumentValues[0].AsEnumerable ()) { if (value is SystemTypeValue systemTypeValue) { - foreach (var stringParam in argumentValues[1]) { + foreach (var stringParam in argumentValues[1].AsEnumerable ()) { if (stringParam is KnownStringValue stringValue) { switch (intrinsicId) { case IntrinsicId.RuntimeReflectionExtensions_GetRuntimeEvent: @@ -594,7 +594,7 @@ GenericParameterValue genericParam // case IntrinsicId.Expression_New: { var targetValue = _annotations.GetMethodParameterValue (new (calledMethod, (ParameterIndex) 0), DynamicallyAccessedMemberTypes.PublicParameterlessConstructor); - foreach (var value in argumentValues[0]) { + foreach (var value in argumentValues[0].AsEnumerable ()) { if (value is SystemTypeValue systemTypeValue) { MarkConstructorsOnType (systemTypeValue.RepresentedType, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, parameterCount: null); } else { @@ -615,7 +615,7 @@ GenericParameterValue genericParam break; } - foreach (var value in argumentValues[1]) { + foreach (var value in argumentValues[1].AsEnumerable ()) { if (value is SystemReflectionMethodBaseValue methodBaseValue) { // We have one of the accessors for the property. The Expression.Property will in this case search // for the matching PropertyInfo and store that. So to be perfectly correct we need to mark the @@ -652,9 +652,9 @@ GenericParameterValue genericParam } var targetValue = _annotations.GetMethodParameterValue (new (calledMethod, (ParameterIndex) 1), memberTypes); - foreach (var value in argumentValues[1]) { + foreach (var value in argumentValues[1].AsEnumerable ()) { if (value is SystemTypeValue systemTypeValue) { - foreach (var stringParam in argumentValues[2]) { + foreach (var stringParam in argumentValues[2].AsEnumerable ()) { if (stringParam is KnownStringValue stringValue) { BindingFlags bindingFlags = argumentValues[0].AsSingleValue () is NullValue ? BindingFlags.Static : BindingFlags.Default; if (intrinsicId == IntrinsicId.Expression_Property) { @@ -689,9 +689,9 @@ GenericParameterValue genericParam // This is true even if we "don't know" - so it's only false if we're sure that there are no type arguments bool hasTypeArguments = (argumentValues[2].AsSingleValue () as ArrayValue)?.Size.AsConstInt () != 0; - foreach (var value in argumentValues[0]) { + foreach (var value in argumentValues[0].AsEnumerable ()) { if (value is SystemTypeValue systemTypeValue) { - foreach (var stringParam in argumentValues[1]) { + foreach (var stringParam in argumentValues[1].AsEnumerable ()) { if (stringParam is KnownStringValue stringValue) { foreach (var method in GetMethodsOnTypeHierarchy (systemTypeValue.RepresentedType, stringValue.Contents, bindingFlags)) { ValidateGenericMethodInstantiation (method.RepresentedMethod, argumentValues[2], calledMethod); @@ -769,7 +769,7 @@ GenericParameterValue genericParam break; } - foreach (var typeNameValue in argumentValues[0]) { + foreach (var typeNameValue in argumentValues[0].AsEnumerable ()) { if (typeNameValue is KnownStringValue knownStringValue) { if (!_requireDynamicallyAccessedMembersAction.TryResolveTypeNameAndMark (knownStringValue.Contents, false, out TypeProxy foundType)) { // Intentionally ignore - it's not wrong for code to call Type.GetType on non-existing name, the code might expect null/exception back. @@ -804,7 +804,7 @@ GenericParameterValue genericParam break; } - foreach (var value in instanceValue) { + foreach (var value in instanceValue.AsEnumerable ()) { if (value is SystemTypeValue typeValue) { // Special case Nullable // Nullables without a type argument are considered SystemTypeValues @@ -815,9 +815,9 @@ GenericParameterValue genericParam // There are several places even in the framework where typeof(Nullable<>).MakeGenericType would warn // without any good reason to do so. - foreach (var argumentValue in argumentValues[0]) { + foreach (var argumentValue in argumentValues[0].AsEnumerable ()) { if ((argumentValue as ArrayValue)?.TryGetValueByIndex (0, out var underlyingMultiValue) == true) { - foreach (var underlyingValue in underlyingMultiValue) { + foreach (var underlyingValue in underlyingMultiValue.AsEnumerable ()) { switch (underlyingValue) { // Don't warn on these types - it will throw instead case NullableValueWithDynamicallyAccessedMembers: @@ -879,7 +879,7 @@ GenericParameterValue genericParam break; } - foreach (var value in instanceValue) { + foreach (var value in instanceValue.AsEnumerable ()) { if (value is ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers) { DynamicallyAccessedMemberTypes propagatedMemberTypes = DynamicallyAccessedMemberTypes.None; if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes == DynamicallyAccessedMemberTypes.All) @@ -953,7 +953,7 @@ GenericParameterValue genericParam }; // Go over all types we've seen - foreach (var value in instanceValue) { + foreach (var value in instanceValue.AsEnumerable ()) { if (value is SystemTypeValue systemTypeValue && !BindingFlagsAreUnsupported (bindingFlags)) { if (HasBindingFlag (bindingFlags, BindingFlags.Public) && !HasBindingFlag (bindingFlags, BindingFlags.NonPublic) && ctorParameterCount == 0) { @@ -986,7 +986,7 @@ GenericParameterValue genericParam break; } - foreach (var methodValue in instanceValue) { + foreach (var methodValue in instanceValue.AsEnumerable ()) { if (methodValue is SystemReflectionMethodBaseValue methodBaseValue) { ValidateGenericMethodInstantiation (methodBaseValue.RepresentedMethod, argumentValues[0], calledMethod); } else if (methodValue == NullValue.Instance) { @@ -1054,7 +1054,7 @@ GenericParameterValue genericParam } // Go over all types we've seen - foreach (var value in argumentValues[0]) { + foreach (var value in argumentValues[0].AsEnumerable ()) { if (value is SystemTypeValue systemTypeValue) { // Special case known type values as we can do better by applying exact binding flags and parameter count. MarkConstructorsOnType (systemTypeValue.RepresentedType, bindingFlags, ctorParameterCount); @@ -1172,7 +1172,7 @@ GenericParameterValue genericParam // Validate that the return value has the correct annotations as per the method return value annotations if (annotatedMethodReturnValue.DynamicallyAccessedMemberTypes != DynamicallyAccessedMemberTypes.None) { - foreach (var uniqueValue in returnValue.Value) { + foreach (var uniqueValue in returnValue.Value.AsEnumerable ()) { if (uniqueValue is ValueWithDynamicallyAccessedMembers methodReturnValueWithMemberTypes) { if (!methodReturnValueWithMemberTypes.DynamicallyAccessedMemberTypes.HasFlag (annotatedMethodReturnValue.DynamicallyAccessedMemberTypes)) throw new InvalidOperationException ($"Internal ILLink error: in {GetContainingSymbolDisplayName ()} processing call to {calledMethod.GetDisplayName ()} returned value which is not correctly annotated with the expected dynamic member access kinds."); @@ -1228,7 +1228,7 @@ private bool AnalyzeGenericInstantiationTypeArray (in MultiValue arrayParam, in if (!hasRequirements) return true; - foreach (var typesValue in arrayParam) { + foreach (var typesValue in arrayParam.AsEnumerable ()) { if (typesValue is not ArrayValue array) { return false; } @@ -1318,13 +1318,13 @@ private void ProcessCreateInstanceByName (MethodProxy calledMethod, IReadOnlyLis bindingFlags |= BindingFlags.Public | BindingFlags.NonPublic; } - foreach (var assemblyNameValue in argumentValues[0]) { + foreach (var assemblyNameValue in argumentValues[0].AsEnumerable ()) { if (assemblyNameValue is KnownStringValue assemblyNameStringValue) { if (assemblyNameStringValue.Contents is string assemblyName && assemblyName.Length == 0) { // Throws exception for zero-length assembly name. continue; } - foreach (var typeNameValue in argumentValues[1]) { + foreach (var typeNameValue in argumentValues[1].AsEnumerable ()) { if (typeNameValue is NullValue) { // Throws exception for null type name. continue; diff --git a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs index aa24361bf5530e..50166c803be30c 100644 --- a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs +++ b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs @@ -23,7 +23,7 @@ public void Invoke (in MultiValue value, ValueWithDynamicallyAccessedMembers tar if (targetValue.DynamicallyAccessedMemberTypes == DynamicallyAccessedMemberTypes.None) return; - foreach (var uniqueValue in value) { + foreach (var uniqueValue in value.AsEnumerable ()) { if (targetValue.DynamicallyAccessedMemberTypes == DynamicallyAccessedMemberTypes.PublicParameterlessConstructor && uniqueValue is GenericParameterValue genericParam && genericParam.GenericParameter.HasDefaultConstructorConstraint ()) { diff --git a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/ValueExtensions.cs b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/ValueExtensions.cs index 0e7643a8d5d439..f9cd1b7ee1e606 100644 --- a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/ValueExtensions.cs +++ b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/ValueExtensions.cs @@ -50,10 +50,22 @@ internal static string ValueToString (this SingleValue value, params object[] ar internal static SingleValue? AsSingleValue (this in MultiValue node) { - if (node.Count () != 1) + var values = node.AsEnumerable (); + if (values.Count () != 1) return null; - return node.Single (); + return values.Single (); + } + + private static ValueSet.Enumerable Unknown = new ValueSet.Enumerable (UnknownValue.Instance); + + // ValueSet is not enumerable. This helper translates ValueSet.Unknown + // into a ValueSet whose sole element is UnknownValue.Instance. + internal static ValueSet.Enumerable AsEnumerable (this MultiValue multiValue) + { + return multiValue.IsUnknown () + ? Unknown + : multiValue.GetKnownValues (); } } } diff --git a/src/tools/illink/src/linker/Linker.Dataflow/ArrayValue.cs b/src/tools/illink/src/linker/Linker.Dataflow/ArrayValue.cs index 6b914c16f70d31..a428dfc4468aeb 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/ArrayValue.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/ArrayValue.cs @@ -17,7 +17,7 @@ internal partial record ArrayValue public static MultiValue Create (MultiValue size, TypeReference elementType) { MultiValue result = MultiValueLattice.Top; - foreach (var sizeValue in size) { + foreach (var sizeValue in size.AsEnumerable ()) { result = MultiValueLattice.Meet (result, new MultiValue (new ArrayValue (sizeValue, elementType))); } @@ -87,7 +87,7 @@ public override SingleValue DeepCopy () // Since it's possible to store a reference to array as one of its own elements // simple deep copy could lead to endless recursion. // So instead we simply disallow arrays as element values completely - and treat that case as "too complex to analyze". - foreach (SingleValue v in kvp.Value.Value) { + foreach (SingleValue v in kvp.Value.Value.AsEnumerable ()) { System.Diagnostics.Debug.Assert (v is not ArrayValue); } #endif @@ -116,7 +116,7 @@ public override string ToString () result.Append (element.Key); result.Append (",("); bool firstValue = true; - foreach (var v in element.Value.Value) { + foreach (var v in element.Value.Value.AsEnumerable ()) { if (firstValue) { result.Append (','); firstValue = false; diff --git a/src/tools/illink/src/linker/Linker.Dataflow/InterproceduralState.cs b/src/tools/illink/src/linker/Linker.Dataflow/InterproceduralState.cs index 23667336eb8ce3..8ab34d80191958 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/InterproceduralState.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/InterproceduralState.cs @@ -53,7 +53,8 @@ public void TrackMethod (MethodBody methodBody) public void TrackMethod (MethodIL methodIL) { // Work around the fact that ValueSet is readonly - var methodsList = new List (MethodBodies); + Debug.Assert (!MethodBodies.IsUnknown ()); + var methodsList = new List (MethodBodies.GetKnownValues ()); methodsList.Add (methodIL); // For state machine methods, also scan the state machine members. diff --git a/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs b/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs index fe140b82d23d52..fac77cce8fd6c3 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs @@ -185,7 +185,7 @@ static void ValidateNoReferenceToReference (LocalVariableStore locals, MethodDef foreach (var keyValuePair in locals) { MultiValue localValue = keyValuePair.Value.Value; VariableDefinition localVariable = keyValuePair.Key; - foreach (var val in localValue) { + foreach (var val in localValue.AsEnumerable ()) { if (val is LocalVariableReferenceValue localReference && localReference.ReferencedType.IsByReference) { string displayName = $"local variable V_{localReference.LocalDefinition.Index}"; throw new LinkerFatalErrorException (MessageContainer.CreateErrorMessage ( @@ -243,7 +243,8 @@ public virtual void InterproceduralScan (MethodIL startingMethodIL) // Flow state through all methods encountered so far, as long as there // are changes discovered in the hoisted local state on entry to any method. - foreach (var methodIL in oldInterproceduralState.MethodBodies) + Debug.Assert (!oldInterproceduralState.MethodBodies.IsUnknown ()); + foreach (var methodIL in oldInterproceduralState.MethodBodies.GetKnownValues ()) Scan (methodIL, ref interproceduralState); } @@ -258,7 +259,7 @@ public virtual void InterproceduralScan (MethodIL startingMethodIL) // foreach (var method in calleeMethods) // Debug.Assert (interproceduralState.Any (kvp => kvp.Key.Method == method)); } else { - Debug.Assert (interproceduralState.MethodBodies.Count () == 1); + Debug.Assert (interproceduralState.MethodBodies.GetKnownValues().Count () == 1); } #endif } @@ -857,7 +858,7 @@ private void ScanIndirectStore ( /// Throws if is not a valid target for an indirect store. protected void StoreInReference (MultiValue target, MultiValue source, MethodDefinition method, Instruction operation, LocalVariableStore locals, int curBasicBlock, ref InterproceduralState ipState) { - foreach (var value in target) { + foreach (var value in target.AsEnumerable ()) { switch (value) { case LocalVariableReferenceValue localReference: StoreMethodLocalValue (locals, source, localReference.LocalDefinition, curBasicBlock); @@ -956,7 +957,7 @@ private void ScanStfld ( return; } - foreach (var value in GetFieldValue (field)) { + foreach (var value in GetFieldValue (field).AsEnumerable ()) { // GetFieldValue may return different node types, in which case they can't be stored to. // At least not yet. if (value is not FieldValue fieldValue) @@ -1012,7 +1013,7 @@ private ValueNodeList PopCallArguments ( internal MultiValue DereferenceValue (MultiValue maybeReferenceValue, LocalVariableStore locals, ref InterproceduralState interproceduralState) { MultiValue dereferencedValue = MultiValueLattice.Top; - foreach (var value in maybeReferenceValue) { + foreach (var value in maybeReferenceValue.AsEnumerable ()) { switch (value) { case FieldReferenceValue fieldReferenceValue: dereferencedValue = MultiValue.Meet ( @@ -1123,7 +1124,7 @@ private void HandleCall ( AssignRefAndOutParameters (callingMethodBody, calledMethod, methodArguments, operation, locals, curBasicBlock, ref interproceduralState); foreach (var param in methodArguments) { - foreach (var v in param) { + foreach (var v in param.AsEnumerable ()) { if (v is ArrayValue arr) { MarkArrayValuesAsUnknown (arr, curBasicBlock); } @@ -1163,7 +1164,7 @@ private void ScanStelem ( StackSlot indexToStoreAt = PopUnknown (currentStack, 1, methodBody, operation.Offset); StackSlot arrayToStoreIn = PopUnknown (currentStack, 1, methodBody, operation.Offset); int? indexToStoreAtInt = indexToStoreAt.Value.AsConstInt (); - foreach (var array in arrayToStoreIn.Value) { + foreach (var array in arrayToStoreIn.Value.AsEnumerable ()) { if (array is ArrayValue arrValue) { if (indexToStoreAtInt == null) { MarkArrayValuesAsUnknown (arrValue, curBasicBlock); diff --git a/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs b/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs index 28780d11239158..7eca458bc81d7a 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs @@ -283,7 +283,7 @@ public static bool HandleCall ( // GetType() // case IntrinsicId.Object_GetType: { - foreach (var valueNode in instanceValue) { + foreach (var valueNode in instanceValue.AsEnumerable ()) { // Note that valueNode can be statically typed in IL as some generic argument type. // For example: // void Method(T instance) { instance.GetType().... } @@ -359,7 +359,7 @@ public static bool HandleCall ( // Validate that the return value has the correct annotations as per the method return value annotations if (annotatedMethodReturnValue.DynamicallyAccessedMemberTypes != 0) { - foreach (var uniqueValue in methodReturnValue) { + foreach (var uniqueValue in methodReturnValue.AsEnumerable ()) { if (uniqueValue is ValueWithDynamicallyAccessedMembers methodReturnValueWithMemberTypes) { if (!methodReturnValueWithMemberTypes.DynamicallyAccessedMemberTypes.HasFlag (annotatedMethodReturnValue.DynamicallyAccessedMemberTypes)) throw new InvalidOperationException ($"Internal trimming error: processing of call from {callingMethodDefinition.GetDisplayName ()} to {calledMethod.GetDisplayName ()} returned value which is not correctly annotated with the expected dynamic member access kinds."); diff --git a/src/tools/illink/src/linker/Linker.Dataflow/TrimAnalysisAssignmentPattern.cs b/src/tools/illink/src/linker/Linker.Dataflow/TrimAnalysisAssignmentPattern.cs index 829fefdb2f545f..ccc91c04fba4cd 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/TrimAnalysisAssignmentPattern.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/TrimAnalysisAssignmentPattern.cs @@ -37,8 +37,8 @@ public void MarkAndProduceDiagnostics (ReflectionMarker reflectionMarker, LinkCo bool diagnosticsEnabled = !context.Annotations.ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode (Origin.Provider, out _); var diagnosticContext = new DiagnosticContext (Origin, diagnosticsEnabled, context); - foreach (var sourceValue in Source) { - foreach (var targetValue in Target) { + foreach (var sourceValue in Source.AsEnumerable ()) { + foreach (var targetValue in Target.AsEnumerable ()) { if (targetValue is not ValueWithDynamicallyAccessedMembers targetWithDynamicallyAccessedMembers) throw new NotImplementedException (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExponentialDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExponentialDataFlow.cs index dffe035d63648d..d2d5b05da72387 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExponentialDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExponentialDataFlow.cs @@ -3,7 +3,9 @@ using System; using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; namespace Mono.Linker.Tests.Cases.DataFlow { @@ -16,6 +18,8 @@ public static void Main () ExponentialArrayStates.Test (); ExponentialArrayStatesDataFlow.Test (); ArrayStatesDataFlow.Test (); + ExponentialArrayInStateMachine.Test (); + ExponentialStateFieldInStateMachine.Test (); } class ExponentialArrayStates @@ -91,8 +95,9 @@ class GenericTypeWithRequires< [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot)] // The way we track arrays causes the analyzer to track exponentially many // ArrayValues in the ValueSet for the pattern in this method, hitting the limit. - // When this happens, we replace the ValueSet wit a TopValue, which doesn't - // produce a warning in this case. + // When this happens, we replace the ValueSet with an unknown value, producing + // this warning. + [ExpectedWarning ("IL2055", ProducedBy = Tool.Analyzer)] [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] @@ -163,5 +168,78 @@ public static void Test () static bool Condition => Random.Shared.Next (2) == 0; } + + class ExponentialArrayInStateMachine + { + // Force state machine + static async Task RecursiveReassignment () + { + typeof (TestType).RequiresAll (); // Force data flow analysis + + object[] args = null; + args = new[] { args }; + } + + public static void Test() + { + RecursiveReassignment ().Wait (); + } + } + + class ExponentialStateFieldInStateMachine + { + [ExpectedWarning ("IL2072", nameof (GetWithPublicFields), nameof (DataFlowTypeExtensions.RequiresAll), CompilerGeneratedCode = true)] + public static async void Test () + { + Type t = GetWithPublicFields (); + + // 100 + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + + // 200 + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + + // 300 + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); await MethodAsync (); + + t.RequiresAll (); + } + } + + class TestType { } + + static async Task MethodAsync () + { + return await Task.FromResult (0); + } + + static Type GetWithPublicFields () => null; } } From cf2b9e3c16acc7e735d9d1397b9e2c98989e5e3d Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Tue, 2 Jan 2024 10:34:12 -0800 Subject: [PATCH 545/783] Add runtime module address to SpecialDiagInfo block in createdump and fix missing DotNetRuntimeDebugHeader export (#96121) * Add runtime module address to SpecialDiagInfo block in createdump Fix missing DotNetRuntimeDebugHeader export: Add ILC options: --export-dynamic-symbol - Add dynamic export symbol to export file. Used to add DotNetRuntimeDebugHeader export. --export-unmanaged-entrypoints - controls whether the exported method definitions are exported Change Native AOT build integration to always pass an export file to ILC and linker. Bump the Native AOT data contract sizes * Fix failing test because the .def path was too long * Fix failing test because the .def path was too long * More .def file path too long fixes * Fix JSON crashinfo exception object address --- src/coreclr/debug/createdump/crashinfo.cpp | 4 + src/coreclr/debug/createdump/crashinfomac.cpp | 20 + .../debug/createdump/crashinfounix.cpp | 22 + src/coreclr/debug/createdump/dumpwriter.cpp | 3 +- .../debug/createdump/specialdiaginfo.h | 7 +- .../Microsoft.NETCore.Native.targets | 11 +- src/coreclr/nativeaot/Runtime/DebugHeader.cpp | 15 +- .../src/System/CrashInfo.cs | 3 +- .../Compiler/ExportsFileWriter.cs | 16 +- .../aot/ILCompiler/ILCompilerRootCommand.cs | 8 +- src/coreclr/tools/aot/ILCompiler/Program.cs | 12 +- ...ContextCommonAndImplementationDICallDI.il} | 2 +- ...extCommonAndImplementationDICallDI.ilproj} | 2 +- .../GenericContextTestDICallDI.il} | 7156 ++++++++--------- .../GenericContextTestDICallDI.ilproj} | 4 +- ...veConstraintOnDIOfStaticAbstractMember.cs} | 0 ...nstraintOnDIOfStaticAbstractMember.csproj} | 0 ...taticVirtualsAndMethodConstraintsAndDI.cs} | 0 ...cVirtualsAndMethodConstraintsAndDI.csproj} | 0 19 files changed, 3678 insertions(+), 3607 deletions(-) rename src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/{GenericContextTestDefaultImpCallDefaultImp/GenericContextCommonAndImplementation.il => GenericContextTestDICallDI/GenericContextCommonAndImplementationDICallDI.il} (99%) rename src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/{GenericContextTestDefaultImpCallDefaultImp/GenericContextCommonAndImplementation.ilproj => GenericContextTestDICallDI/GenericContextCommonAndImplementationDICallDI.ilproj} (80%) rename src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/{GenericContextTestDefaultImpCallDefaultImp/GenericContextTestDefaultImpCallDefaultImp.il => GenericContextTestDICallDI/GenericContextTestDICallDI.il} (88%) rename src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/{GenericContextTestDefaultImpCallDefaultImp/GenericContextTestDefaultImpCallDefaultImp.ilproj => GenericContextTestDICallDI/GenericContextTestDICallDI.ilproj} (79%) rename src/tests/Loader/classloader/StaticVirtualMethods/Regression/{RecursiveConstraintOnDefaultImplementationOfStaticAbstractMember.cs => RecursiveConstraintOnDIOfStaticAbstractMember.cs} (100%) rename src/tests/Loader/classloader/StaticVirtualMethods/Regression/{RecursiveConstraintOnDefaultImplementationOfStaticAbstractMember.csproj => RecursiveConstraintOnDIOfStaticAbstractMember.csproj} (100%) rename src/tests/Loader/classloader/StaticVirtualMethods/Regression/{StaticVirtualsAndMethodConstraintsAndDefaultImplementation.cs => StaticVirtualsAndMethodConstraintsAndDI.cs} (100%) rename src/tests/Loader/classloader/StaticVirtualMethods/Regression/{StaticVirtualsAndMethodConstraintsAndDefaultImplementation.csproj => StaticVirtualsAndMethodConstraintsAndDI.csproj} (100%) diff --git a/src/coreclr/debug/createdump/crashinfo.cpp b/src/coreclr/debug/createdump/crashinfo.cpp index 8af6ec4a54f5bd..996f3a81935d0f 100644 --- a/src/coreclr/debug/createdump/crashinfo.cpp +++ b/src/coreclr/debug/createdump/crashinfo.cpp @@ -9,6 +9,9 @@ typedef HINSTANCE (PALAPI_NOEXPORT *PFN_REGISTER_MODULE)(LPCSTR); /* u // This is for the PAL_VirtualUnwindOutOfProc read memory adapter. CrashInfo* g_crashInfo; +// This is the NativeAOT DotNetRuntimeDebugHeader signature +uint8_t g_debugHeaderCookie[4] = { 0x44, 0x4E, 0x44, 0x48 }; + static bool ModuleInfoCompare(const ModuleInfo* lhs, const ModuleInfo* rhs) { return lhs->BaseAddress() < rhs->BaseAddress(); } CrashInfo::CrashInfo(const CreateDumpOptions& options) : @@ -30,6 +33,7 @@ CrashInfo::CrashInfo(const CreateDumpOptions& options) : m_enumMemoryPagesAdded(0) { g_crashInfo = this; + m_runtimeBaseAddress = 0; #ifdef __APPLE__ m_task = 0; #else diff --git a/src/coreclr/debug/createdump/crashinfomac.cpp b/src/coreclr/debug/createdump/crashinfomac.cpp index 90a31f106d6845..89c71c9e586c85 100644 --- a/src/coreclr/debug/createdump/crashinfomac.cpp +++ b/src/coreclr/debug/createdump/crashinfomac.cpp @@ -3,6 +3,8 @@ #include "createdump.h" +extern uint8_t g_debugHeaderCookie[4]; + int g_readProcessMemoryResult = KERN_SUCCESS; bool @@ -263,6 +265,24 @@ void CrashInfo::VisitModule(MachOModule& module) } } } + else if (m_appModel == AppModelType::NativeAOT) + { + uint64_t symbolOffset; + if (module.TryLookupSymbol("DotNetRuntimeDebugHeader", &symbolOffset)) + { + m_coreclrPath = GetDirectory(module.Name()); + m_runtimeBaseAddress = module.BaseAddress(); + + uint8_t cookie[sizeof(g_debugHeaderCookie)]; + if (ReadMemory((void*)(module.BaseAddress() + symbolOffset), cookie, sizeof(cookie))) + { + if (memcmp(cookie, g_debugHeaderCookie, sizeof(g_debugHeaderCookie)) == 0) + { + TRACE("Found valid NativeAOT runtime module\n"); + } + } + } + } } // VisitSegment is called for each segment of the module module.EnumerateSegments(); diff --git a/src/coreclr/debug/createdump/crashinfounix.cpp b/src/coreclr/debug/createdump/crashinfounix.cpp index 70b2ddb270d74f..24b975e3d65559 100644 --- a/src/coreclr/debug/createdump/crashinfounix.cpp +++ b/src/coreclr/debug/createdump/crashinfounix.cpp @@ -8,6 +8,7 @@ #endif extern CrashInfo* g_crashInfo; +extern uint8_t g_debugHeaderCookie[4]; int g_readProcessMemoryErrno = 0; @@ -383,6 +384,27 @@ CrashInfo::VisitModule(uint64_t baseAddress, std::string& moduleName) } } } + else if (m_appModel == AppModelType::NativeAOT) + { + if (PopulateForSymbolLookup(baseAddress)) + { + uint64_t symbolOffset; + if (TryLookupSymbol("DotNetRuntimeDebugHeader", &symbolOffset)) + { + m_coreclrPath = GetDirectory(moduleName); + m_runtimeBaseAddress = baseAddress; + + uint8_t cookie[sizeof(g_debugHeaderCookie)]; + if (ReadMemory((void*)(baseAddress + symbolOffset), cookie, sizeof(cookie))) + { + if (memcmp(cookie, g_debugHeaderCookie, sizeof(g_debugHeaderCookie)) == 0) + { + TRACE("Found valid NativeAOT runtime module\n"); + } + } + } + } + } } EnumerateProgramHeaders(baseAddress); } diff --git a/src/coreclr/debug/createdump/dumpwriter.cpp b/src/coreclr/debug/createdump/dumpwriter.cpp index 5153ba790154ff..0e39b52b3a7d4c 100644 --- a/src/coreclr/debug/createdump/dumpwriter.cpp +++ b/src/coreclr/debug/createdump/dumpwriter.cpp @@ -39,7 +39,8 @@ DumpWriter::WriteDiagInfo(size_t size) SpecialDiagInfoHeader header = { {SPECIAL_DIAGINFO_SIGNATURE}, SPECIAL_DIAGINFO_VERSION, - m_crashInfo.ExceptionRecord() + m_crashInfo.ExceptionRecord(), + m_crashInfo.RuntimeBaseAddress() }; if (!WriteData(&header, sizeof(header))) { return false; diff --git a/src/coreclr/debug/createdump/specialdiaginfo.h b/src/coreclr/debug/createdump/specialdiaginfo.h index a857129c9c91ff..84f79f00a160df 100644 --- a/src/coreclr/debug/createdump/specialdiaginfo.h +++ b/src/coreclr/debug/createdump/specialdiaginfo.h @@ -8,11 +8,11 @@ // ****************************************************************************** // This is a special memory region added to ELF and MachO dumps that contains extra diagnostics -// information like the exception record for a crash for a NativeAOT app. The exception record -// contains the pointer to the JSON formatted crash info. +// information like the exception record address for a NativeAOT app crash or the runtime module +// base address. The exception record contains the pointer to the JSON formatted crash info. #define SPECIAL_DIAGINFO_SIGNATURE "DIAGINFOHEADER" -#define SPECIAL_DIAGINFO_VERSION 1 +#define SPECIAL_DIAGINFO_VERSION 2 #ifdef __APPLE__ const uint64_t SpecialDiagInfoAddress = 0x7fffffff10000000; @@ -31,4 +31,5 @@ struct SpecialDiagInfoHeader char Signature[16]; int32_t Version; uint64_t ExceptionRecordAddress; + uint64_t RuntimeBaseAddress; }; diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index e9462399741c5e..e379eb457bdc6c 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -81,7 +81,7 @@ The .NET Foundation licenses this file to you under the MIT license. $(NativeIntermediateOutputPath)$(TargetName)$(NativeObjectExt) $(NativeOutputPath)$(TargetName)$(NativeBinaryExt) true - $(NativeIntermediateOutputPath)$(TargetName)$(ExportsFileExt) + $(NativeIntermediateOutputPath)$(TargetName)$(ExportsFileExt) $(NativeObject) @@ -240,7 +240,10 @@ The .NET Foundation licenses this file to you under the MIT license. - + + + + @@ -334,8 +337,8 @@ The .NET Foundation licenses this file to you under the MIT license. - - + + diff --git a/src/coreclr/nativeaot/Runtime/DebugHeader.cpp b/src/coreclr/nativeaot/Runtime/DebugHeader.cpp index 121fdec1019e0f..8cafe9e1dab835 100644 --- a/src/coreclr/nativeaot/Runtime/DebugHeader.cpp +++ b/src/coreclr/nativeaot/Runtime/DebugHeader.cpp @@ -36,12 +36,12 @@ struct GlobalValueEntry // This size should be one bigger than the number of entries since a null entry // signifies the end of the array. -static constexpr size_t DebugTypeEntriesArraySize = 96; +static constexpr size_t DebugTypeEntriesArraySize = 100; static DebugTypeEntry s_DebugEntries[DebugTypeEntriesArraySize]; // This size should be one bigger than the number of entries since a null entry // signifies the end of the array. -static constexpr size_t GlobalEntriesArraySize = 6; +static constexpr size_t GlobalEntriesArraySize = 8; static GlobalValueEntry s_GlobalEntries[GlobalEntriesArraySize]; // This structure is part of a in-memory serialization format that is used by diagnostic tools to @@ -107,10 +107,11 @@ struct DotNetRuntimeDebugHeader GlobalValueEntry (* volatile GlobalEntries)[GlobalEntriesArraySize] = nullptr; }; -#ifdef TARGET_WINDOWS -#pragma comment (linker, "/EXPORT:DotNetRuntimeDebugHeader,DATA") -#endif extern "C" struct DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader; + +#ifdef HOST_UNIX +__attribute__ ((visibility ("default"))) +#endif struct DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader = {}; #define MAKE_DEBUG_ENTRY(TypeName, FieldName, Value) \ @@ -118,7 +119,7 @@ struct DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader = {}; { \ s_DebugEntries[currentDebugPos] = { #TypeName, #FieldName, Value, 0 }; \ ++currentDebugPos; \ - ASSERT(currentDebugPos <= DebugTypeEntriesArraySize); \ + ASSERT(currentDebugPos < DebugTypeEntriesArraySize); \ } while(0) #define MAKE_DEBUG_FIELD_ENTRY(TypeName, FieldName) MAKE_DEBUG_ENTRY(TypeName, FieldName, offsetof(TypeName, FieldName)) @@ -132,7 +133,7 @@ struct DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader = {}; { \ s_GlobalEntries[currentGlobalPos] = { #Name, Name }; \ ++currentGlobalPos; \ - ASSERT(currentGlobalPos <= GlobalEntriesArraySize) \ + ASSERT(currentGlobalPos < GlobalEntriesArraySize); \ } while(0) \ extern "C" void PopulateDebugHeaders() diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs index c2421fc6b4ceb9..a92f64f368cfe4 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs @@ -170,7 +170,8 @@ private bool WriteExceptionHelper(ReadOnlySpan key, Exception exception, i if (!OpenValue(key, '{')) return false; - if (!WriteHexValue("address"u8, (ulong)Unsafe.AsPointer(ref exception))) + ulong address = Unsafe.As(ref exception); + if (!WriteHexValue("address"u8, address)) return false; if (!WriteHexValue("hr"u8, exception.HResult)) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExportsFileWriter.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExportsFileWriter.cs index 9937ecacc986c1..7f1a4e2b51de4d 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExportsFileWriter.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExportsFileWriter.cs @@ -12,13 +12,15 @@ namespace ILCompiler { public class ExportsFileWriter { - private string _exportsFile; - private List _methods; - private TypeSystemContext _context; + private readonly string _exportsFile; + private readonly IEnumerable _exportSymbols; + private readonly List _methods; + private readonly TypeSystemContext _context; - public ExportsFileWriter(TypeSystemContext context, string exportsFile) + public ExportsFileWriter(TypeSystemContext context, string exportsFile, IEnumerable exportSymbols) { _exportsFile = exportsFile; + _exportSymbols = exportSymbols; _context = context; _methods = new List(); } @@ -34,11 +36,15 @@ public void EmitExportedMethods() if (_context.Target.IsWindows) { streamWriter.WriteLine("EXPORTS"); + foreach (string symbol in _exportSymbols) + streamWriter.WriteLine($" {symbol.Replace(',', ' ')}"); foreach (var method in _methods) streamWriter.WriteLine($" {method.GetUnmanagedCallersOnlyExportName()}"); } else if(_context.Target.IsOSXLike) { + foreach (string symbol in _exportSymbols) + streamWriter.WriteLine($"_{symbol}"); foreach (var method in _methods) streamWriter.WriteLine($"_{method.GetUnmanagedCallersOnlyExportName()}"); } @@ -46,6 +52,8 @@ public void EmitExportedMethods() { streamWriter.WriteLine("V1.0 {"); streamWriter.WriteLine(" global: _init; _fini;"); + foreach (string symbol in _exportSymbols) + streamWriter.WriteLine($" {symbol};"); foreach (var method in _methods) streamWriter.WriteLine($" {method.GetUnmanagedCallersOnlyExportName()};"); streamWriter.WriteLine(" local: *;"); diff --git a/src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs b/src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs index 1470888a664e79..92f3294f0f4624 100644 --- a/src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs +++ b/src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs @@ -38,7 +38,11 @@ internal sealed class ILCompilerRootCommand : CliRootCommand public CliOption SplitExeInitialization { get; } = new("--splitinit") { Description = "Split initialization of an executable between the library entrypoint and a main entrypoint" }; public CliOption ExportsFile { get; } = - new("--exportsfile") { Description = "File to write exported method definitions" }; + new("--exportsfile") { Description = "File to write exported symbol and method definitions" }; + public CliOption ExportUnmanagedEntryPoints { get; } = + new("--export-unmanaged-entrypoints") { Description = "Controls whether the named UnmanagedCallersOnly methods are exported" }; + public CliOption ExportDynamicSymbols { get; } = + new("--export-dynamic-symbol") { Description = "Add dynamic export symbol to exports file" }; public CliOption DgmlLogFileName { get; } = new("--dgmllog") { Description = "Save result of dependency analysis as DGML" }; public CliOption GenerateFullDgmlLog { get; } = @@ -176,6 +180,8 @@ public ILCompilerRootCommand(string[] args) : base(".NET Native IL Compiler") Options.Add(NativeLib); Options.Add(SplitExeInitialization); Options.Add(ExportsFile); + Options.Add(ExportDynamicSymbols); + Options.Add(ExportUnmanagedEntryPoints); Options.Add(DgmlLogFileName); Options.Add(GenerateFullDgmlLog); Options.Add(ScanDgmlLogFileName); diff --git a/src/coreclr/tools/aot/ILCompiler/Program.cs b/src/coreclr/tools/aot/ILCompiler/Program.cs index ed7b013ae3d942..23f661e22c7d8d 100644 --- a/src/coreclr/tools/aot/ILCompiler/Program.cs +++ b/src/coreclr/tools/aot/ILCompiler/Program.cs @@ -565,11 +565,15 @@ void RunScanner() string exportsFile = Get(_command.ExportsFile); if (exportsFile != null) { - ExportsFileWriter defFileWriter = new ExportsFileWriter(typeSystemContext, exportsFile); - foreach (var compilationRoot in compilationRoots) + ExportsFileWriter defFileWriter = new ExportsFileWriter(typeSystemContext, exportsFile, Get(_command.ExportDynamicSymbols)); + + if (Get(_command.ExportUnmanagedEntryPoints)) { - if (compilationRoot is UnmanagedEntryPointsRootProvider provider) - defFileWriter.AddExportedMethods(provider.ExportedMethods); + foreach (var compilationRoot in compilationRoots) + { + if (compilationRoot is UnmanagedEntryPointsRootProvider provider) + defFileWriter.AddExportedMethods(provider.ExportedMethods); + } } defFileWriter.EmitExportedMethods(); diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDefaultImpCallDefaultImp/GenericContextCommonAndImplementation.il b/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDICallDI/GenericContextCommonAndImplementationDICallDI.il similarity index 99% rename from src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDefaultImpCallDefaultImp/GenericContextCommonAndImplementation.il rename to src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDICallDI/GenericContextCommonAndImplementationDICallDI.il index d1ef8895883362..5f21b51ced4c02 100644 --- a/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDefaultImpCallDefaultImp/GenericContextCommonAndImplementation.il +++ b/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDICallDI/GenericContextCommonAndImplementationDICallDI.il @@ -7,7 +7,7 @@ .assembly extern mscorlib {} .assembly extern System.Runtime {} .assembly extern GenericContextCommonCs {} -.assembly GenericContextCommonAndImplementation {} +.assembly GenericContextCommonAndImplementationDICallDI {} .class interface public abstract auto ansi IFaceNonGeneric { .method public newslot virtual abstract static void NormalMethod() {} diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDefaultImpCallDefaultImp/GenericContextCommonAndImplementation.ilproj b/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDICallDI/GenericContextCommonAndImplementationDICallDI.ilproj similarity index 80% rename from src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDefaultImpCallDefaultImp/GenericContextCommonAndImplementation.ilproj rename to src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDICallDI/GenericContextCommonAndImplementationDICallDI.ilproj index 8f17e9188e06af..82490f2b1cf46c 100644 --- a/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDefaultImpCallDefaultImp/GenericContextCommonAndImplementation.ilproj +++ b/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDICallDI/GenericContextCommonAndImplementationDICallDI.ilproj @@ -8,6 +8,6 @@ Full - + diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDefaultImpCallDefaultImp/GenericContextTestDefaultImpCallDefaultImp.il b/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDICallDI/GenericContextTestDICallDI.il similarity index 88% rename from src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDefaultImpCallDefaultImp/GenericContextTestDefaultImpCallDefaultImp.il rename to src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDICallDI/GenericContextTestDICallDI.il index c4bc38234b6849..f96ebcdf8106be 100644 --- a/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDefaultImpCallDefaultImp/GenericContextTestDefaultImpCallDefaultImp.il +++ b/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDICallDI/GenericContextTestDICallDI.il @@ -7,15 +7,15 @@ .assembly extern mscorlib {} .assembly extern System.Runtime {} .assembly extern GenericContextCommonCs {} -.assembly extern GenericContextCommonAndImplementation {} -.assembly GenericContextTestDefaultImpCallDefaultImp {} +.assembly extern GenericContextCommonAndImplementationDICallDI {} +.assembly GenericContextTestDICallDI {} .class public auto ansi TestEntrypoint extends [System.Runtime]System.Object { .method public static void Test_Call_NonGenericNonGenericClass_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_NonGenericNonGenericClass_NonGeneric_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -23,8 +23,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_NonGeneric_NonGeneric_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericClass_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -38,8 +38,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -54,8 +54,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_NonGeneric_NormalMethod .method public static void Test_Call_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -63,8 +63,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -78,8 +78,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -94,8 +94,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_NormalMethod .method public static void Test_Call_NonGenericNonGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -103,8 +103,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -118,8 +118,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -134,8 +134,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -143,8 +143,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -158,8 +158,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -174,8 +174,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericClass_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericClass_NonGeneric_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -183,8 +183,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_NonGeneric_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericClass_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -198,8 +198,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -214,8 +214,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_NonGeneric_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -223,8 +223,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -238,8 +238,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -254,8 +254,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericClass_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericClass_NonGeneric_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -263,8 +263,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_NonGeneric_GenericOverString_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericClass_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -278,8 +278,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -294,8 +294,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_GenericOverString_NormalMethod .method public static void Test_Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -303,8 +303,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -318,8 +318,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -334,8 +334,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_NormalMethod .method public static void Test_Call_NonGenericNonGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -343,8 +343,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -358,8 +358,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -374,8 +374,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -383,8 +383,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -398,8 +398,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -414,8 +414,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericClass_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_NonGeneric_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -423,8 +423,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_NonGeneric_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericClass_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -438,8 +438,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -454,8 +454,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_GenericOverString_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -463,8 +463,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -478,8 +478,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -494,8 +494,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericClass_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericClass_NonGeneric_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -503,8 +503,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_NonGeneric_GenericOverObject_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericClass_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -518,8 +518,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -534,8 +534,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_GenericOverObject_NormalMethod .method public static void Test_Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -543,8 +543,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -558,8 +558,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -574,8 +574,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_NormalMethod .method public static void Test_Call_NonGenericNonGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -583,8 +583,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -598,8 +598,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -614,8 +614,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -623,8 +623,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -638,8 +638,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -654,8 +654,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -663,8 +663,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -678,8 +678,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -694,8 +694,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -703,8 +703,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -718,8 +718,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -734,8 +734,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -743,8 +743,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -758,8 +758,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -774,8 +774,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -783,8 +783,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -798,8 +798,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -814,8 +814,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -823,8 +823,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -838,8 +838,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -854,8 +854,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -863,8 +863,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -878,8 +878,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -894,8 +894,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -903,8 +903,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -918,8 +918,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -934,8 +934,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -943,8 +943,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -958,8 +958,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -974,8 +974,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -983,8 +983,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -998,8 +998,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1014,8 +1014,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1023,8 +1023,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1038,8 +1038,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1054,8 +1054,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1063,8 +1063,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1078,8 +1078,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1094,8 +1094,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1103,8 +1103,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1118,8 +1118,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1134,8 +1134,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1143,8 +1143,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1158,8 +1158,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1174,8 +1174,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1183,8 +1183,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1198,8 +1198,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1214,8 +1214,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1223,8 +1223,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1238,8 +1238,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1254,8 +1254,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1263,8 +1263,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1278,8 +1278,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1294,8 +1294,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1303,8 +1303,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1318,8 +1318,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1334,8 +1334,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1343,8 +1343,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1358,8 +1358,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1374,8 +1374,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1383,8 +1383,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1398,8 +1398,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1414,8 +1414,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1423,8 +1423,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1438,8 +1438,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1454,8 +1454,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1463,8 +1463,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1478,8 +1478,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1494,8 +1494,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1503,8 +1503,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1518,8 +1518,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1534,8 +1534,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1543,8 +1543,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1558,8 +1558,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1574,8 +1574,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1583,8 +1583,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1598,8 +1598,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1614,8 +1614,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1623,8 +1623,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1638,8 +1638,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1654,8 +1654,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1663,8 +1663,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1678,8 +1678,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1694,8 +1694,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1703,8 +1703,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1718,8 +1718,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1734,8 +1734,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1743,8 +1743,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1758,8 +1758,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1774,8 +1774,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1783,8 +1783,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1798,8 +1798,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1814,8 +1814,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1823,8 +1823,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1838,8 +1838,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1854,8 +1854,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1863,8 +1863,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1878,8 +1878,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1894,8 +1894,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1903,8 +1903,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1918,8 +1918,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1934,8 +1934,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1943,8 +1943,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1958,8 +1958,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -1974,8 +1974,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -1983,8 +1983,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -1998,8 +1998,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2014,8 +2014,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2023,8 +2023,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2038,8 +2038,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2054,8 +2054,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2063,8 +2063,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2078,8 +2078,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2094,8 +2094,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2103,8 +2103,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2118,8 +2118,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2134,8 +2134,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2143,8 +2143,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2158,8 +2158,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2174,8 +2174,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2183,8 +2183,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2198,8 +2198,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2214,8 +2214,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2223,8 +2223,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2238,8 +2238,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2254,8 +2254,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2263,8 +2263,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2278,8 +2278,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2294,8 +2294,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2303,8 +2303,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2318,8 +2318,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2334,8 +2334,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2343,8 +2343,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2358,8 +2358,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2374,8 +2374,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2383,8 +2383,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2398,8 +2398,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2414,8 +2414,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2423,8 +2423,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2438,8 +2438,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2454,8 +2454,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2463,8 +2463,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2478,8 +2478,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2494,8 +2494,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2503,8 +2503,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2518,8 +2518,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2534,8 +2534,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2543,8 +2543,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2558,8 +2558,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2574,8 +2574,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2583,8 +2583,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2598,8 +2598,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2614,8 +2614,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2623,8 +2623,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2638,8 +2638,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2654,8 +2654,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2663,8 +2663,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2678,8 +2678,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2694,8 +2694,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2703,8 +2703,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2718,8 +2718,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2734,8 +2734,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2743,8 +2743,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2758,8 +2758,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2774,8 +2774,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2783,8 +2783,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2798,8 +2798,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2814,8 +2814,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2823,8 +2823,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2838,8 +2838,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2854,8 +2854,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2863,8 +2863,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2878,8 +2878,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2894,8 +2894,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2903,8 +2903,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2918,8 +2918,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2934,8 +2934,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2943,8 +2943,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2958,8 +2958,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -2974,8 +2974,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -2983,8 +2983,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -2998,8 +2998,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3014,8 +3014,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -3023,8 +3023,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3038,8 +3038,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3054,8 +3054,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -3063,8 +3063,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3078,8 +3078,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3094,8 +3094,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -3103,8 +3103,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3118,8 +3118,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3134,8 +3134,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -3143,8 +3143,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3158,8 +3158,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3174,8 +3174,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -3183,8 +3183,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3198,8 +3198,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3214,8 +3214,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -3223,8 +3223,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3238,8 +3238,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3254,8 +3254,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -3263,8 +3263,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3278,8 +3278,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3294,8 +3294,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -3303,8 +3303,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3318,8 +3318,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3334,8 +3334,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -3343,8 +3343,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3358,8 +3358,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3374,8 +3374,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -3383,8 +3383,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3398,8 +3398,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3414,8 +3414,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -3423,8 +3423,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3438,8 +3438,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3454,8 +3454,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -3463,8 +3463,8 @@ } // end of method Test_Call_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3478,8 +3478,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]NonGenericClass - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]NonGenericClass + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3494,8 +3494,8 @@ } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -3503,8 +3503,8 @@ } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3518,8 +3518,8 @@ .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]NonGenericValuetype - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]NonGenericValuetype + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3532,19 +3532,19 @@ call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3554,12 +3554,12 @@ ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3571,20 +3571,20 @@ ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3594,12 +3594,12 @@ ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3611,20 +3611,20 @@ ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3634,12 +3634,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3651,20 +3651,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3674,12 +3674,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3691,20 +3691,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3714,12 +3714,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3731,20 +3731,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3754,12 +3754,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3771,20 +3771,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3794,12 +3794,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3811,20 +3811,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3834,12 +3834,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3851,11 +3851,11 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" ldstr "!!1" @@ -3863,11 +3863,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3880,12 +3880,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3900,11 +3900,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" ldstr "!!1" @@ -3912,11 +3912,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3929,12 +3929,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3949,11 +3949,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -3961,11 +3961,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -3978,12 +3978,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -3998,11 +3998,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -4010,11 +4010,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4027,12 +4027,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4047,11 +4047,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -4059,11 +4059,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4076,12 +4076,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4096,11 +4096,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -4108,11 +4108,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4125,12 +4125,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4145,11 +4145,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -4157,11 +4157,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4174,12 +4174,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4194,11 +4194,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -4206,11 +4206,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4223,12 +4223,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4243,11 +4243,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" ldstr "!!1" @@ -4255,11 +4255,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4272,12 +4272,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4292,11 +4292,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" ldstr "!!1" @@ -4304,11 +4304,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4321,12 +4321,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4341,11 +4341,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -4353,11 +4353,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4370,12 +4370,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4390,11 +4390,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -4402,11 +4402,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4419,12 +4419,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4439,11 +4439,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -4451,11 +4451,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4468,12 +4468,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4488,11 +4488,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -4500,11 +4500,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4517,12 +4517,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4537,11 +4537,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -4549,11 +4549,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4566,12 +4566,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4586,11 +4586,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -4598,11 +4598,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4615,12 +4615,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4635,20 +4635,20 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4658,12 +4658,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4675,20 +4675,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4698,12 +4698,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4715,20 +4715,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4738,12 +4738,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4755,20 +4755,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4778,12 +4778,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4795,20 +4795,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4818,12 +4818,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4835,20 +4835,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4858,12 +4858,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4875,20 +4875,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4898,12 +4898,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4915,20 +4915,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() ldstr "Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4938,12 +4938,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4955,11 +4955,11 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> + } // end of method Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1) T,U> .method public static void Test_Call_GenericOverStructGenericClass_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverStructGenericClass_NonGeneric_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -4967,8 +4967,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_NonGeneric_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericClass_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -4982,8 +4982,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -4998,8 +4998,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5007,8 +5007,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5022,8 +5022,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5038,8 +5038,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverStructGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5047,8 +5047,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5062,8 +5062,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5078,8 +5078,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5087,8 +5087,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5102,8 +5102,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5118,8 +5118,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericClass_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericClass_NonGeneric_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5127,8 +5127,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_NonGeneric_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericClass_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5142,8 +5142,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5158,8 +5158,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5167,8 +5167,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5182,8 +5182,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5198,8 +5198,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericClass_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericClass_NonGeneric_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5207,8 +5207,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_NonGeneric_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericClass_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5222,8 +5222,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5238,8 +5238,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5247,8 +5247,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5262,8 +5262,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5278,8 +5278,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverStructGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5287,8 +5287,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5302,8 +5302,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5318,8 +5318,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5327,8 +5327,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5342,8 +5342,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5358,8 +5358,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericClass_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_NonGeneric_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5367,8 +5367,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_NonGeneric_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericClass_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5382,8 +5382,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5398,8 +5398,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5407,8 +5407,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5422,8 +5422,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5438,8 +5438,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericClass_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericClass_NonGeneric_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5447,8 +5447,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_NonGeneric_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericClass_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5462,8 +5462,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5478,8 +5478,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5487,8 +5487,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5502,8 +5502,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5518,8 +5518,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverStructGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5527,8 +5527,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5542,8 +5542,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5558,8 +5558,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5567,8 +5567,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5582,8 +5582,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5598,8 +5598,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5607,8 +5607,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5622,8 +5622,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5638,8 +5638,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5647,8 +5647,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5662,8 +5662,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5678,8 +5678,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5687,8 +5687,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5702,8 +5702,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5718,8 +5718,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5727,8 +5727,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5742,8 +5742,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5758,8 +5758,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5767,8 +5767,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5782,8 +5782,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5798,8 +5798,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5807,8 +5807,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5822,8 +5822,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5838,8 +5838,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5847,8 +5847,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5862,8 +5862,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5878,8 +5878,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5887,8 +5887,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5902,8 +5902,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5918,8 +5918,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5927,8 +5927,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5942,8 +5942,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5958,8 +5958,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -5967,8 +5967,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -5982,8 +5982,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -5998,8 +5998,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6007,8 +6007,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6022,8 +6022,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6038,8 +6038,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6047,8 +6047,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6062,8 +6062,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6078,8 +6078,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6087,8 +6087,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6102,8 +6102,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6118,8 +6118,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6127,8 +6127,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6142,8 +6142,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6158,8 +6158,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6167,8 +6167,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6182,8 +6182,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6198,8 +6198,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6207,8 +6207,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6222,8 +6222,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6238,8 +6238,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6247,8 +6247,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6262,8 +6262,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6278,8 +6278,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6287,8 +6287,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6302,8 +6302,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6318,8 +6318,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6327,8 +6327,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6342,8 +6342,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6358,8 +6358,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6367,8 +6367,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6382,8 +6382,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6398,8 +6398,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6407,8 +6407,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6422,8 +6422,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6438,8 +6438,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6447,8 +6447,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6462,8 +6462,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6478,8 +6478,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6487,8 +6487,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6502,8 +6502,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6518,8 +6518,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6527,8 +6527,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6542,8 +6542,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6558,8 +6558,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6567,8 +6567,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6582,8 +6582,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6598,8 +6598,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6607,8 +6607,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6622,8 +6622,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6638,8 +6638,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6647,8 +6647,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6662,8 +6662,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6678,8 +6678,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6687,8 +6687,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6702,8 +6702,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6718,8 +6718,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6727,8 +6727,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6742,8 +6742,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6758,8 +6758,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6767,8 +6767,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6782,8 +6782,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6798,8 +6798,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6807,8 +6807,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6822,8 +6822,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6838,8 +6838,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6847,8 +6847,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6862,8 +6862,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6878,8 +6878,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6887,8 +6887,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6902,8 +6902,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6918,8 +6918,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6927,8 +6927,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6942,8 +6942,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6958,8 +6958,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -6967,8 +6967,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -6982,8 +6982,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -6998,8 +6998,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7007,8 +7007,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7022,8 +7022,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7038,8 +7038,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7047,8 +7047,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7062,8 +7062,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7078,8 +7078,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7087,8 +7087,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7102,8 +7102,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7118,8 +7118,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7127,8 +7127,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7142,8 +7142,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7158,8 +7158,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7167,8 +7167,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7182,8 +7182,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7198,8 +7198,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7207,8 +7207,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7222,8 +7222,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7238,8 +7238,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7247,8 +7247,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7262,8 +7262,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7278,8 +7278,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7287,8 +7287,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7302,8 +7302,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7318,8 +7318,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7327,8 +7327,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7342,8 +7342,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7358,8 +7358,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7367,8 +7367,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7382,8 +7382,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7398,8 +7398,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7407,8 +7407,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7422,8 +7422,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7438,8 +7438,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7447,8 +7447,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7462,8 +7462,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7478,8 +7478,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7487,8 +7487,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7502,8 +7502,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7518,8 +7518,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7527,8 +7527,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7542,8 +7542,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7558,8 +7558,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7567,8 +7567,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7582,8 +7582,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7598,8 +7598,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7607,8 +7607,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7622,8 +7622,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7638,8 +7638,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7647,8 +7647,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7662,8 +7662,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7678,8 +7678,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7687,8 +7687,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7702,8 +7702,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7718,8 +7718,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7727,8 +7727,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7742,8 +7742,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7758,8 +7758,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7767,8 +7767,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7782,8 +7782,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7798,8 +7798,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7807,8 +7807,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7822,8 +7822,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7838,8 +7838,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7847,8 +7847,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7862,8 +7862,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7878,8 +7878,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7887,8 +7887,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7902,8 +7902,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7918,8 +7918,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7927,8 +7927,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7942,8 +7942,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7958,8 +7958,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -7967,8 +7967,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -7982,8 +7982,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -7998,8 +7998,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -8007,8 +8007,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8022,8 +8022,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8038,8 +8038,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -8047,8 +8047,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8062,8 +8062,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8078,8 +8078,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -8087,8 +8087,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8102,8 +8102,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8118,8 +8118,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -8127,8 +8127,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8142,8 +8142,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8158,8 +8158,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -8167,8 +8167,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8182,8 +8182,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8198,8 +8198,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -8207,8 +8207,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8222,8 +8222,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8238,8 +8238,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -8247,8 +8247,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8262,8 +8262,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8278,8 +8278,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -8287,8 +8287,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8302,8 +8302,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8318,8 +8318,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -8327,8 +8327,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8342,8 +8342,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8358,8 +8358,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -8367,8 +8367,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8382,8 +8382,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8398,8 +8398,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -8407,8 +8407,8 @@ } // end of method Test_Call_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8422,8 +8422,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8438,8 +8438,8 @@ } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -8447,8 +8447,8 @@ } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8462,8 +8462,8 @@ .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8476,19 +8476,19 @@ call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8498,12 +8498,12 @@ ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8515,20 +8515,20 @@ ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8538,12 +8538,12 @@ ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8555,20 +8555,20 @@ ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8578,12 +8578,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8595,20 +8595,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8618,12 +8618,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8635,20 +8635,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8658,12 +8658,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8675,20 +8675,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8698,12 +8698,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8715,20 +8715,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8738,12 +8738,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8755,20 +8755,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8778,12 +8778,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8795,11 +8795,11 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" ldstr "!!1" @@ -8807,11 +8807,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8824,12 +8824,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8844,11 +8844,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" ldstr "!!1" @@ -8856,11 +8856,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8873,12 +8873,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8893,11 +8893,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -8905,11 +8905,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8922,12 +8922,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8942,11 +8942,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -8954,11 +8954,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -8971,12 +8971,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -8991,11 +8991,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -9003,11 +9003,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9020,12 +9020,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9040,11 +9040,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -9052,11 +9052,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9069,12 +9069,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9089,11 +9089,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod>" ldstr "!!1" @@ -9101,11 +9101,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9118,12 +9118,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9138,11 +9138,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod>" ldstr "!!1" @@ -9150,11 +9150,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9167,12 +9167,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9187,11 +9187,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" ldstr "!!1" @@ -9199,11 +9199,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9216,12 +9216,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9236,11 +9236,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" ldstr "!!1" @@ -9248,11 +9248,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9265,12 +9265,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9285,11 +9285,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -9297,11 +9297,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9314,12 +9314,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9334,11 +9334,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -9346,11 +9346,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9363,12 +9363,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9383,11 +9383,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -9395,11 +9395,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9412,12 +9412,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9432,11 +9432,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -9444,11 +9444,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9461,12 +9461,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9481,11 +9481,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod>" ldstr "!!1" @@ -9493,11 +9493,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9510,12 +9510,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9530,11 +9530,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod>" ldstr "!!1" @@ -9542,11 +9542,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9559,12 +9559,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9579,20 +9579,20 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9602,12 +9602,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9619,20 +9619,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9642,12 +9642,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9659,20 +9659,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9682,12 +9682,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9699,20 +9699,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9722,12 +9722,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9739,20 +9739,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9762,12 +9762,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9779,20 +9779,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9802,12 +9802,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9819,20 +9819,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9842,12 +9842,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9859,20 +9859,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9882,12 +9882,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9899,11 +9899,11 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + } // end of method Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -9911,8 +9911,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9926,8 +9926,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9942,8 +9942,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -9951,8 +9951,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -9966,8 +9966,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -9982,8 +9982,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -9991,8 +9991,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10006,8 +10006,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10022,8 +10022,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10031,8 +10031,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10046,8 +10046,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10062,8 +10062,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10071,8 +10071,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10086,8 +10086,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10102,8 +10102,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10111,8 +10111,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10126,8 +10126,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10142,8 +10142,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10151,8 +10151,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10166,8 +10166,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10182,8 +10182,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10191,8 +10191,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10206,8 +10206,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10222,8 +10222,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10231,8 +10231,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10246,8 +10246,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10262,8 +10262,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10271,8 +10271,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10286,8 +10286,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10302,8 +10302,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10311,8 +10311,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10326,8 +10326,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10342,8 +10342,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10351,8 +10351,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10366,8 +10366,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10382,8 +10382,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10391,8 +10391,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10406,8 +10406,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10422,8 +10422,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10431,8 +10431,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10446,8 +10446,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10462,8 +10462,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10471,8 +10471,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10486,8 +10486,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10502,8 +10502,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10511,8 +10511,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10526,8 +10526,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10542,8 +10542,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10551,8 +10551,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10566,8 +10566,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10582,8 +10582,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10591,8 +10591,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10606,8 +10606,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10622,8 +10622,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10631,8 +10631,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10646,8 +10646,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10662,8 +10662,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10671,8 +10671,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10686,8 +10686,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10702,8 +10702,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10711,8 +10711,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10726,8 +10726,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10742,8 +10742,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10751,8 +10751,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10766,8 +10766,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10782,8 +10782,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10791,8 +10791,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10806,8 +10806,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10822,8 +10822,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10831,8 +10831,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10846,8 +10846,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10862,8 +10862,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10871,8 +10871,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10886,8 +10886,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10902,8 +10902,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10911,8 +10911,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10926,8 +10926,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10942,8 +10942,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10951,8 +10951,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -10966,8 +10966,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -10982,8 +10982,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -10991,8 +10991,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11006,8 +11006,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11022,8 +11022,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11031,8 +11031,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11046,8 +11046,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11062,8 +11062,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11071,8 +11071,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11086,8 +11086,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11102,8 +11102,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11111,8 +11111,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11126,8 +11126,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11142,8 +11142,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11151,8 +11151,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11166,8 +11166,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11182,8 +11182,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11191,8 +11191,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11206,8 +11206,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11222,8 +11222,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11231,8 +11231,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11246,8 +11246,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11262,8 +11262,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11271,8 +11271,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11286,8 +11286,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11302,8 +11302,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11311,8 +11311,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11326,8 +11326,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11342,8 +11342,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11351,8 +11351,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11366,8 +11366,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11382,8 +11382,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11391,8 +11391,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11406,8 +11406,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11422,8 +11422,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11431,8 +11431,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11446,8 +11446,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11462,8 +11462,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11471,8 +11471,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11486,8 +11486,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11502,8 +11502,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11511,8 +11511,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11526,8 +11526,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11542,8 +11542,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11551,8 +11551,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11566,8 +11566,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11582,8 +11582,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11591,8 +11591,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11606,8 +11606,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11622,8 +11622,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11631,8 +11631,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11646,8 +11646,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11662,8 +11662,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11671,8 +11671,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11686,8 +11686,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11702,8 +11702,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11711,8 +11711,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11726,8 +11726,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11742,8 +11742,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11751,8 +11751,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11766,8 +11766,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11782,8 +11782,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11791,8 +11791,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11806,8 +11806,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11822,8 +11822,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11831,8 +11831,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11846,8 +11846,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11862,8 +11862,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11871,8 +11871,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11886,8 +11886,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11902,8 +11902,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11911,8 +11911,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11926,8 +11926,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11942,8 +11942,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11951,8 +11951,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -11966,8 +11966,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -11982,8 +11982,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -11991,8 +11991,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12006,8 +12006,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12022,8 +12022,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12031,8 +12031,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12046,8 +12046,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12062,8 +12062,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12071,8 +12071,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12086,8 +12086,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12102,8 +12102,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12111,8 +12111,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12126,8 +12126,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12142,8 +12142,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12151,8 +12151,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12166,8 +12166,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12182,8 +12182,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12191,8 +12191,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12206,8 +12206,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12222,8 +12222,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12231,8 +12231,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12246,8 +12246,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12262,8 +12262,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12271,8 +12271,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12286,8 +12286,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12302,8 +12302,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12311,8 +12311,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12326,8 +12326,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12342,8 +12342,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12351,8 +12351,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12366,8 +12366,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12382,8 +12382,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12391,8 +12391,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12406,8 +12406,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12422,8 +12422,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() ldstr "Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12431,8 +12431,8 @@ } // end of method Test_Call_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12446,8 +12446,8 @@ .method public static void Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1> - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1> + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12462,8 +12462,8 @@ } // end of method Test_CreateDelegate_GenericOverGenericStructOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12471,8 +12471,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12486,8 +12486,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12502,8 +12502,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12511,8 +12511,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12526,8 +12526,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12542,8 +12542,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12551,8 +12551,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12566,8 +12566,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12582,8 +12582,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12591,8 +12591,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12606,8 +12606,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12622,8 +12622,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12631,8 +12631,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12646,8 +12646,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12662,8 +12662,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12671,8 +12671,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12686,8 +12686,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12702,8 +12702,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12711,8 +12711,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12726,8 +12726,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12742,8 +12742,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12751,8 +12751,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12766,8 +12766,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12782,8 +12782,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12791,8 +12791,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12806,8 +12806,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12822,8 +12822,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12831,8 +12831,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12846,8 +12846,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12862,8 +12862,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12871,8 +12871,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12886,8 +12886,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12902,8 +12902,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12911,8 +12911,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12926,8 +12926,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12942,8 +12942,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12951,8 +12951,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -12966,8 +12966,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -12982,8 +12982,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -12991,8 +12991,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13006,8 +13006,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13022,8 +13022,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13031,8 +13031,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13046,8 +13046,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13062,8 +13062,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13071,8 +13071,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13086,8 +13086,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13102,8 +13102,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13111,8 +13111,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13126,8 +13126,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13142,8 +13142,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13151,8 +13151,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13166,8 +13166,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13182,8 +13182,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13191,8 +13191,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13206,8 +13206,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13222,8 +13222,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13231,8 +13231,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13246,8 +13246,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13262,8 +13262,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13271,8 +13271,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13286,8 +13286,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13302,8 +13302,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13311,8 +13311,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13326,8 +13326,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13342,8 +13342,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13351,8 +13351,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13366,8 +13366,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13382,8 +13382,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13391,8 +13391,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13406,8 +13406,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13422,8 +13422,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_NonGeneric_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13431,8 +13431,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13446,8 +13446,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13462,8 +13462,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13471,8 +13471,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13486,8 +13486,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13502,8 +13502,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13511,8 +13511,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13526,8 +13526,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13542,8 +13542,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13551,8 +13551,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13566,8 +13566,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13582,8 +13582,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13591,8 +13591,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13606,8 +13606,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13622,8 +13622,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13631,8 +13631,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13646,8 +13646,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13662,8 +13662,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13671,8 +13671,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13686,8 +13686,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13702,8 +13702,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13711,8 +13711,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13726,8 +13726,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13742,8 +13742,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13751,8 +13751,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13766,8 +13766,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13782,8 +13782,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13791,8 +13791,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13806,8 +13806,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13822,8 +13822,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13831,8 +13831,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13846,8 +13846,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13862,8 +13862,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13871,8 +13871,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13886,8 +13886,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13902,8 +13902,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13911,8 +13911,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13926,8 +13926,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13942,8 +13942,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13951,8 +13951,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -13966,8 +13966,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -13982,8 +13982,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -13991,8 +13991,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14006,8 +14006,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14022,8 +14022,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14031,8 +14031,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14046,8 +14046,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14062,8 +14062,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14071,8 +14071,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14086,8 +14086,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14102,8 +14102,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14111,8 +14111,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14126,8 +14126,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14142,8 +14142,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14151,8 +14151,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14166,8 +14166,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14182,8 +14182,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14191,8 +14191,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14206,8 +14206,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14222,8 +14222,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14231,8 +14231,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14246,8 +14246,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14262,8 +14262,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14271,8 +14271,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14286,8 +14286,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14302,8 +14302,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14311,8 +14311,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14326,8 +14326,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14342,8 +14342,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14351,8 +14351,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14366,8 +14366,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14382,8 +14382,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14391,8 +14391,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14406,8 +14406,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14422,8 +14422,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14431,8 +14431,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14446,8 +14446,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14462,8 +14462,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14471,8 +14471,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14486,8 +14486,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14502,8 +14502,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14511,8 +14511,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14526,8 +14526,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14542,8 +14542,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14551,8 +14551,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14566,8 +14566,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14582,8 +14582,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14591,8 +14591,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14606,8 +14606,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14622,8 +14622,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14631,8 +14631,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14646,8 +14646,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14662,8 +14662,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14671,8 +14671,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14686,8 +14686,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14702,8 +14702,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14711,8 +14711,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14726,8 +14726,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14742,8 +14742,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14751,8 +14751,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14766,8 +14766,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14782,8 +14782,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14791,8 +14791,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14806,8 +14806,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14822,8 +14822,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14831,8 +14831,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14846,8 +14846,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14862,8 +14862,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14871,8 +14871,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14886,8 +14886,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14902,8 +14902,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14911,8 +14911,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14926,8 +14926,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14942,8 +14942,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14951,8 +14951,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -14966,8 +14966,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -14982,8 +14982,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -14991,8 +14991,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15006,8 +15006,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15022,8 +15022,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15031,8 +15031,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15046,8 +15046,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15062,8 +15062,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15071,8 +15071,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15086,8 +15086,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15102,8 +15102,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15111,8 +15111,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15126,8 +15126,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15142,8 +15142,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15151,8 +15151,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15166,8 +15166,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15182,8 +15182,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15191,8 +15191,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15206,8 +15206,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15222,8 +15222,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15231,8 +15231,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15246,8 +15246,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15262,8 +15262,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15271,8 +15271,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15286,8 +15286,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15302,8 +15302,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15311,8 +15311,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15326,8 +15326,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15342,8 +15342,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15351,8 +15351,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15366,8 +15366,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15382,8 +15382,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15391,8 +15391,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15406,8 +15406,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15422,8 +15422,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15431,8 +15431,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15446,8 +15446,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15462,8 +15462,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15471,8 +15471,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15486,8 +15486,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15502,8 +15502,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15511,8 +15511,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15526,8 +15526,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15542,8 +15542,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15551,8 +15551,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15566,8 +15566,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15582,8 +15582,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15591,8 +15591,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15606,8 +15606,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15622,8 +15622,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15631,8 +15631,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15646,8 +15646,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15662,8 +15662,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15671,8 +15671,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15686,8 +15686,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15702,8 +15702,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15711,8 +15711,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15726,8 +15726,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15742,8 +15742,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15751,8 +15751,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15766,8 +15766,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15782,8 +15782,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15791,8 +15791,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15806,8 +15806,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15822,8 +15822,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15831,8 +15831,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15846,8 +15846,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15862,8 +15862,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15871,8 +15871,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15886,8 +15886,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15902,8 +15902,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15911,8 +15911,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15926,8 +15926,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15942,8 +15942,8 @@ } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -15951,8 +15951,8 @@ } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -15966,8 +15966,8 @@ .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -15980,19 +15980,19 @@ call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16002,12 +16002,12 @@ ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16019,20 +16019,20 @@ ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16042,12 +16042,12 @@ ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16059,20 +16059,20 @@ ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16082,12 +16082,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16099,20 +16099,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16122,12 +16122,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16139,20 +16139,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16162,12 +16162,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16179,20 +16179,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16202,12 +16202,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16219,20 +16219,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16242,12 +16242,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16259,20 +16259,20 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16282,12 +16282,12 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16299,11 +16299,11 @@ ldstr "IFaceNonGenericDefaultImp.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter<([GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" ldstr "!!1" @@ -16311,11 +16311,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16328,12 +16328,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16348,11 +16348,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" ldstr "!!1" @@ -16360,11 +16360,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16377,12 +16377,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16397,11 +16397,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -16409,11 +16409,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16426,12 +16426,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16446,11 +16446,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -16458,11 +16458,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16475,12 +16475,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16495,11 +16495,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -16507,11 +16507,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16524,12 +16524,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16544,11 +16544,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -16556,11 +16556,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16573,12 +16573,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16593,11 +16593,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod>" ldstr "!!1" @@ -16605,11 +16605,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16622,12 +16622,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16642,11 +16642,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod>" ldstr "!!1" @@ -16654,11 +16654,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16671,12 +16671,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16691,11 +16691,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" ldstr "!!1" @@ -16703,11 +16703,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16720,12 +16720,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16740,11 +16740,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" ldstr "!!1" @@ -16752,11 +16752,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16769,12 +16769,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16789,11 +16789,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -16801,11 +16801,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16818,12 +16818,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16838,11 +16838,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -16850,11 +16850,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16867,12 +16867,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16887,11 +16887,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -16899,11 +16899,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16916,12 +16916,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16936,11 +16936,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" ldstr "!!1" @@ -16948,11 +16948,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -16965,12 +16965,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -16985,11 +16985,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod>" ldstr "!!1" @@ -16997,11 +16997,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17014,12 +17014,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17034,11 +17034,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod>" ldstr "!!1" @@ -17046,11 +17046,11 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17063,12 +17063,12 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17083,20 +17083,20 @@ call instance string [System.Runtime]System.String::Replace(string, string) call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17106,12 +17106,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17123,20 +17123,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17146,12 +17146,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17163,20 +17163,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17186,12 +17186,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17203,20 +17203,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17226,12 +17226,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17243,20 +17243,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17266,12 +17266,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17283,20 +17283,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17306,12 +17306,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17323,20 +17323,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17346,12 +17346,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17363,20 +17363,20 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17386,12 +17386,12 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> - .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining + } // end of method Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + .method public static void Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U>() cil managed noinlining { ldnull constrained. !!0 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17403,11 +17403,11 @@ ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod>" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) ret - } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> + } // end of method Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter<(class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>) T,U> .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17415,8 +17415,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17430,8 +17430,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17446,8 +17446,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17455,8 +17455,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17470,8 +17470,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17486,8 +17486,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17495,8 +17495,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17510,8 +17510,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17526,8 +17526,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17535,8 +17535,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17550,8 +17550,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17566,8 +17566,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17575,8 +17575,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17590,8 +17590,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17606,8 +17606,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17615,8 +17615,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17630,8 +17630,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17646,8 +17646,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17655,8 +17655,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17670,8 +17670,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17686,8 +17686,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17695,8 +17695,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17710,8 +17710,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17726,8 +17726,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17735,8 +17735,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17750,8 +17750,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17766,8 +17766,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17775,8 +17775,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17790,8 +17790,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17806,8 +17806,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17815,8 +17815,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17830,8 +17830,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17846,8 +17846,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17855,8 +17855,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17870,8 +17870,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17886,8 +17886,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17895,8 +17895,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17910,8 +17910,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17926,8 +17926,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17935,8 +17935,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17950,8 +17950,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -17966,8 +17966,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -17975,8 +17975,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -17990,8 +17990,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18006,8 +18006,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18015,8 +18015,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18030,8 +18030,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18046,8 +18046,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18055,8 +18055,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18070,8 +18070,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18086,8 +18086,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18095,8 +18095,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18110,8 +18110,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18126,8 +18126,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18135,8 +18135,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18150,8 +18150,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18166,8 +18166,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18175,8 +18175,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18190,8 +18190,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18206,8 +18206,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18215,8 +18215,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18230,8 +18230,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18246,8 +18246,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18255,8 +18255,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18270,8 +18270,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18286,8 +18286,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18295,8 +18295,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18310,8 +18310,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18326,8 +18326,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18335,8 +18335,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18350,8 +18350,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18366,8 +18366,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18375,8 +18375,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18390,8 +18390,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18406,8 +18406,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18415,8 +18415,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18430,8 +18430,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18446,8 +18446,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18455,8 +18455,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18470,8 +18470,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18486,8 +18486,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18495,8 +18495,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18510,8 +18510,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18526,8 +18526,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18535,8 +18535,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18550,8 +18550,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18566,8 +18566,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18575,8 +18575,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18590,8 +18590,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18606,8 +18606,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18615,8 +18615,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18630,8 +18630,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18646,8 +18646,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18655,8 +18655,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18670,8 +18670,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18686,8 +18686,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverInt32_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18695,8 +18695,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18710,8 +18710,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18726,8 +18726,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_NormalMethod" ldstr "IFaceNonGenericDefaultImp.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18735,8 +18735,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18750,8 +18750,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18766,8 +18766,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18775,8 +18775,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18790,8 +18790,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18806,8 +18806,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18815,8 +18815,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18830,8 +18830,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18846,8 +18846,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18855,8 +18855,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18870,8 +18870,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18886,8 +18886,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18895,8 +18895,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18910,8 +18910,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18926,8 +18926,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18935,8 +18935,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18950,8 +18950,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -18966,8 +18966,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter" ldstr "IFaceNonGenericDefaultImp.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -18975,8 +18975,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -18990,8 +18990,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceNonGenericDefaultImp::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceNonGenericDefaultImp::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19006,8 +19006,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_NonGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19015,8 +19015,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19030,8 +19030,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19046,8 +19046,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19055,8 +19055,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19070,8 +19070,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19086,8 +19086,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19095,8 +19095,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19110,8 +19110,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19126,8 +19126,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19135,8 +19135,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19150,8 +19150,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19166,8 +19166,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19175,8 +19175,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19190,8 +19190,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19206,8 +19206,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19215,8 +19215,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19230,8 +19230,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19246,8 +19246,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19255,8 +19255,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19270,8 +19270,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19286,8 +19286,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19295,8 +19295,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19310,8 +19310,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19326,8 +19326,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverString_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19335,8 +19335,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19350,8 +19350,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19366,8 +19366,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_NormalMethod" ldstr "IFaceGenericDefaultImp`1.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19375,8 +19375,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19390,8 +19390,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19406,8 +19406,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19415,8 +19415,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19430,8 +19430,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19446,8 +19446,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19455,8 +19455,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19470,8 +19470,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19486,8 +19486,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19495,8 +19495,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19510,8 +19510,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19526,8 +19526,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19535,8 +19535,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19550,8 +19550,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19566,8 +19566,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19575,8 +19575,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19590,8 +19590,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19606,8 +19606,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter" ldstr "IFaceGenericDefaultImp`1.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19615,8 +19615,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19630,8 +19630,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceGenericDefaultImp`1::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceGenericDefaultImp`1::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19646,8 +19646,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_GenericOverObject_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19655,8 +19655,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19670,8 +19670,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19686,8 +19686,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.NormalMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19695,8 +19695,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19710,8 +19710,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::NormalMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19726,8 +19726,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_NormalMethod .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19735,8 +19735,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19750,8 +19750,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19766,8 +19766,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19775,8 +19775,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19790,8 +19790,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19806,8 +19806,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverInt .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19815,8 +19815,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19830,8 +19830,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19846,8 +19846,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19855,8 +19855,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19870,8 +19870,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19886,8 +19886,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverString .method public static void Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19895,8 +19895,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19910,8 +19910,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. class [GenericContextCommonAndImplementation]GenericClass`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. class [GenericContextCommonAndImplementationDICallDI]GenericClass`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -19926,8 +19926,8 @@ } // end of method Test_CreateDelegate_GenericOverTypeParameterGenericClass_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - call void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + call void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() ldstr "Call_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter" ldstr "IFaceCuriouslyRecurringGenericDefaultImp`1>.GenericMethod" call void [GenericContextCommonCs]Statics::CheckForFailure(string,string) @@ -19935,8 +19935,8 @@ } // end of method Test_Call_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter .method public static void Test_Ldftn_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() volatile. stsfld native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) [GenericContextCommonCs]Statics::FtnHolder volatile. @@ -19950,8 +19950,8 @@ .method public static void Test_CreateDelegate_GenericOverTypeParameterGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() cil managed noinlining { ldnull - constrained. valuetype [GenericContextCommonAndImplementation]GenericValuetype`1 - ldftn void class [GenericContextCommonAndImplementation]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() + constrained. valuetype [GenericContextCommonAndImplementationDICallDI]GenericValuetype`1 + ldftn void class [GenericContextCommonAndImplementationDICallDI]IFaceCuriouslyRecurringGenericDefaultImp`1>::GenericMethod() newobj instance void [System.Runtime]System.Action::.ctor(object, native int) volatile. @@ -23404,7 +23404,7 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_ } CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23417,7 +23417,7 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverString_CuriouslyRecurrin } Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23430,7 +23430,7 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMetho } Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23443,7 +23443,7 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMeth } CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23456,7 +23456,7 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_N } Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23469,7 +23469,7 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalM } Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23482,7 +23482,7 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_Normal } CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23495,7 +23495,7 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGener } Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23508,7 +23508,7 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMeth } Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23521,7 +23521,7 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMet } CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23534,7 +23534,7 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_G } Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23547,7 +23547,7 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_Generic } Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23560,7 +23560,7 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_Generi } CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23573,7 +23573,7 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGener } Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23586,7 +23586,7 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMeth } Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23599,7 +23599,7 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMet } CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23612,7 +23612,7 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_G } Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23625,7 +23625,7 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_Generic } Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23638,7 +23638,7 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_Generi } CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23651,7 +23651,7 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGener } Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23664,7 +23664,7 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMeth } Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23677,7 +23677,7 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMet } CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23690,7 +23690,7 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_NonGeneric_G } Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23703,7 +23703,7 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_Generic } Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23718,7 +23718,7 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_NonGener .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23733,7 +23733,7 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_Norm .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23748,7 +23748,7 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_Nor .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23763,7 +23763,7 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverS .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23778,7 +23778,7 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23793,7 +23793,7 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23808,7 +23808,7 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23823,7 +23823,7 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23838,7 +23838,7 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23853,7 +23853,7 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverS .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23868,7 +23868,7 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23883,7 +23883,7 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23898,7 +23898,7 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23913,7 +23913,7 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23928,7 +23928,7 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23943,7 +23943,7 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverS .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23958,7 +23958,7 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23973,7 +23973,7 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -23988,7 +23988,7 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24003,7 +24003,7 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24018,7 +24018,7 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24033,7 +24033,7 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverS .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24048,7 +24048,7 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24063,7 +24063,7 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24078,10 +24078,10 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24096,10 +24096,10 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_Norm .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24114,10 +24114,10 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_Nor .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24132,10 +24132,10 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24150,10 +24150,10 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24168,10 +24168,10 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24186,10 +24186,10 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24204,10 +24204,10 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24222,10 +24222,10 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24240,10 +24240,10 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24258,10 +24258,10 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24276,10 +24276,10 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24294,10 +24294,10 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24312,10 +24312,10 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24330,10 +24330,10 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24348,10 +24348,10 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24366,10 +24366,10 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24384,10 +24384,10 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24402,10 +24402,10 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24420,10 +24420,10 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24438,10 +24438,10 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24456,10 +24456,10 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_GenericOverO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24474,10 +24474,10 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24492,10 +24492,10 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24508,7 +24508,7 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject } CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24521,7 +24521,7 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_GenericO } Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24534,7 +24534,7 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGene } Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24547,7 +24547,7 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGen } CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24560,7 +24560,7 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRec } Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24573,7 +24573,7 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurring } Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24586,7 +24586,7 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurrin } CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24599,7 +24599,7 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_Curiousl } Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24612,7 +24612,7 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGene } Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24625,7 +24625,7 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGen } CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24638,7 +24638,7 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRec } Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24651,7 +24651,7 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurring } Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24664,7 +24664,7 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurrin } CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24677,7 +24677,7 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_Curiousl } Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24690,7 +24690,7 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGene } Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24703,7 +24703,7 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGen } CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24716,7 +24716,7 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRec } Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24729,7 +24729,7 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurring } Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24742,7 +24742,7 @@ Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurrin } CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() leave.s Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24755,7 +24755,7 @@ CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_Curiousl } Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() leave.s Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24768,7 +24768,7 @@ Call_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGene } Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() leave.s CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24781,7 +24781,7 @@ Ldftn_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGen } CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() leave.s Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24794,7 +24794,7 @@ CreateDelegate_NonGenericNonGenericClass_GenericOverConstrainedType_CuriouslyRec } Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() leave.s Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -24807,7 +24807,7 @@ Call_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurring } Ldftn_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() + call void TestEntrypoint::Test_CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter() leave.s CreateDelegate_NonGenericNonGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28252,7 +28252,7 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGene } CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28265,7 +28265,7 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverString_CuriouslyRecu } Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28278,7 +28278,7 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalM } Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28291,7 +28291,7 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_Normal } CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28304,7 +28304,7 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGener } Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28317,7 +28317,7 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_Nor } Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28330,7 +28330,7 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_No } CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28343,7 +28343,7 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonG } Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28356,7 +28356,7 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_Generic } Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28369,7 +28369,7 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_Generi } CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28382,7 +28382,7 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGener } Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28395,7 +28395,7 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_Gen } Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28408,7 +28408,7 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_Ge } CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28421,7 +28421,7 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonG } Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28434,7 +28434,7 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_Generic } Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28447,7 +28447,7 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_Generi } CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28460,7 +28460,7 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGener } Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28473,7 +28473,7 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_Gen } Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28486,7 +28486,7 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_Ge } CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28499,7 +28499,7 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonG } Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28512,7 +28512,7 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_Generic } Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28525,7 +28525,7 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_Generi } CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28538,7 +28538,7 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_NonGener } Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28551,7 +28551,7 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_Gen } Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28566,7 +28566,7 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_NonG .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28581,7 +28581,7 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28596,7 +28596,7 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28611,7 +28611,7 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28626,7 +28626,7 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverStr .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28641,7 +28641,7 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverSt .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28656,7 +28656,7 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28671,7 +28671,7 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28686,7 +28686,7 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28701,7 +28701,7 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28716,7 +28716,7 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverStr .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28731,7 +28731,7 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverSt .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28746,7 +28746,7 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28761,7 +28761,7 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28776,7 +28776,7 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28791,7 +28791,7 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28806,7 +28806,7 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverStr .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28821,7 +28821,7 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverSt .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28836,7 +28836,7 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28851,7 +28851,7 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28866,7 +28866,7 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28881,7 +28881,7 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28896,7 +28896,7 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverStr .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28911,7 +28911,7 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverSt .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28926,10 +28926,10 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28944,10 +28944,10 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28962,10 +28962,10 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28980,10 +28980,10 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -28998,10 +28998,10 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObj .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29016,10 +29016,10 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverOb .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29034,10 +29034,10 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29052,10 +29052,10 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29070,10 +29070,10 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29088,10 +29088,10 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29106,10 +29106,10 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObj .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29124,10 +29124,10 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverOb .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29142,10 +29142,10 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29160,10 +29160,10 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29178,10 +29178,10 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29196,10 +29196,10 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29214,10 +29214,10 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObj .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29232,10 +29232,10 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverOb .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29250,10 +29250,10 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29268,10 +29268,10 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29286,10 +29286,10 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29304,10 +29304,10 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_GenericO .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29322,10 +29322,10 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObj .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29340,10 +29340,10 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverOb .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29356,7 +29356,7 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverOb } CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29369,7 +29369,7 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_Gene } Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29382,7 +29382,7 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurring } Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29395,7 +29395,7 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurrin } CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29408,7 +29408,7 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_Curiousl } Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29421,7 +29421,7 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecur } Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29434,7 +29434,7 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecu } CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29447,7 +29447,7 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_Curi } Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29460,7 +29460,7 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurring } Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29473,7 +29473,7 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurrin } CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29486,7 +29486,7 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_Curiousl } Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29499,7 +29499,7 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecur } Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29512,7 +29512,7 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecu } CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29525,7 +29525,7 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_Curi } Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29538,7 +29538,7 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurring } Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29551,7 +29551,7 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurrin } CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29564,7 +29564,7 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_Curiousl } Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29577,7 +29577,7 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecur } Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29590,7 +29590,7 @@ Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecu } CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() leave.s Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29603,7 +29603,7 @@ CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_Curi } Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() leave.s Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29616,7 +29616,7 @@ Call_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurring } Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() leave.s CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29629,7 +29629,7 @@ Ldftn_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurrin } CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() leave.s Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29642,7 +29642,7 @@ CreateDelegate_GenericOverStructGenericClass_GenericOverConstrainedType_Curiousl } Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() leave.s Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -29655,7 +29655,7 @@ Call_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecur } Ldftn_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() leave.s CreateDelegate_GenericOverStructGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35596,7 +35596,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_Curiousl } CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35609,7 +35609,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverString } Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35622,7 +35622,7 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonG } Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35635,7 +35635,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Non } CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35648,7 +35648,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine } Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35661,7 +35661,7 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ } Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethod,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35674,7 +35674,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType } CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35687,7 +35687,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr } Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35700,7 +35700,7 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonG } Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35713,7 +35713,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Non } CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35726,7 +35726,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine } Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35739,7 +35739,7 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ } Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverInt,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35752,7 +35752,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType } CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35765,7 +35765,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr } Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35778,7 +35778,7 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonG } Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35791,7 +35791,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Non } CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35804,7 +35804,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine } Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35817,7 +35817,7 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ } Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverString,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35830,7 +35830,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType } CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35843,7 +35843,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr } Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35856,7 +35856,7 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonG } Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35869,7 +35869,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Non } CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35882,7 +35882,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine } Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35895,7 +35895,7 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ } Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameter,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_NonGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35910,7 +35910,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35925,7 +35925,7 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35940,7 +35940,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35955,7 +35955,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35970,7 +35970,7 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -35985,7 +35985,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethod,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36000,7 +36000,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36015,7 +36015,7 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36030,7 +36030,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36045,7 +36045,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36060,7 +36060,7 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36075,7 +36075,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverInt,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36090,7 +36090,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36105,7 +36105,7 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36120,7 +36120,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36135,7 +36135,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36150,7 +36150,7 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36165,7 +36165,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverString,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36180,7 +36180,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36195,7 +36195,7 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36210,7 +36210,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36225,7 +36225,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36240,7 +36240,7 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36255,7 +36255,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameter,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverString_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36270,10 +36270,10 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36288,10 +36288,10 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36306,10 +36306,10 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36324,10 +36324,10 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36342,10 +36342,10 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36360,10 +36360,10 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethod,object>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36378,10 +36378,10 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36396,10 +36396,10 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36414,10 +36414,10 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36432,10 +36432,10 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36450,10 +36450,10 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36468,10 +36468,10 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverInt,object>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36486,10 +36486,10 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36504,10 +36504,10 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36522,10 +36522,10 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36540,10 +36540,10 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36558,10 +36558,10 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36576,10 +36576,10 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverString,object>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36594,10 +36594,10 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36612,10 +36612,10 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gene .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36630,10 +36630,10 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Gen .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36648,10 +36648,10 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36666,10 +36666,10 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36684,10 +36684,10 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType .try { ldstr "string" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,string>() ldstr "object" stsfld string [GenericContextCommonCs]Statics::BangBang1Param - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameter,object>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36700,7 +36700,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType } CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_GenericOverObject_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36713,7 +36713,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr } Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36726,7 +36726,7 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Curi } Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36739,7 +36739,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Cur } CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36752,7 +36752,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine } Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36765,7 +36765,7 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ } Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethod,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36778,7 +36778,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType } CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_NormalMethodDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36791,7 +36791,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr } Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36804,7 +36804,7 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Curi } Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36817,7 +36817,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Cur } CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36830,7 +36830,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine } Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36843,7 +36843,7 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ } Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverInt,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36856,7 +36856,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType } CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverIntDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36869,7 +36869,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr } Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36882,7 +36882,7 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Curi } Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36895,7 +36895,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Cur } CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36908,7 +36908,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine } Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36921,7 +36921,7 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ } Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverString,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36934,7 +36934,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType } CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverStringDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() leave.s Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36947,7 +36947,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstr } Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36960,7 +36960,7 @@ Call_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Curi } Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36973,7 +36973,7 @@ Ldftn_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_Cur } CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() leave.s Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36986,7 +36986,7 @@ CreateDelegate_GenericOverReferenceType_ClassAGenericClass_GenericOverConstraine } Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() leave.s Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 @@ -36999,7 +36999,7 @@ Call_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_ } Ldftn_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone: nop .try { - call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() + call void TestEntrypoint::Test_CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameter,string>() leave.s CreateDelegate_GenericOverReferenceType_ClassAGenericValuetype_GenericOverConstrainedType_CuriouslyRecurringGeneric_GenericMethodOverTypeParameterDone } catch [System.Runtime]System.Exception { stloc.0 diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDefaultImpCallDefaultImp/GenericContextTestDefaultImpCallDefaultImp.ilproj b/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDICallDI/GenericContextTestDICallDI.ilproj similarity index 79% rename from src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDefaultImpCallDefaultImp/GenericContextTestDefaultImpCallDefaultImp.ilproj rename to src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDICallDI/GenericContextTestDICallDI.ilproj index d75af9b8dafdfb..0f878a7e4a537a 100644 --- a/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDefaultImpCallDefaultImp/GenericContextTestDefaultImpCallDefaultImp.ilproj +++ b/src/tests/Loader/classloader/StaticVirtualMethods/GenericContext/GenericContextTestDICallDI/GenericContextTestDICallDI.ilproj @@ -6,8 +6,8 @@ Full - + - + diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/Regression/RecursiveConstraintOnDefaultImplementationOfStaticAbstractMember.cs b/src/tests/Loader/classloader/StaticVirtualMethods/Regression/RecursiveConstraintOnDIOfStaticAbstractMember.cs similarity index 100% rename from src/tests/Loader/classloader/StaticVirtualMethods/Regression/RecursiveConstraintOnDefaultImplementationOfStaticAbstractMember.cs rename to src/tests/Loader/classloader/StaticVirtualMethods/Regression/RecursiveConstraintOnDIOfStaticAbstractMember.cs diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/Regression/RecursiveConstraintOnDefaultImplementationOfStaticAbstractMember.csproj b/src/tests/Loader/classloader/StaticVirtualMethods/Regression/RecursiveConstraintOnDIOfStaticAbstractMember.csproj similarity index 100% rename from src/tests/Loader/classloader/StaticVirtualMethods/Regression/RecursiveConstraintOnDefaultImplementationOfStaticAbstractMember.csproj rename to src/tests/Loader/classloader/StaticVirtualMethods/Regression/RecursiveConstraintOnDIOfStaticAbstractMember.csproj diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/Regression/StaticVirtualsAndMethodConstraintsAndDefaultImplementation.cs b/src/tests/Loader/classloader/StaticVirtualMethods/Regression/StaticVirtualsAndMethodConstraintsAndDI.cs similarity index 100% rename from src/tests/Loader/classloader/StaticVirtualMethods/Regression/StaticVirtualsAndMethodConstraintsAndDefaultImplementation.cs rename to src/tests/Loader/classloader/StaticVirtualMethods/Regression/StaticVirtualsAndMethodConstraintsAndDI.cs diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/Regression/StaticVirtualsAndMethodConstraintsAndDefaultImplementation.csproj b/src/tests/Loader/classloader/StaticVirtualMethods/Regression/StaticVirtualsAndMethodConstraintsAndDI.csproj similarity index 100% rename from src/tests/Loader/classloader/StaticVirtualMethods/Regression/StaticVirtualsAndMethodConstraintsAndDefaultImplementation.csproj rename to src/tests/Loader/classloader/StaticVirtualMethods/Regression/StaticVirtualsAndMethodConstraintsAndDI.csproj From ef39923825b7443216cc25f163584fbb0bd177fa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 14:25:31 +0100 Subject: [PATCH 546/783] [release/8.0-staging] Fix idle HTTP/2 connection KeepAliveTimeout teardown (#96158) * Fix idle HTTP/2 connection KeepAliveTimeout teardown * Update src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Http2KeepAlivePing.cs --------- Co-authored-by: Miha Zupan --- .../SocketsHttpHandler/Http2Connection.cs | 11 ++-- ...cketsHttpHandlerTest.Http2KeepAlivePing.cs | 60 ++++++++----------- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs index f96ce45dc26f59..e9cce1c24d34d5 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs @@ -260,11 +260,13 @@ private void Shutdown() if (!_shutdown) { + // InvalidateHttp2Connection may call back into Shutdown, + // so we set the flag early to prevent executing FinalTeardown twice. + _shutdown = true; + _pool.InvalidateHttp2Connection(this); SignalAvailableStreamsWaiter(false); - _shutdown = true; - if (_streamsInUse == 0) { FinalTeardown(); @@ -359,7 +361,7 @@ private void SignalAvailableStreamsWaiter(bool result) if (_availableStreamsWaiter is not null) { - Debug.Assert(!_shutdown); + Debug.Assert(_shutdown != result); _availableStreamsWaiter.SetResult(result); _availableStreamsWaiter = null; } @@ -1850,7 +1852,8 @@ private void FinalTeardown() _stream.Dispose(); _connectionWindow.Dispose(); - _writeChannel.Writer.Complete(); + bool completed = _writeChannel.Writer.TryComplete(); + Debug.Assert(completed, "FinalTeardown was called twice"); // We're not disposing the _incomingBuffer and _outgoingBuffer here as they may still be in use by // ProcessIncomingFramesAsync and ProcessOutgoingFramesAsync respectively, and those methods are diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Http2KeepAlivePing.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Http2KeepAlivePing.cs index 4fd9251ba24cca..a9beb393918b5c 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Http2KeepAlivePing.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Http2KeepAlivePing.cs @@ -28,7 +28,7 @@ public sealed class SocketsHttpHandler_Http2KeepAlivePing_Test : HttpClientHandl private CancellationTokenSource _incomingFramesCts = new CancellationTokenSource(); private Task _incomingFramesTask; private TaskCompletionSource _serverFinished = new TaskCompletionSource(); - private int _sendPingResponse = 1; + private bool _sendPingResponse = true; private static Http2Options NoAutoPingResponseHttp2Options => new Http2Options() { EnableTransparentPingResponse = false }; @@ -90,7 +90,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => Assert.True(_pingCounter <= 1); await TerminateLoopbackConnectionAsync(); - }).WaitAsync(TestTimeout); + }); } [OuterLoop("Runs long")] @@ -168,13 +168,15 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => } Assert.False(unexpectedFrames.Any(), "Received unexpected frames: \n" + string.Join('\n', unexpectedFrames.Select(f => f.ToString()).ToArray())); - }, NoAutoPingResponseHttp2Options).WaitAsync(TestTimeout); + }, NoAutoPingResponseHttp2Options); } [OuterLoop("Runs long")] [Fact] public async Task KeepAliveConfigured_NoPingResponseDuringActiveStream_RequestShouldFail() { + _sendPingResponse = false; + await Http2LoopbackServer.CreateClientAndServerAsync(async uri => { SocketsHttpHandler handler = CreateSocketsHttpHandler(allowAllCertificates: true); @@ -190,7 +192,11 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => Assert.Equal(HttpStatusCode.OK, response0.StatusCode); // Actual request: - await Assert.ThrowsAsync(() => client.GetAsync(uri)); + Exception ex = await Assert.ThrowsAsync(() => client.GetAsync(uri)); + + // The request should fail due to the connection being torn down due to KeepAlivePingTimeout. + HttpProtocolException pex = Assert.IsType(ex.InnerException); + Assert.Equal(HttpRequestError.HttpProtocolError, pex.HttpRequestError); // Let connection live until server finishes: await _serverFinished.Task; @@ -203,25 +209,19 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => int streamId1 = await ReadRequestHeaderAsync(); await GuardConnectionWriteAsync(() => _connection.SendDefaultResponseAsync(streamId1)); - // Request under the test scope. - int streamId2 = await ReadRequestHeaderAsync(); - - DisablePingResponse(); - - // Simulate inactive period: - await Task.Delay(6_000); - - // Finish the response: - await GuardConnectionWriteAsync(() => _connection.SendDefaultResponseAsync(streamId2)); + // Wait for the client to disconnect due to hitting the KeepAliveTimeout + await _incomingFramesTask; await TerminateLoopbackConnectionAsync(); - }, NoAutoPingResponseHttp2Options).WaitAsync(TestTimeout); + }, NoAutoPingResponseHttp2Options); } [OuterLoop("Runs long")] [Fact] public async Task HttpKeepAlivePingPolicy_Always_NoPingResponseBetweenStreams_SecondRequestShouldFail() { + _sendPingResponse = false; + await Http2LoopbackServer.CreateClientAndServerAsync(async uri => { SocketsHttpHandler handler = CreateSocketsHttpHandler(allowAllCertificates: true); @@ -236,10 +236,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => HttpResponseMessage response0 = await client.GetAsync(uri); Assert.Equal(HttpStatusCode.OK, response0.StatusCode); - // Second request should fail: - await Assert.ThrowsAsync(() => client.GetAsync(uri)); - - // Let connection live until server finishes: + // Simulate inactive period by waiting until server finishes: await _serverFinished.Task; }, async server => @@ -250,19 +247,11 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => int streamId1 = await ReadRequestHeaderAsync(); await GuardConnectionWriteAsync(() => _connection.SendDefaultResponseAsync(streamId1)); - DisablePingResponse(); - - // Simulate inactive period: - await Task.Delay(6_000); - - // Request under the test scope. - int streamId2 = await ReadRequestHeaderAsync(); - - // Finish the response: - await GuardConnectionWriteAsync(() => _connection.SendDefaultResponseAsync(streamId2)); + // Wait for the client to disconnect due to hitting the KeepAliveTimeout + await _incomingFramesTask; await TerminateLoopbackConnectionAsync(); - }, NoAutoPingResponseHttp2Options).WaitAsync(TestTimeout); + }, NoAutoPingResponseHttp2Options); } private async Task ProcessIncomingFramesAsync(CancellationToken cancellationToken) @@ -273,6 +262,11 @@ private async Task ProcessIncomingFramesAsync(CancellationToken cancellationToke { Frame frame = await _connection.ReadFrameAsync(cancellationToken); + if (frame is null) + { + break; + } + if (frame is PingFrame pingFrame) { if (pingFrame.AckFlag) @@ -285,7 +279,7 @@ private async Task ProcessIncomingFramesAsync(CancellationToken cancellationToke _output?.WriteLine($"Received PING ({pingFrame.Data})"); Interlocked.Increment(ref _pingCounter); - if (_sendPingResponse > 0) + if (_sendPingResponse) { await GuardConnectionWriteAsync(() => _connection.SendPingAckAsync(pingFrame.Data, cancellationToken), cancellationToken); } @@ -295,7 +289,7 @@ private async Task ProcessIncomingFramesAsync(CancellationToken cancellationToke { _output?.WriteLine($"Received WINDOW_UPDATE"); } - else if (frame is not null) + else { //_output?.WriteLine($"Received {frame}"); await _framesChannel.Writer.WriteAsync(frame, cancellationToken); @@ -310,8 +304,6 @@ private async Task ProcessIncomingFramesAsync(CancellationToken cancellationToke await _connection.DisposeAsync(); } - private void DisablePingResponse() => Interlocked.Exchange(ref _sendPingResponse, 0); - private async Task EstablishConnectionAsync(Http2LoopbackServer server) { _connection = await server.EstablishConnectionAsync(); From 8db980c0f80207eada2f43cf1800b04a60eb94ae Mon Sep 17 00:00:00 2001 From: Tom McDonald Date: Thu, 4 Jan 2024 14:12:21 -0500 Subject: [PATCH 547/783] Skip address for x64 prefix parsing (#96375) --- src/coreclr/debug/ee/amd64/walker.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/coreclr/debug/ee/amd64/walker.cpp b/src/coreclr/debug/ee/amd64/walker.cpp index 79f0952dee1c47..815366def5b0d6 100644 --- a/src/coreclr/debug/ee/amd64/walker.cpp +++ b/src/coreclr/debug/ee/amd64/walker.cpp @@ -929,7 +929,6 @@ void NativeWalker::DecodeInstructionForPatchSkip(const BYTE *address, Instructio case 0x45: case 0x46: case 0x47: - done = true; break; // REX register extension prefixes with W @@ -942,7 +941,6 @@ void NativeWalker::DecodeInstructionForPatchSkip(const BYTE *address, Instructio case 0x4e: case 0x4f: W = true; - done = true; break; default: From b7dae68d25bfe1f556bc8d662d23944757c7a844 Mon Sep 17 00:00:00 2001 From: vseanreesermsft <78103370+vseanreesermsft@users.noreply.github.com> Date: Tue, 9 Jan 2024 14:52:52 -0800 Subject: [PATCH 548/783] Update branding to 8.0.2 (#96422) --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index da037c2c7ca922..5a585bda332e83 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,11 +1,11 @@ - 8.0.1 + 8.0.2 8 0 - 1 + 2 8.0.100 7.0.$([MSBuild]::Add($(PatchVersion),14)) 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) From ae7fac5cb4ab7c080a9a87a74c42e9b6b38c43c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Tue, 9 Jan 2024 14:53:35 -0800 Subject: [PATCH 549/783] [release/8.0] Reset OOB packages from the December Release in the January Release (#96704) * Microsoft.Bcl.TimeProvider.csproj * Microsoft.Extensions.Configuration.Binder * Microsoft.Extensions.Options --- .../src/Microsoft.Bcl.TimeProvider.csproj | 2 +- .../src/Microsoft.Extensions.Configuration.Binder.csproj | 2 +- .../src/Microsoft.Extensions.Options.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/Microsoft.Bcl.TimeProvider/src/Microsoft.Bcl.TimeProvider.csproj b/src/libraries/Microsoft.Bcl.TimeProvider/src/Microsoft.Bcl.TimeProvider.csproj index fbc46e4552c673..3bb23525dc4916 100644 --- a/src/libraries/Microsoft.Bcl.TimeProvider/src/Microsoft.Bcl.TimeProvider.csproj +++ b/src/libraries/Microsoft.Bcl.TimeProvider/src/Microsoft.Bcl.TimeProvider.csproj @@ -14,7 +14,7 @@ System.TimeProvider System.ITimer false - true + false 1 diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj index 59f155270c6633..4d20115e2f710d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj @@ -4,7 +4,7 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true true - true + false 1 Provides the functionality to bind an object to data in configuration providers for Microsoft.Extensions.Configuration. This package enables you to represent the configuration data as strongly-typed classes defined in the application code. To bind a configuration, use the Microsoft.Extensions.Configuration.ConfigurationBinder.Get extension method on the IConfiguration object. To use this package, you also need to install a package for the configuration provider, for example, Microsoft.Extensions.Configuration.Json for the JSON provider. diff --git a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj index abbc5d2329c5c1..de066111eb5797 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj +++ b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj @@ -4,7 +4,7 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.1;netstandard2.0;$(NetFrameworkMinimum) true true - true + false 1 Provides a strongly typed way of specifying and accessing settings using dependency injection. From 981db45600b6308af2980d74cf8c48310e26e320 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:03:02 -0800 Subject: [PATCH 550/783] Use NuGetAuthenticate@1 instead of @0 (#96666) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a build warning about the old version now. eng/common usages are handled by https://github.com/dotnet/arcade/pull/14314 Co-authored-by: Alexander Köplinger --- eng/pipelines/common/restore-internal-tools.yml | 2 +- eng/pipelines/installer/jobs/steps/build-linux-package.yml | 2 +- eng/pipelines/official/jobs/prepare-signed-artifacts.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/pipelines/common/restore-internal-tools.yml b/eng/pipelines/common/restore-internal-tools.yml index eead4b67c30f64..fdec41da53da55 100644 --- a/eng/pipelines/common/restore-internal-tools.yml +++ b/eng/pipelines/common/restore-internal-tools.yml @@ -1,5 +1,5 @@ steps: - - task: NuGetAuthenticate@0 + - task: NuGetAuthenticate@1 inputs: nuGetServiceConnections: 'devdiv/dotnet-core-internal-tooling' forceReinstallCredentialProvider: true diff --git a/eng/pipelines/installer/jobs/steps/build-linux-package.yml b/eng/pipelines/installer/jobs/steps/build-linux-package.yml index 645b3edefa7ef5..a5645af3d9ccd3 100644 --- a/eng/pipelines/installer/jobs/steps/build-linux-package.yml +++ b/eng/pipelines/installer/jobs/steps/build-linux-package.yml @@ -8,7 +8,7 @@ parameters: steps: ## Run NuGet Authentication for each of the side containers - ${{ if ne(variables['System.TeamProject'], 'public') }}: - - task: NuGetAuthenticate@0 + - task: NuGetAuthenticate@1 target: ${{ parameters.target }} - script: | $(Build.SourcesDirectory)/build.sh \ diff --git a/eng/pipelines/official/jobs/prepare-signed-artifacts.yml b/eng/pipelines/official/jobs/prepare-signed-artifacts.yml index c6d1624603fe1c..908f2b64c71c22 100644 --- a/eng/pipelines/official/jobs/prepare-signed-artifacts.yml +++ b/eng/pipelines/official/jobs/prepare-signed-artifacts.yml @@ -26,7 +26,7 @@ jobs: fetchDepth: 20 - ${{ if eq(parameters.isOfficialBuild, true) }}: - - task: NuGetAuthenticate@0 + - task: NuGetAuthenticate@1 - task: MicroBuildSigningPlugin@2 displayName: Install MicroBuild plugin for Signing From ed220f0ea5948309ceec76da9987c4a670c8794c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:03:20 -0800 Subject: [PATCH 551/783] [release/8.0-staging] Update dependencies from dotnet/source-build-externals (#96551) * Update dependencies from https://github.com/dotnet/source-build-externals build 20240104.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.23570.1 -> To Version 8.0.0-alpha.1.24054.1 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240104.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.23570.1 -> To Version 8.0.0-alpha.1.24054.1 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240104.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.23570.1 -> To Version 8.0.0-alpha.1.24054.1 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240104.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.23570.1 -> To Version 8.0.0-alpha.1.24054.1 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ffd224e565faf1..0e4791863556a3 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -104,9 +104,9 @@ 95f83e27806330fec09edd96e06bba3acabe3f35 - + https://github.com/dotnet/source-build-externals - e844aa02a05b90d8cbe499676ec6ee0f19ec4980 + 6c9557fbf18398d6f226bfd16ce3876f1fe2e940 From 1fdffe33d2cfbf54023ab68ae440bf60f3ba1c79 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:11:48 -0800 Subject: [PATCH 552/783] Update dependencies from https://github.com/dotnet/arcade build 20231220.2 (#96674) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23564.4 -> To Version 8.0.0-beta.23620.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 72 +++++++++---------- eng/Versions.props | 30 ++++---- eng/common/darc-init.ps1 | 2 +- eng/common/darc-init.sh | 2 +- .../post-build/add-build-to-channel.ps1 | 2 +- eng/common/post-build/publish-using-darc.ps1 | 2 +- .../post-build/trigger-subscriptions.ps1 | 2 +- eng/common/templates/job/job.yml | 2 +- .../templates/job/publish-build-assets.yml | 4 +- .../templates/post-build/common-variables.yml | 2 +- .../templates/post-build/post-build.yml | 4 +- global.json | 6 +- 12 files changed, 65 insertions(+), 65 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0e4791863556a3..c038e900cddf04 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -111,9 +111,9 @@ - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc @@ -121,69 +121,69 @@ 73f0850939d96131c28cf6ea6ee5aacb4da0083a - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc https://github.com/dotnet/runtime-assets @@ -334,9 +334,9 @@ https://github.com/dotnet/xharness 480b9159eb7e69b182a87581d5a336e97e0b6dae - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 84129325171e65373edef24019e1171feeb19cbc https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index 77645744dfd548..4c0dd26a4c5f67 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -87,21 +87,21 @@ 8.0.100 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 2.5.1-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 + 8.0.0-beta.23620.2 + 8.0.0-beta.23620.2 + 8.0.0-beta.23620.2 + 8.0.0-beta.23620.2 + 8.0.0-beta.23620.2 + 2.5.1-beta.23620.2 + 8.0.0-beta.23620.2 + 8.0.0-beta.23620.2 + 8.0.0-beta.23620.2 + 8.0.0-beta.23620.2 + 8.0.0-beta.23620.2 + 8.0.0-beta.23620.2 + 8.0.0-beta.23620.2 + 8.0.0-beta.23620.2 + 8.0.0-beta.23620.2 6.0.0-preview.1.102 diff --git a/eng/common/darc-init.ps1 b/eng/common/darc-init.ps1 index 435e7641341b16..8fda30bdce2b09 100644 --- a/eng/common/darc-init.ps1 +++ b/eng/common/darc-init.ps1 @@ -1,6 +1,6 @@ param ( $darcVersion = $null, - $versionEndpoint = 'https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16', + $versionEndpoint = 'https://maestro.dot.net/api/assets/darc-version?api-version=2019-01-16', $verbosity = 'minimal', $toolpath = $null ) diff --git a/eng/common/darc-init.sh b/eng/common/darc-init.sh index 84c1d0cc2e75ac..c305ae6bd771ef 100755 --- a/eng/common/darc-init.sh +++ b/eng/common/darc-init.sh @@ -2,7 +2,7 @@ source="${BASH_SOURCE[0]}" darcVersion='' -versionEndpoint='https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16' +versionEndpoint='https://maestro.dot.net/api/assets/darc-version?api-version=2019-01-16' verbosity='minimal' while [[ $# > 0 ]]; do diff --git a/eng/common/post-build/add-build-to-channel.ps1 b/eng/common/post-build/add-build-to-channel.ps1 index de2d957922a653..49938f0c89f768 100644 --- a/eng/common/post-build/add-build-to-channel.ps1 +++ b/eng/common/post-build/add-build-to-channel.ps1 @@ -2,7 +2,7 @@ param( [Parameter(Mandatory=$true)][int] $BuildId, [Parameter(Mandatory=$true)][int] $ChannelId, [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, - [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com', + [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net', [Parameter(Mandatory=$false)][string] $MaestroApiVersion = '2019-01-16' ) diff --git a/eng/common/post-build/publish-using-darc.ps1 b/eng/common/post-build/publish-using-darc.ps1 index 8508397d77640e..1e779fec4dd1ea 100644 --- a/eng/common/post-build/publish-using-darc.ps1 +++ b/eng/common/post-build/publish-using-darc.ps1 @@ -3,7 +3,7 @@ param( [Parameter(Mandatory=$true)][int] $PublishingInfraVersion, [Parameter(Mandatory=$true)][string] $AzdoToken, [Parameter(Mandatory=$true)][string] $MaestroToken, - [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com', + [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net', [Parameter(Mandatory=$true)][string] $WaitPublishingFinish, [Parameter(Mandatory=$false)][string] $ArtifactsPublishingAdditionalParameters, [Parameter(Mandatory=$false)][string] $SymbolPublishingAdditionalParameters diff --git a/eng/common/post-build/trigger-subscriptions.ps1 b/eng/common/post-build/trigger-subscriptions.ps1 index 55dea518ac5850..ac9a95778fcd9e 100644 --- a/eng/common/post-build/trigger-subscriptions.ps1 +++ b/eng/common/post-build/trigger-subscriptions.ps1 @@ -2,7 +2,7 @@ param( [Parameter(Mandatory=$true)][string] $SourceRepo, [Parameter(Mandatory=$true)][int] $ChannelId, [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, - [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com', + [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net', [Parameter(Mandatory=$false)][string] $MaestroApiVersion = '2019-01-16' ) diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index e20ee3a983cb05..e24ca2f46f98f9 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -136,7 +136,7 @@ jobs: condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}: - - task: NuGetAuthenticate@0 + - task: NuGetAuthenticate@1 - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}: - task: DownloadPipelineArtifact@2 diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml index 42017109f374d6..fa5446c093dd11 100644 --- a/eng/common/templates/job/publish-build-assets.yml +++ b/eng/common/templates/job/publish-build-assets.yml @@ -72,7 +72,7 @@ jobs: condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} - - task: NuGetAuthenticate@0 + - task: NuGetAuthenticate@1 - task: PowerShell@2 displayName: Publish Build Assets @@ -81,7 +81,7 @@ jobs: arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' /p:BuildAssetRegistryToken=$(MaestroAccessToken) - /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com + /p:MaestroApiEndpoint=https://maestro.dot.net /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} /p:OfficialBuildId=$(Build.BuildNumber) condition: ${{ parameters.condition }} diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml index c24193acfc981f..173914f2364a70 100644 --- a/eng/common/templates/post-build/common-variables.yml +++ b/eng/common/templates/post-build/common-variables.yml @@ -7,7 +7,7 @@ variables: # Default Maestro++ API Endpoint and API Version - name: MaestroApiEndPoint - value: "https://maestro-prod.westus2.cloudapp.azure.com" + value: "https://maestro.dot.net" - name: MaestroApiAccessToken value: $(MaestroAccessToken) - name: MaestroApiVersion diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index ef720f9d781989..3f74abf7ce0f8a 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -169,7 +169,7 @@ stages: # This is necessary whenever we want to publish/restore to an AzDO private feed # Since sdk-task.ps1 tries to restore packages we need to do this authentication here # otherwise it'll complain about accessing a private feed. - - task: NuGetAuthenticate@0 + - task: NuGetAuthenticate@1 displayName: 'Authenticate to AzDO Feeds' # Signing validation will optionally work with the buildmanifest file which is downloaded from @@ -266,7 +266,7 @@ stages: BARBuildId: ${{ parameters.BARBuildId }} PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - task: NuGetAuthenticate@0 + - task: NuGetAuthenticate@1 - task: PowerShell@2 displayName: Publish Using Darc diff --git a/global.json b/global.json index 517059ae7a3859..4822dcaddf37ee 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.100" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23564.4", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23564.4", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23564.4", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23620.2", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23620.2", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23620.2", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From 8cd309a73bf26b45d8b79de43cc78f4e75987642 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:12:07 -0800 Subject: [PATCH 553/783] Update dependencies from https://github.com/dotnet/emsdk build 20240104.3 (#96491) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.1-servicing.23609.2 -> To Version 8.0.2-servicing.24054.3 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/NuGet.config b/NuGet.config index 0a9c52079be067..71536152cf8cb7 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c038e900cddf04..6422d175c123b0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,13 +90,13 @@ 45dd3a73dd5b64b010c4251303b3664bb30df029 - + https://github.com/dotnet/emsdk - 9be4a716fd007be9be89d6acea302bd15bfb165d + b52fa06c6cca7355d2ec0fccc8f5c2a48ea10cf6 - + https://github.com/dotnet/emsdk - 9be4a716fd007be9be89d6acea302bd15bfb165d + b52fa06c6cca7355d2ec0fccc8f5c2a48ea10cf6 diff --git a/eng/Versions.props b/eng/Versions.props index 4c0dd26a4c5f67..623f222f87522d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.1 + 8.0.2 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda From 82fd4c6418e1a0d0fb7e2bec332cde1ca40abd14 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 17:52:46 -0800 Subject: [PATCH 554/783] [android] Bump to win 11 helix queue (#96634) Co-authored-by: Steve Pfister --- eng/pipelines/coreclr/templates/helix-queues-setup.yml | 2 +- eng/pipelines/libraries/helix-queues-setup.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml index e264588ee78c91..8e5ddd36759581 100644 --- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml +++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml @@ -44,7 +44,7 @@ jobs: # Android arm64 - ${{ if in(parameters.platform, 'android_arm64') }}: - - Windows.10.Amd64.Android.Open + - Windows.11.Amd64.Android.Open # Android x64 - ${{ if in(parameters.platform, 'android_x64') }}: diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 987d7f99c41f4a..dd80cdc85095ad 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -101,7 +101,7 @@ jobs: - ${{ if in(parameters.platform, 'android_x86', 'android_x64', 'linux_bionic_x64') }}: - Ubuntu.1804.Amd64.Android.29.Open - ${{ if in(parameters.platform, 'android_arm', 'android_arm64', 'linux_bionic_arm64') }}: - - Windows.10.Amd64.Android.Open + - Windows.11.Amd64.Android.Open # iOS Simulator/Mac Catalyst arm64 - ${{ if in(parameters.platform, 'maccatalyst_arm64', 'iossimulator_arm64') }}: From 209fb535d17bb56bcf0d4865f21dd49f6fc9b509 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 10:46:54 -0800 Subject: [PATCH 555/783] Update dependencies from https://github.com/dotnet/hotreload-utils build 20240110.1 (#96761) Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.23618.2 -> To Version 8.0.0-alpha.0.24060.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6422d175c123b0..c94e70882b6a01 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -354,9 +354,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 67613417f5e1af250e6ddfba79f8f2885d8e90fb - + https://github.com/dotnet/hotreload-utils - 4fb0eb65850bcfed5b6bdb171b447f9da2945a11 + 3b7da338c73b31b943c5512dcf0e2f6dd75f601c https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index 3707eb72716cc2..52f7fff12c6f5f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -186,7 +186,7 @@ 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 8.0.0-prerelease.23407.2 - 8.0.0-alpha.0.23618.2 + 8.0.0-alpha.0.24060.1 2.4.2 1.0.0 2.4.5 From 11ed2e2e8a09b431693e87b74ac71d7d93d1d391 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 10:47:15 -0800 Subject: [PATCH 556/783] Update dependencies from https://github.com/dotnet/source-build-externals build 20240109.4 (#96765) Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24054.1 -> To Version 8.0.0-alpha.1.24059.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c94e70882b6a01..0bf967dcfd12a0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -104,9 +104,9 @@ 95f83e27806330fec09edd96e06bba3acabe3f35 - + https://github.com/dotnet/source-build-externals - 6c9557fbf18398d6f226bfd16ce3876f1fe2e940 + 7134e53b6b1210a1ce8838b12b8f6071e0a3433b From 145399b686fc972828c009ce3e40a07fffa1c491 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 10:51:32 -0800 Subject: [PATCH 557/783] Update dependencies from https://github.com/dotnet/runtime-assets build 20240110.2 (#96767) Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.23607.1 -> To Version 8.0.0-beta.24060.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 56 ++++++++++++++++++++--------------------- eng/Versions.props | 28 ++++++++++----------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0bf967dcfd12a0..e5910481a61cce 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -185,57 +185,57 @@ https://github.com/dotnet/arcade 84129325171e65373edef24019e1171feeb19cbc - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b https://github.com/dotnet/llvm-project @@ -358,9 +358,9 @@ https://github.com/dotnet/hotreload-utils 3b7da338c73b31b943c5512dcf0e2f6dd75f601c - + https://github.com/dotnet/runtime-assets - dfd16e832e63dd036e42ad2f0acc4a4cbdb825fa + 3b165c269b12cc194f48fde6a1a7694bece8931b https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index 52f7fff12c6f5f..6a1569445e01fb 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -143,20 +143,20 @@ 4.5.0 8.0.0-rc.1.23406.6 - 8.0.0-beta.23607.1 - 8.0.0-beta.23607.1 - 8.0.0-beta.23607.1 - 8.0.0-beta.23607.1 - 8.0.0-beta.23607.1 - 8.0.0-beta.23607.1 - 8.0.0-beta.23607.1 - 8.0.0-beta.23607.1 - 8.0.0-beta.23607.1 - 8.0.0-beta.23607.1 - 8.0.0-beta.23607.1 - 8.0.0-beta.23607.1 - 8.0.0-beta.23607.1 - 8.0.0-beta.23607.1 + 8.0.0-beta.24060.2 + 8.0.0-beta.24060.2 + 8.0.0-beta.24060.2 + 8.0.0-beta.24060.2 + 8.0.0-beta.24060.2 + 8.0.0-beta.24060.2 + 8.0.0-beta.24060.2 + 8.0.0-beta.24060.2 + 8.0.0-beta.24060.2 + 8.0.0-beta.24060.2 + 8.0.0-beta.24060.2 + 8.0.0-beta.24060.2 + 8.0.0-beta.24060.2 + 8.0.0-beta.24060.2 1.0.0-prerelease.23566.3 1.0.0-prerelease.23566.3 From 0ef7d15807cea3812f7a7e74ba81bba96329ab17 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:24:19 -0800 Subject: [PATCH 558/783] Update dependencies from https://github.com/dotnet/emsdk build 20240110.3 (#96768) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.2-servicing.24054.3 -> To Version 8.0.2-servicing.24060.3 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 71536152cf8cb7..a574dbc251ad5e 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e5910481a61cce..31c3d3745ce80a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - b52fa06c6cca7355d2ec0fccc8f5c2a48ea10cf6 + 3e200af819951858669fe9616334259e000de22a - + https://github.com/dotnet/emsdk - b52fa06c6cca7355d2ec0fccc8f5c2a48ea10cf6 + 3e200af819951858669fe9616334259e000de22a From e2c178e4cef2ea887773e3796686700644a73a42 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:27:42 +0000 Subject: [PATCH 559/783] [release/8.0-staging] Fix fast-path support for ignoring nullable value types (#96669) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix fast-path support for ignoring nullable value types * Bump System.Text.Json servicing version to 2. --------- Co-authored-by: Eirik Tsarpalis Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- .../Common/src/SourceGenerators/TypeRef.cs | 2 +- .../src/System.Text.Json.csproj | 2 +- .../tests/Common/PropertyVisibilityTests.cs | 77 +++---------------- .../Serialization/PropertyVisibilityTests.cs | 37 +++++++++ 4 files changed, 49 insertions(+), 69 deletions(-) diff --git a/src/libraries/Common/src/SourceGenerators/TypeRef.cs b/src/libraries/Common/src/SourceGenerators/TypeRef.cs index cfbf33ed741366..a4d556ef786dbe 100644 --- a/src/libraries/Common/src/SourceGenerators/TypeRef.cs +++ b/src/libraries/Common/src/SourceGenerators/TypeRef.cs @@ -19,7 +19,7 @@ public TypeRef(ITypeSymbol type) FullyQualifiedName = type.GetFullyQualifiedName(); IsValueType = type.IsValueType; TypeKind = type.TypeKind; - SpecialType = type.SpecialType; + SpecialType = type.OriginalDefinition.SpecialType; } public string Name { get; } diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index 3e867457e45ba6..29409f7f886293 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -9,7 +9,7 @@ true true true - 1 + 2 Provides high-performance and low-allocating types that serialize objects to JavaScript Object Notation (JSON) text and deserialize JSON text to objects, with UTF-8 support built-in. Also provides types to read and write JSON text encoded as UTF-8, and to create an in-memory document object model (DOM), that is read-only, for random access of the JSON elements within a structured view of the data. The System.Text.Json library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks. diff --git a/src/libraries/System.Text.Json/tests/Common/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Common/PropertyVisibilityTests.cs index 79a6ce599ad83c..44c702025f5d1e 100644 --- a/src/libraries/System.Text.Json/tests/Common/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Common/PropertyVisibilityTests.cs @@ -1322,10 +1322,6 @@ public async Task JsonIgnoreAttribute() } [Fact] -#if BUILDING_SOURCE_GENERATOR_TESTS - // Needs support for more collections. - [ActiveIssue("https://github.com/dotnet/runtime/issues/53393")] -#endif public async Task JsonIgnoreAttribute_UnsupportedCollection() { string json = @@ -1771,10 +1767,6 @@ public async Task OverrideJsonIgnorePropertyUsingJsonPropertyNameReversed() [Theory] [InlineData(typeof(ClassWithProperty_IgnoreConditionAlways))] [InlineData(typeof(ClassWithProperty_IgnoreConditionAlways_Ctor))] -#if BUILDING_SOURCE_GENERATOR_TESTS - // Need support for parameterized ctors. - [ActiveIssue("https://github.com/dotnet/runtime/issues/45448")] -#endif public async Task JsonIgnoreConditionSetToAlwaysWorks(Type type) { string json = @"{""MyString"":""Random"",""MyDateTime"":""2020-03-23"",""MyInt"":4}"; @@ -1798,7 +1790,7 @@ public class ClassWithProperty_IgnoreConditionAlways public int MyInt { get; set; } } - private class ClassWithProperty_IgnoreConditionAlways_Ctor + public class ClassWithProperty_IgnoreConditionAlways_Ctor { public string MyString { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Always)] @@ -1814,10 +1806,6 @@ public ClassWithProperty_IgnoreConditionAlways_Ctor(DateTime myDateTime, int myI [Theory] [MemberData(nameof(JsonIgnoreConditionWhenWritingDefault_ClassProperty_TestData))] -#if BUILDING_SOURCE_GENERATOR_TESTS - // Need support for parameterized ctors. - [ActiveIssue("https://github.com/dotnet/runtime/issues/45448")] -#endif public async Task JsonIgnoreConditionWhenWritingDefault_ClassProperty(Type type, JsonSerializerOptions options) { // Property shouldn't be ignored if it isn't null. @@ -1868,7 +1856,7 @@ public class ClassWithClassProperty_IgnoreConditionWhenWritingDefault public int Int2 { get; set; } } - private class ClassWithClassProperty_IgnoreConditionWhenWritingDefault_Ctor + public class ClassWithClassProperty_IgnoreConditionWhenWritingDefault_Ctor { public int Int1 { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] @@ -1892,10 +1880,6 @@ public static IEnumerable JsonIgnoreConditionWhenWritingDefault_ClassP [Theory] [MemberData(nameof(JsonIgnoreConditionWhenWritingDefault_StructProperty_TestData))] -#if BUILDING_SOURCE_GENERATOR_TESTS - // Need support for parameterized ctors. - [ActiveIssue("https://github.com/dotnet/runtime/issues/45448")] -#endif public async Task JsonIgnoreConditionWhenWritingDefault_StructProperty(Type type, JsonSerializerOptions options) { // Property shouldn't be ignored if it isn't null. @@ -1924,7 +1908,7 @@ public class ClassWithStructProperty_IgnoreConditionWhenWritingDefault public int Int2 { get; set; } } - private struct StructWithStructProperty_IgnoreConditionWhenWritingDefault_Ctor + public struct StructWithStructProperty_IgnoreConditionWhenWritingDefault_Ctor { public int Int1 { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] @@ -1948,10 +1932,6 @@ public static IEnumerable JsonIgnoreConditionWhenWritingDefault_Struct [Theory] [MemberData(nameof(JsonIgnoreConditionNever_TestData))] -#if BUILDING_SOURCE_GENERATOR_TESTS - // Need support for parameterized ctors. - [ActiveIssue("https://github.com/dotnet/runtime/issues/45448")] -#endif public async Task JsonIgnoreConditionNever(Type type) { // Property should always be (de)serialized, even when null. @@ -1983,10 +1963,6 @@ public async Task JsonIgnoreConditionNever(Type type) [Theory] [MemberData(nameof(JsonIgnoreConditionNever_TestData))] -#if BUILDING_SOURCE_GENERATOR_TESTS - // Need support for parameterized ctors. - [ActiveIssue("https://github.com/dotnet/runtime/issues/45448")] -#endif public async Task JsonIgnoreConditionNever_IgnoreNullValues_True(Type type) { // Property should always be (de)serialized. @@ -2060,9 +2036,6 @@ public async Task JsonIgnoreCondition_LastOneWins() } [Fact] -#if BUILDING_SOURCE_GENERATOR_TESTS - [ActiveIssue("https://github.com/dotnet/runtime/issues/53393")] -#endif public async Task ClassWithComplexObjectsUsingIgnoreWhenWritingDefaultAttribute() { string json = @"{""Class"":{""MyInt16"":18}, ""Dictionary"":null}"; @@ -2091,9 +2064,6 @@ public class ClassUsingIgnoreWhenWritingDefaultAttribute } [Fact] -#if BUILDING_SOURCE_GENERATOR_TESTS - [ActiveIssue("https://github.com/dotnet/runtime/issues/53393")] -#endif public async Task ClassWithComplexObjectUsingIgnoreNeverAttribute() { string json = @"{""Class"":null, ""Dictionary"":null}"; @@ -2375,10 +2345,6 @@ public async Task ValueType_Properties_NotIgnoredWhen_IgnoreNullValues_Active_Cl } [Fact] -#if BUILDING_SOURCE_GENERATOR_TESTS - // Need support for parameterized ctors. - [ActiveIssue("https://github.com/dotnet/runtime/issues/45448")] -#endif public async Task ValueType_Properties_NotIgnoredWhen_IgnoreNullValues_Active_LargeStructTest() { var options = new JsonSerializerOptions { IgnoreNullValues = true }; @@ -2412,10 +2378,6 @@ public async Task ValueType_Properties_NotIgnoredWhen_IgnoreNullValues_Active_La } [Fact] -#if BUILDING_SOURCE_GENERATOR_TESTS - // Need support for parameterized ctors. - [ActiveIssue("https://github.com/dotnet/runtime/issues/45448")] -#endif public async Task ValueType_Properties_NotIgnoredWhen_IgnoreNullValues_Active_SmallStructTest() { var options = new JsonSerializerOptions { IgnoreNullValues = true }; @@ -2478,7 +2440,7 @@ public LargeStructWithValueAndReferenceTypes( } } - private struct SmallStructWithValueAndReferenceTypes + public struct SmallStructWithValueAndReferenceTypes { public string MyString { get; } public int MyInt { get; set; } @@ -2502,10 +2464,6 @@ public SmallStructWithValueAndReferenceTypes( public class PointClass { } [Fact] -#if BUILDING_SOURCE_GENERATOR_TESTS - // Need support for parameterized ctors. - [ActiveIssue("https://github.com/dotnet/runtime/issues/45448")] -#endif public async Task Ignore_WhenWritingNull_Globally() { var options = new JsonSerializerOptions @@ -2579,17 +2537,8 @@ public class ClassWithThingsToIgnore } [Fact] -#if BUILDING_SOURCE_GENERATOR_TESTS - // Need support for parameterized ctors. - [ActiveIssue("https://github.com/dotnet/runtime/issues/45448")] -#endif public async Task Ignore_WhenWritingNull_PerProperty() { - var options = new JsonSerializerOptions - { - IncludeFields = true - }; - string json = @"{ ""MyPointClass2_IgnoredWhenWritingNull"":{}, ""MyString1_IgnoredWhenWritingNull"":""Default"", @@ -2604,7 +2553,7 @@ public async Task Ignore_WhenWritingNull_PerProperty() }"; // All members should correspond to JSON contents, as ignore doesn't apply to deserialization. - ClassWithThingsToIgnore_PerProperty obj = await Serializer.DeserializeWrapper(json, options); + ClassWithThingsToIgnore_PerProperty obj = await Serializer.DeserializeWrapper(json); Assert.NotNull(obj.MyPointClass2_IgnoredWhenWritingNull); Assert.Equal("Default", obj.MyString1_IgnoredWhenWritingNull); Assert.Null(obj.MyNullableBool1_IgnoredWhenWritingNull); @@ -2628,7 +2577,7 @@ public async Task Ignore_WhenWritingNull_PerProperty() ""MyNullableBool2_IgnoredWhenWritingNull"":true, ""MyPointStruct1"":{""X"":0,""Y"":0} }"; - JsonTestHelper.AssertJsonEqual(expectedJson, await Serializer.SerializeWrapper(obj, options)); + JsonTestHelper.AssertJsonEqual(expectedJson, await Serializer.SerializeWrapper(obj)); } public class ClassWithThingsToIgnore_PerProperty @@ -2639,6 +2588,7 @@ public class ClassWithThingsToIgnore_PerProperty [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string MyString2_IgnoredWhenWritingNull; + [JsonInclude] public int MyInt1; public int MyInt2 { get; set; } @@ -2646,15 +2596,16 @@ public class ClassWithThingsToIgnore_PerProperty [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public bool? MyNullableBool1_IgnoredWhenWritingNull { get; set; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonInclude, JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public bool? MyNullableBool2_IgnoredWhenWritingNull; - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonInclude, JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public PointClass MyPointClass1_IgnoredWhenWritingNull; [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public PointClass MyPointClass2_IgnoredWhenWritingNull { get; set; } + [JsonInclude] public Point_2D_Struct_WithAttribute MyPointStruct1; public Point_2D_Struct_WithAttribute MyPointStruct2 { get; set; } @@ -2748,10 +2699,6 @@ public MyClassWithValueType() { } } [Fact] -#if BUILDING_SOURCE_GENERATOR_TESTS - // Needs bug fixes to custom converter handling. - [ActiveIssue("https://github.com/dotnet/runtime/issues/45448")] -#endif public async Task JsonIgnoreCondition_WhenWritingDefault_OnValueTypeWithCustomConverter() { var obj = new MyClassWithValueType(); @@ -2799,10 +2746,6 @@ public async Task JsonIgnoreCondition_ConverterCalledOnDeserialize() } [Fact] -#if BUILDING_SOURCE_GENERATOR_TESTS - // Needs bug fixes to custom converter handling. - [ActiveIssue("https://github.com/dotnet/runtime/issues/45448")] -#endif public async Task JsonIgnoreCondition_WhenWritingNull_OnValueTypeWithCustomConverter() { string json; diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyVisibilityTests.cs index e614b9d938ed8c..89635a6b64b5f0 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyVisibilityTests.cs @@ -334,6 +334,14 @@ public override async Task ClassWithIgnoredAndPrivateMembers_DoesNotIncludeIgnor [JsonSerializable(typeof(DictionaryWithPrivateKeyAndValueType))][JsonSerializable(typeof(ClassWithIgnoredAndPrivateMembers))] [JsonSerializable(typeof(ClassWithInternalJsonIncludeProperties))] [JsonSerializable(typeof(ClassWithIgnoredAndPrivateMembers))] + [JsonSerializable(typeof(ClassUsingIgnoreWhenWritingDefaultAttribute))] + [JsonSerializable(typeof(ClassUsingIgnoreNeverAttribute))] + [JsonSerializable(typeof(ClassWithIgnoredUnsupportedDictionary))] + [JsonSerializable(typeof(ClassWithProperty_IgnoreConditionAlways_Ctor))] + [JsonSerializable(typeof(ClassWithClassProperty_IgnoreConditionWhenWritingDefault_Ctor))] + [JsonSerializable(typeof(StructWithStructProperty_IgnoreConditionWhenWritingDefault_Ctor))] + [JsonSerializable(typeof(SmallStructWithValueAndReferenceTypes))] + [JsonSerializable(typeof(WrapperForClassWithIgnoredUnsupportedDictionary))] [JsonSerializable(typeof(Class1))] [JsonSerializable(typeof(Class2))] [JsonSerializable(typeof(NamespaceBase.Class1), TypeInfoPropertyName = "Class1FromNamespaceBase")] @@ -427,6 +435,27 @@ public void PublicContextAndJsonSerializerOptions() Assert.Equal(obj.MaxDepth, deserialized.MaxDepth); } + [Fact] + public void PocoWithNullableProperties_IgnoresNullValuesWithGlobalSetting() + { + // Regression test for https://github.com/dotnet/runtime/issues/96404 + var value = new PocoWithNullableProperties(); + string json = JsonSerializer.Serialize(value, DefaultContextWithGlobalIgnoreSetting.Default.PocoWithNullableProperties); + Assert.Equal("{}", json); + } + + class PocoWithNullableProperties + { + public string? NullableRefType { get; set; } + public int? NullableValueType { get; set; } + } + + [JsonSourceGenerationOptions( + GenerationMode = JsonSourceGenerationMode.Default, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] + [JsonSerializable(typeof(PocoWithNullableProperties))] + partial class DefaultContextWithGlobalIgnoreSetting : JsonSerializerContext; + [JsonSerializable(typeof(ClassWithNewSlotField))] [JsonSerializable(typeof(int))] [JsonSerializable(typeof(object))] @@ -578,6 +607,14 @@ public void PublicContextAndJsonSerializerOptions() [JsonSerializable(typeof(DictionaryWithPrivateKeyAndValueType))] [JsonSerializable(typeof(ClassWithInternalJsonIncludeProperties))] [JsonSerializable(typeof(ClassWithIgnoredAndPrivateMembers))] + [JsonSerializable(typeof(ClassUsingIgnoreWhenWritingDefaultAttribute))] + [JsonSerializable(typeof(ClassUsingIgnoreNeverAttribute))] + [JsonSerializable(typeof(ClassWithIgnoredUnsupportedDictionary))] + [JsonSerializable(typeof(ClassWithProperty_IgnoreConditionAlways_Ctor))] + [JsonSerializable(typeof(ClassWithClassProperty_IgnoreConditionWhenWritingDefault_Ctor))] + [JsonSerializable(typeof(StructWithStructProperty_IgnoreConditionWhenWritingDefault_Ctor))] + [JsonSerializable(typeof(SmallStructWithValueAndReferenceTypes))] + [JsonSerializable(typeof(WrapperForClassWithIgnoredUnsupportedDictionary))] [JsonSerializable(typeof(Class1))] [JsonSerializable(typeof(Class2))] [JsonSerializable(typeof(NamespaceBase.Class1), TypeInfoPropertyName = "Class1FromNamespaceBase")] From 508b876542e31e87c2f0bbfdd6c4687697a9934b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 19:53:46 -0800 Subject: [PATCH 560/783] Update dependencies from https://github.com/dotnet/xharness build 20240110.1 (#96775) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Microsoft.DotNet.XHarness.CLI , Microsoft.DotNet.XHarness.TestRunners.Common , Microsoft.DotNet.XHarness.TestRunners.Xunit From Version 8.0.0-prerelease.23407.2 -> To Version 8.0.0-prerelease.24060.1 Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index bd60f2e67ceacc..72af997c0c2543 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "8.0.0-prerelease.23407.2", + "version": "8.0.0-prerelease.24060.1", "commands": [ "xharness" ] diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 31c3d3745ce80a..d1370af8325e4c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -322,17 +322,17 @@ https://github.com/dotnet/runtime edbd5c769a19798b6955050baccf99e6797d3208 - + https://github.com/dotnet/xharness - 480b9159eb7e69b182a87581d5a336e97e0b6dae + a417169d3ba558fd6daa522f04e686574bbce520 - + https://github.com/dotnet/xharness - 480b9159eb7e69b182a87581d5a336e97e0b6dae + a417169d3ba558fd6daa522f04e686574bbce520 - + https://github.com/dotnet/xharness - 480b9159eb7e69b182a87581d5a336e97e0b6dae + a417169d3ba558fd6daa522f04e686574bbce520 https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index 6a1569445e01fb..e34b67d6ba99fc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -183,9 +183,9 @@ 1.1.0 17.4.0-preview-20220707-01 - 8.0.0-prerelease.23407.2 - 8.0.0-prerelease.23407.2 - 8.0.0-prerelease.23407.2 + 8.0.0-prerelease.24060.1 + 8.0.0-prerelease.24060.1 + 8.0.0-prerelease.24060.1 8.0.0-alpha.0.24060.1 2.4.2 1.0.0 From 2c6886b606207a808cdca6c0fc180082b7ad6e88 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 11:01:32 -0800 Subject: [PATCH 561/783] [release/8.0-staging] Update dependencies from dotnet/arcade (#96777) * Update dependencies from https://github.com/dotnet/arcade build 20240109.4 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23620.2 -> To Version 8.0.0-beta.24059.4 * workloads: Update sdk used for testing to 8.0.101 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Ankit Jain --- eng/Version.Details.xml | 72 ++++++++++++++++++++--------------------- eng/Versions.props | 32 +++++++++--------- eng/common/tools.ps1 | 10 +++++- eng/common/tools.sh | 7 +++- global.json | 10 +++--- 5 files changed, 72 insertions(+), 59 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d1370af8325e4c..0e764146f71cca 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -111,9 +111,9 @@ - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 @@ -121,69 +121,69 @@ 73f0850939d96131c28cf6ea6ee5aacb4da0083a - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 https://github.com/dotnet/runtime-assets @@ -334,9 +334,9 @@ https://github.com/dotnet/xharness a417169d3ba558fd6daa522f04e686574bbce520 - + https://github.com/dotnet/arcade - 84129325171e65373edef24019e1171feeb19cbc + 61ae141d2bf3534619265c8f691fd55dc3e75147 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index e34b67d6ba99fc..55ce55ada067df 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -87,21 +87,21 @@ 8.0.100 - 8.0.0-beta.23620.2 - 8.0.0-beta.23620.2 - 8.0.0-beta.23620.2 - 8.0.0-beta.23620.2 - 8.0.0-beta.23620.2 - 2.5.1-beta.23620.2 - 8.0.0-beta.23620.2 - 8.0.0-beta.23620.2 - 8.0.0-beta.23620.2 - 8.0.0-beta.23620.2 - 8.0.0-beta.23620.2 - 8.0.0-beta.23620.2 - 8.0.0-beta.23620.2 - 8.0.0-beta.23620.2 - 8.0.0-beta.23620.2 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 2.5.1-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 6.0.0-preview.1.102 @@ -258,7 +258,7 @@ 3.1.7 1.0.406601 - 8.0.100 + 8.0.101 $(MicrosoftDotnetSdkInternalVersion) diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index fdd0cbb91f8596..eb188cfda415b4 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -601,7 +601,15 @@ function InitializeBuildTool() { ExitWithExitCode 1 } $dotnetPath = Join-Path $dotnetRoot (GetExecutableFileName 'dotnet') - $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = 'net8.0' } + + # Use override if it exists - commonly set by source-build + if ($null -eq $env:_OverrideArcadeInitializeBuildToolFramework) { + $initializeBuildToolFramework="net8.0" + } else { + $initializeBuildToolFramework=$env:_OverrideArcadeInitializeBuildToolFramework + } + + $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = $initializeBuildToolFramework } } elseif ($msbuildEngine -eq "vs") { try { $msbuildPath = InitializeVisualStudioMSBuild -install:$restore diff --git a/eng/common/tools.sh b/eng/common/tools.sh index e8d478943341df..3392e3a99921f7 100755 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -341,7 +341,12 @@ function InitializeBuildTool { # return values _InitializeBuildTool="$_InitializeDotNetCli/dotnet" _InitializeBuildToolCommand="msbuild" - _InitializeBuildToolFramework="net8.0" + # use override if it exists - commonly set by source-build + if [[ "${_OverrideArcadeInitializeBuildToolFramework:-x}" == "x" ]]; then + _InitializeBuildToolFramework="net8.0" + else + _InitializeBuildToolFramework="${_OverrideArcadeInitializeBuildToolFramework}" + fi } # Set RestoreNoCache as a workaround for https://github.com/NuGet/Home/issues/3116 diff --git a/global.json b/global.json index 4822dcaddf37ee..13f92203054630 100644 --- a/global.json +++ b/global.json @@ -1,16 +1,16 @@ { "sdk": { - "version": "8.0.100", + "version": "8.0.101", "allowPrerelease": true, "rollForward": "major" }, "tools": { - "dotnet": "8.0.100" + "dotnet": "8.0.101" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23620.2", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23620.2", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23620.2", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24059.4", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24059.4", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.24059.4", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From 074d301ac8c004fb53cb2bcbdc0dbbd8cd0a08de Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 11:02:29 -0800 Subject: [PATCH 562/783] [release/8.0] Update dependencies from dotnet/arcade (#96776) * Update dependencies from https://github.com/dotnet/arcade build 20240109.4 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.23564.4 -> To Version 8.0.0-beta.24059.4 * workloads: Update sdk used for testing to 8.0.101 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Ankit Jain --- NuGet.config | 5 +- eng/Version.Details.xml | 72 +++++++++---------- eng/Versions.props | 32 ++++----- eng/common/darc-init.ps1 | 2 +- eng/common/darc-init.sh | 2 +- .../post-build/add-build-to-channel.ps1 | 2 +- eng/common/post-build/publish-using-darc.ps1 | 2 +- .../post-build/trigger-subscriptions.ps1 | 2 +- eng/common/templates/job/job.yml | 2 +- .../templates/job/publish-build-assets.yml | 4 +- .../templates/post-build/common-variables.yml | 2 +- .../templates/post-build/post-build.yml | 4 +- eng/common/tools.ps1 | 10 ++- eng/common/tools.sh | 7 +- global.json | 10 +-- 15 files changed, 86 insertions(+), 72 deletions(-) diff --git a/NuGet.config b/NuGet.config index f34253e5b0e2fe..b128648435e3d9 100644 --- a/NuGet.config +++ b/NuGet.config @@ -10,8 +10,9 @@ - - + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c8a893de7d463b..acbe3a4cf0259f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -111,9 +111,9 @@ - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 @@ -121,69 +121,69 @@ 73f0850939d96131c28cf6ea6ee5aacb4da0083a - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 https://github.com/dotnet/runtime-assets @@ -334,9 +334,9 @@ https://github.com/dotnet/xharness 480b9159eb7e69b182a87581d5a336e97e0b6dae - + https://github.com/dotnet/arcade - 0aaeafef60933f87b0b50350313bb2fd77defb5d + 61ae141d2bf3534619265c8f691fd55dc3e75147 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index 5a585bda332e83..de1937187364e7 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -87,21 +87,21 @@ 8.0.100 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 2.5.1-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 - 8.0.0-beta.23564.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 2.5.1-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 + 8.0.0-beta.24059.4 6.0.0-preview.1.102 @@ -258,7 +258,7 @@ 3.1.7 1.0.406601 - 8.0.100 + 8.0.101 $(MicrosoftDotnetSdkInternalVersion) diff --git a/eng/common/darc-init.ps1 b/eng/common/darc-init.ps1 index 435e7641341b16..8fda30bdce2b09 100644 --- a/eng/common/darc-init.ps1 +++ b/eng/common/darc-init.ps1 @@ -1,6 +1,6 @@ param ( $darcVersion = $null, - $versionEndpoint = 'https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16', + $versionEndpoint = 'https://maestro.dot.net/api/assets/darc-version?api-version=2019-01-16', $verbosity = 'minimal', $toolpath = $null ) diff --git a/eng/common/darc-init.sh b/eng/common/darc-init.sh index 84c1d0cc2e75ac..c305ae6bd771ef 100755 --- a/eng/common/darc-init.sh +++ b/eng/common/darc-init.sh @@ -2,7 +2,7 @@ source="${BASH_SOURCE[0]}" darcVersion='' -versionEndpoint='https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16' +versionEndpoint='https://maestro.dot.net/api/assets/darc-version?api-version=2019-01-16' verbosity='minimal' while [[ $# > 0 ]]; do diff --git a/eng/common/post-build/add-build-to-channel.ps1 b/eng/common/post-build/add-build-to-channel.ps1 index de2d957922a653..49938f0c89f768 100644 --- a/eng/common/post-build/add-build-to-channel.ps1 +++ b/eng/common/post-build/add-build-to-channel.ps1 @@ -2,7 +2,7 @@ param( [Parameter(Mandatory=$true)][int] $BuildId, [Parameter(Mandatory=$true)][int] $ChannelId, [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, - [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com', + [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net', [Parameter(Mandatory=$false)][string] $MaestroApiVersion = '2019-01-16' ) diff --git a/eng/common/post-build/publish-using-darc.ps1 b/eng/common/post-build/publish-using-darc.ps1 index 8508397d77640e..1e779fec4dd1ea 100644 --- a/eng/common/post-build/publish-using-darc.ps1 +++ b/eng/common/post-build/publish-using-darc.ps1 @@ -3,7 +3,7 @@ param( [Parameter(Mandatory=$true)][int] $PublishingInfraVersion, [Parameter(Mandatory=$true)][string] $AzdoToken, [Parameter(Mandatory=$true)][string] $MaestroToken, - [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com', + [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net', [Parameter(Mandatory=$true)][string] $WaitPublishingFinish, [Parameter(Mandatory=$false)][string] $ArtifactsPublishingAdditionalParameters, [Parameter(Mandatory=$false)][string] $SymbolPublishingAdditionalParameters diff --git a/eng/common/post-build/trigger-subscriptions.ps1 b/eng/common/post-build/trigger-subscriptions.ps1 index 55dea518ac5850..ac9a95778fcd9e 100644 --- a/eng/common/post-build/trigger-subscriptions.ps1 +++ b/eng/common/post-build/trigger-subscriptions.ps1 @@ -2,7 +2,7 @@ param( [Parameter(Mandatory=$true)][string] $SourceRepo, [Parameter(Mandatory=$true)][int] $ChannelId, [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, - [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com', + [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net', [Parameter(Mandatory=$false)][string] $MaestroApiVersion = '2019-01-16' ) diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index e20ee3a983cb05..e24ca2f46f98f9 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -136,7 +136,7 @@ jobs: condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}: - - task: NuGetAuthenticate@0 + - task: NuGetAuthenticate@1 - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}: - task: DownloadPipelineArtifact@2 diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml index 42017109f374d6..fa5446c093dd11 100644 --- a/eng/common/templates/job/publish-build-assets.yml +++ b/eng/common/templates/job/publish-build-assets.yml @@ -72,7 +72,7 @@ jobs: condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} - - task: NuGetAuthenticate@0 + - task: NuGetAuthenticate@1 - task: PowerShell@2 displayName: Publish Build Assets @@ -81,7 +81,7 @@ jobs: arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' /p:BuildAssetRegistryToken=$(MaestroAccessToken) - /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com + /p:MaestroApiEndpoint=https://maestro.dot.net /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} /p:OfficialBuildId=$(Build.BuildNumber) condition: ${{ parameters.condition }} diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml index c24193acfc981f..173914f2364a70 100644 --- a/eng/common/templates/post-build/common-variables.yml +++ b/eng/common/templates/post-build/common-variables.yml @@ -7,7 +7,7 @@ variables: # Default Maestro++ API Endpoint and API Version - name: MaestroApiEndPoint - value: "https://maestro-prod.westus2.cloudapp.azure.com" + value: "https://maestro.dot.net" - name: MaestroApiAccessToken value: $(MaestroAccessToken) - name: MaestroApiVersion diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index ef720f9d781989..3f74abf7ce0f8a 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -169,7 +169,7 @@ stages: # This is necessary whenever we want to publish/restore to an AzDO private feed # Since sdk-task.ps1 tries to restore packages we need to do this authentication here # otherwise it'll complain about accessing a private feed. - - task: NuGetAuthenticate@0 + - task: NuGetAuthenticate@1 displayName: 'Authenticate to AzDO Feeds' # Signing validation will optionally work with the buildmanifest file which is downloaded from @@ -266,7 +266,7 @@ stages: BARBuildId: ${{ parameters.BARBuildId }} PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - task: NuGetAuthenticate@0 + - task: NuGetAuthenticate@1 - task: PowerShell@2 displayName: Publish Using Darc diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index fdd0cbb91f8596..eb188cfda415b4 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -601,7 +601,15 @@ function InitializeBuildTool() { ExitWithExitCode 1 } $dotnetPath = Join-Path $dotnetRoot (GetExecutableFileName 'dotnet') - $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = 'net8.0' } + + # Use override if it exists - commonly set by source-build + if ($null -eq $env:_OverrideArcadeInitializeBuildToolFramework) { + $initializeBuildToolFramework="net8.0" + } else { + $initializeBuildToolFramework=$env:_OverrideArcadeInitializeBuildToolFramework + } + + $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = $initializeBuildToolFramework } } elseif ($msbuildEngine -eq "vs") { try { $msbuildPath = InitializeVisualStudioMSBuild -install:$restore diff --git a/eng/common/tools.sh b/eng/common/tools.sh index e8d478943341df..3392e3a99921f7 100755 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -341,7 +341,12 @@ function InitializeBuildTool { # return values _InitializeBuildTool="$_InitializeDotNetCli/dotnet" _InitializeBuildToolCommand="msbuild" - _InitializeBuildToolFramework="net8.0" + # use override if it exists - commonly set by source-build + if [[ "${_OverrideArcadeInitializeBuildToolFramework:-x}" == "x" ]]; then + _InitializeBuildToolFramework="net8.0" + else + _InitializeBuildToolFramework="${_OverrideArcadeInitializeBuildToolFramework}" + fi } # Set RestoreNoCache as a workaround for https://github.com/NuGet/Home/issues/3116 diff --git a/global.json b/global.json index 517059ae7a3859..13f92203054630 100644 --- a/global.json +++ b/global.json @@ -1,16 +1,16 @@ { "sdk": { - "version": "8.0.100", + "version": "8.0.101", "allowPrerelease": true, "rollForward": "major" }, "tools": { - "dotnet": "8.0.100" + "dotnet": "8.0.101" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23564.4", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23564.4", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23564.4", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24059.4", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24059.4", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.24059.4", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From 7441026ca664fd57ac0add21852a96046821058a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 14:03:19 -0800 Subject: [PATCH 563/783] [release/8.0-staging] Update dependencies from dotnet/emsdk (#96812) * Update dependencies from https://github.com/dotnet/emsdk build 20240110.4 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.2-servicing.24060.3 -> To Version 8.0.2-servicing.24060.4 * Update dependencies from https://github.com/dotnet/emsdk build 20240112.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.2-servicing.24060.3 -> To Version 8.0.2-servicing.24062.1 --------- Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index a574dbc251ad5e..76ed5a30293c3a 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0e764146f71cca..3a66ed84acce1d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - 3e200af819951858669fe9616334259e000de22a + 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/emsdk - 3e200af819951858669fe9616334259e000de22a + 2fc2ffd960930318f33fcaa690cbdbc55d72f52d From 69d721940be72e9410597000fcf24e4c016a5a60 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 14:06:33 -0800 Subject: [PATCH 564/783] Move RSA 16384 tests to outerloop. (#95310) These tests take a significant amount of time on Linux due to primality tests of RSA 16384. Co-authored-by: Kevin Jones --- .../RSA/ImportExport.cs | 3 +- .../RSA/RSAKeyFileTests.cs | 42 +++++++++++++++++-- .../AlgorithmImplementations/RSA/RSAXml.cs | 30 +++++++++++-- 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.cs index 4378f4590f19d2..0c196f1c0290a0 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.cs @@ -10,7 +10,8 @@ namespace System.Security.Cryptography.Rsa.Tests [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public partial class ImportExport { - public static bool Supports16384 { get; } = TestRsa16384(); + private static readonly Lazy s_supports16384 = new Lazy(TestRsa16384); + public static bool Supports16384 => s_supports16384.Value; [Fact] public static void ExportAutoKey() diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs index daa175dda47a93..65f73cdef43519 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs @@ -3,6 +3,7 @@ using System.Security.Cryptography.Encryption.RC2.Tests; using System.Text; +using Microsoft.DotNet.XUnitExtensions; using Test.Cryptography; using Xunit; @@ -122,9 +123,17 @@ public static void ReadWriteDiminishedDPPrivatePkcs1() TestData.DiminishedDPParameters); } - [ConditionalFact(typeof(ImportExport), nameof(ImportExport.Supports16384))] + [ConditionalFact] + [OuterLoop("RSA 16384 takes considerable time.")] public static void ReadWritePublicPkcs1() { + // Do not move this to the [ConditionalFact], otherwise the platform will check if RSA 16384 is supported + // during test discovery for innerloop, and the check itself is expensive. + if (!ImportExport.Supports16384) + { + throw new SkipTestException("Platform does not support RSA 16384."); + } + ReadWriteBase64PublicPkcs1( @" MIIICgKCCAEAmyxwX6kQNx+LSMao1StC1p5rKCEwcBjzI136An3B/BjthgezAOuu @@ -198,9 +207,18 @@ public static void ReadWriteSubjectPublicKeyInfo_DiminishedDPKey() TestData.DiminishedDPParameters); } - [ConditionalFact(typeof(ImportExport), nameof(ImportExport.Supports16384))] + + [ConditionalFact] + [OuterLoop("RSA 16384 takes considerable time.")] public static void ReadWriteRsa16384SubjectPublicKeyInfo() { + // Do not move this to the [ConditionalFact], otherwise the platform will check if RSA 16384 is supported + // during test discovery for innerloop, and the check itself is expensive. + if (!ImportExport.Supports16384) + { + throw new SkipTestException("Platform does not support RSA 16384."); + } + ReadWriteBase64SubjectPublicKeyInfo( @" MIIIIjANBgkqhkiG9w0BAQEFAAOCCA8AMIIICgKCCAEAmyxwX6kQNx+LSMao1StC @@ -250,9 +268,17 @@ public static void ReadWriteRsa16384SubjectPublicKeyInfo() TestData.RSA16384Params); } - [ConditionalFact(typeof(ImportExport), nameof(ImportExport.Supports16384))] + [ConditionalFact] + [OuterLoop("RSA 16384 takes considerable time.")] public static void ReadWrite16384Pkcs8() { + // Do not move this to the [ConditionalFact], otherwise the platform will check if RSA 16384 is supported + // during test discovery for innerloop, and the check itself is expensive. + if (!ImportExport.Supports16384) + { + throw new SkipTestException("Platform does not support RSA 16384"); + } + ReadWriteBase64Pkcs8( @" MIIkQgIBADANBgkqhkiG9w0BAQEFAASCJCwwgiQoAgEAAoIIAQCbLHBfqRA3H4tI @@ -525,9 +551,17 @@ public static void ReadEncryptedRsa1032() TestData.RSA1032Parameters); } - [ConditionalFact(typeof(ImportExport), nameof(ImportExport.Supports16384))] + [ConditionalFact] + [OuterLoop("RSA 16384 takes considerable time.")] public static void ReadEncryptedRsa16384() { + // Do not move this to the [ConditionalFact], otherwise the platform will check if RSA 16384 is supported + // during test discovery for innerloop, and the check itself is expensive. + if (!ImportExport.Supports16384) + { + throw new SkipTestException("Platform does not support RSA 16384"); + } + // PBES2: PBKDF2 + des (single DES, not 3DES). const string base64 = @" MIIkizA9BgkqhkiG9w0BBQ0wMDAbBgkqhkiG9w0BBQwwDgQI63upT8JPNNcCAggA diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAXml.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAXml.cs index 666f9bea3c4095..eb354216e77fca 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAXml.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAXml.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Xml.Linq; +using Microsoft.DotNet.XUnitExtensions; using Xunit; namespace System.Security.Cryptography.Rsa.Tests @@ -76,9 +77,17 @@ public static void TestRead1032Parameters_Private() TestData.RSA1032Parameters); } - [ConditionalFact(typeof(ImportExport), nameof(ImportExport.Supports16384))] + [ConditionalFact] + [OuterLoop("RSA 16384 takes considerable time.")] public static void TestRead16384Parameters_Public() { + // Do not move this to the [ConditionalFact], otherwise the platform will check if RSA 16384 is supported + // during test discovery for innerloop, and the check itself is expensive. + if (!ImportExport.Supports16384) + { + throw new SkipTestException("Platform does not support RSA 16384"); + } + RSAParameters expectedParameters = ImportExport.MakePublic(TestData.RSA16384Params); // Bonus trait of this XML: the Modulus and Exponent parameters @@ -157,9 +166,16 @@ iC2wXFMDafnWp1lxXiGcVVu9dE2LeglCgnMUps9QlJD0aXaJHYi2VDQ3zFdMvn8A imlqKtZGdGf9 expectedParameters); } - [ConditionalFact(typeof(ImportExport), nameof(ImportExport.Supports16384))] + [ConditionalFact] public static void TestRead16384Parameters_Private() { + // Do not move this to the [ConditionalFact], otherwise the platform will check if RSA 16384 is supported + // during test discovery for innerloop, and the check itself is expensive. + if (!ImportExport.Supports16384) + { + throw new SkipTestException("Platform does not support RSA 16384"); + } + // Bonus trait of this XML: the D parameter is not in // canonical order. TestReadXml( @@ -634,11 +650,19 @@ public static void TestWrite2048Parameters(bool includePrivateParameters) )); } - [ConditionalTheory(typeof(ImportExport), nameof(ImportExport.Supports16384))] + [ConditionalTheory] [InlineData(true)] [InlineData(false)] + [OuterLoop("RSA 16384 takes considerable time for primality tests.")] public static void TestWrite16384Parameters(bool includePrivateParameters) { + // Do not move this to the [ConditionalFact], otherwise the platform will check if RSA 16384 is supported + // during test discovery for innerloop, and the check itself is expensive. + if (!ImportExport.Supports16384) + { + throw new SkipTestException("Platform does not support RSA 16384"); + } + TestWriteXml( TestData.RSA16384Params, includePrivateParameters, From 8948ea0f36ba815ce94b6c91fdf20686090390ec Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 14:19:41 -0800 Subject: [PATCH 565/783] Make sorting of modules more stable in the compiler (#96167) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The compiler is multithreaded and to achieve stable outputs, it needs to sort everything before writing it to disk. The way we sort modules currently is by looking at the module MVID. It's a very simple, reliable, and efficient way. Except this causes disproportionally large differences in the compiler outputs when a small part of the program was changed - changing something small in an assembly could result in large blocks of methods being shifted in the output executable. This makes delta patching very inefficient. I'm changing the sorting to use assembly names instead. It's less efficient, but doesn't cause problems for delta patching. Co-authored-by: Michal Strehovský --- .../TypeSystem/Ecma/EcmaModule.Sorting.cs | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaModule.Sorting.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaModule.Sorting.cs index 86ec5968907381..ec4e9709459df0 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaModule.Sorting.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaModule.Sorting.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Reflection; using Debug = System.Diagnostics.Debug; @@ -14,11 +15,30 @@ public int CompareTo(EcmaModule other) if (this == other) return 0; - Guid thisMvid = _metadataReader.GetGuid(_metadataReader.GetModuleDefinition().Mvid); - Guid otherMvid = other._metadataReader.GetGuid(other.MetadataReader.GetModuleDefinition().Mvid); + IAssemblyDesc thisAssembly = Assembly; + IAssemblyDesc otherAssembly = other.Assembly; + if (thisAssembly != otherAssembly) + { + // Each module comes from a different assembly: compare the assemblies + AssemblyName thisAssemblyName = thisAssembly.GetName(); + AssemblyName otherAssemblyName = otherAssembly.GetName(); - Debug.Assert(thisMvid.CompareTo(otherMvid) != 0, "Different instance of EcmaModule but same MVID?"); - return thisMvid.CompareTo(otherMvid); + int compare = StringComparer.Ordinal.Compare(thisAssemblyName.Name, otherAssemblyName.Name); + if (compare != 0) + return compare; + + compare = StringComparer.Ordinal.Compare(thisAssemblyName.CultureName, otherAssemblyName.CultureName); + Debug.Assert(compare != 0); + return compare; + } + else + { + // Multi-module assembly: compare two modules that are part of same assembly + string thisName = _metadataReader.GetString(_metadataReader.GetModuleDefinition().Name); + string otherName = other._metadataReader.GetString(other._metadataReader.GetModuleDefinition().Name); + Debug.Assert(StringComparer.Ordinal.Compare(thisName, otherName) != 0); + return StringComparer.Ordinal.Compare(thisName, otherName); + } } } } From f21e249972eb7a9083b45439bd2325a1ebdfead0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 14:19:50 -0800 Subject: [PATCH 566/783] Use a sorted module order for metadata generation (#96168) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reflection metadata generation within the compiler follows a simple algorithm: foreach module in compilation, for each type in the module, if the type generates metadata, generate metadata for it. But it turns out the list of modules that we start with is not sorted. This is not a problem for multithreaded stability, because none of this happens in the multithreaded phase, but it is a problem for delta patching - small change in a program can perturb the metadata blob for no good reason. This sorts the list. Co-authored-by: Michal Strehovský --- .../tools/Common/TypeSystem/Sorting/TypeSystemComparer.cs | 7 ++++++- .../Compiler/UsageBasedMetadataManager.cs | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/coreclr/tools/Common/TypeSystem/Sorting/TypeSystemComparer.cs b/src/coreclr/tools/Common/TypeSystem/Sorting/TypeSystemComparer.cs index 0c91acb42c7d5f..1e0b8a9311dfb0 100644 --- a/src/coreclr/tools/Common/TypeSystem/Sorting/TypeSystemComparer.cs +++ b/src/coreclr/tools/Common/TypeSystem/Sorting/TypeSystemComparer.cs @@ -25,7 +25,7 @@ namespace Internal.TypeSystem // to sort itself with respect to other instances of the same type. // Comparisons between different categories of types are centralized to a single location that // can provide rules to sort them. - public class TypeSystemComparer : IComparer, IComparer, IComparer, IComparer + public class TypeSystemComparer : IComparer, IComparer, IComparer, IComparer, IComparer { public static TypeSystemComparer Instance { get; } = new TypeSystemComparer(); @@ -128,5 +128,10 @@ public int Compare(MethodSignature x, MethodSignature y) { return x.CompareTo(y, this); } + + public int Compare(ModuleDesc x, ModuleDesc y) + { + return Compare(x.GetGlobalModuleType(), y.GetGlobalModuleType()); + } } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs index bd3e1069881361..60a4c0b14f1b74 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs @@ -50,7 +50,7 @@ private static (string AttributeName, DiagnosticId Id)[] _requiresAttributeMisma }; private readonly List _typesWithForcedEEType = new List(); - private readonly List _modulesWithMetadata = new List(); + private readonly SortedSet _modulesWithMetadata = new SortedSet(CompilerComparer.Instance); private readonly List _fieldsWithMetadata = new List(); private readonly List _methodsWithMetadata = new List(); private readonly List _typesWithMetadata = new List(); From 7fd31a3ba3b2ff231f9309a4f41235253d4b3884 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 14:19:59 -0800 Subject: [PATCH 567/783] [release/8.0-staging] Explicit zeroing for stackalloc if inlined into a caller without LocalsInit (#96220) * Propagate locals-init flag from callee * Address feedback * Add a test * Address feedback * clean up --------- Co-authored-by: EgorBo --- src/coreclr/jit/importer.cpp | 7 +++ .../JitBlue/Runtime_96174/Runtime_96174.cs | 43 +++++++++++++++++++ .../Runtime_96174/Runtime_96174.csproj | 10 +++++ 3 files changed, 60 insertions(+) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_96174/Runtime_96174.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_96174/Runtime_96174.csproj diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index b621f7822997b6..6087b1499301cf 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -9517,6 +9517,13 @@ void Compiler::impImportBlockCode(BasicBlock* block) op1 = gtNewLclVarAddrNode(stackallocAsLocal); convertedToLocal = true; + if (compIsForInlining() && info.compInitMem && !impInlineRoot()->info.compInitMem) + { + // Explicitly zero out the local if we're inlining a method with InitLocals into a + // method without InitLocals. + impStoreTemp(stackallocAsLocal, gtNewIconNode(0), CHECK_SPILL_ALL); + } + if (!this->opts.compDbgEnC) { // Ensure we have stack security for this method. diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_96174/Runtime_96174.cs b/src/tests/JIT/Regression/JitBlue/Runtime_96174/Runtime_96174.cs new file mode 100644 index 00000000000000..57d59d30a42aee --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_96174/Runtime_96174.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_96174 +{ + [MethodImpl(MethodImplOptions.NoInlining)] + private static void MethodWithoutLocalsInit() + { + SmallStackalloc(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void MethodWithLoop() + { + for (int i = 0; i < 10000; i++) + { + SmallStackalloc(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SmallStackalloc() + { + Span buf = stackalloc byte[4]; + if (!buf.SequenceEqual("\0\0\0\0"u8)) + throw new InvalidOperationException("Stackalloc was not zero-initialized"); + Consume(buf); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Consume(Span _) {} + + [Fact] + public static void Test() + { + MethodWithoutLocalsInit(); + MethodWithLoop(); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_96174/Runtime_96174.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_96174/Runtime_96174.csproj new file mode 100644 index 00000000000000..6c2e6c34ba4034 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_96174/Runtime_96174.csproj @@ -0,0 +1,10 @@ + + + True + None + true + + + + + \ No newline at end of file From 279dd28f3591fc1dbfa2007817f7c615e5df9f96 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 14:21:22 -0800 Subject: [PATCH 568/783] [release/8.0-staging] ILLink: Allow interface methods to not have newslot (#95571) * ILLink: Allow interface methods to not have newslot Fixes https://github.com/dotnet/runtime/issues/93008 This comes from F#, where interface method defined in F# doesn't have `newslot` flag in its metadata. Trimmer gets confused and doesn't recognize such method as a "base" method for its implementation in the type which implements the interface. As a result, the implementation method is removed from the program because there doesn't seem to be a use for it anywhere. The fix is to basically ignore the `newslot` flag for interface instance methods. The existing behavior must be kept for static interface methods though - as a redefinition of a method with the `new` C# keyword will produce an interface method definition without the `newslot` flag as well. The change adds a new test and modifies the AOT/analyzer infra to run the test as well. * Modify the condition to return for all statics. * Fix the test - ignore unresolved assemblies --------- Co-authored-by: vitek-karas <10670590+vitek-karas@users.noreply.github.com> --- .../TestCases/TestDatabase.cs | 5 ++ .../Mono.Linker.Tests/TestCases/TestSuites.cs | 14 ++++ .../illink/src/linker/Linker/TypeMapInfo.cs | 5 +- .../Inheritance.InterfacesTests.g.cs | 6 ++ .../Dependencies/InterfaceWithoutNewSlot.il | 53 ++++++++++++ .../InterfaceWithoutNewSlot.cs | 80 +++++++++++++++++++ 6 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/Dependencies/InterfaceWithoutNewSlot.il create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceWithoutNewSlot.cs diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs index 57c3de36dd7574..488a283b043db2 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs @@ -34,6 +34,11 @@ public static IEnumerable InlineArrays () return TestNamesBySuiteName(); } + public static IEnumerable Inheritance_Interaces() + { + return TestNamesBySuiteName("Inheritance.Interfaces"); + } + public static IEnumerable Libraries() { return TestNamesBySuiteName(); diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs index f8d7fb5c69d02b..86b5bb49b4f3d2 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs @@ -37,6 +37,20 @@ public void InlineArrays(string t) Run(t); } + [Theory] + [MemberData(nameof(TestDatabase.Inheritance_Interaces), MemberType = typeof(TestDatabase))] + public void Inheritance_Interfaces(string t) + { + switch (t) { + case ".InterfaceWithoutNewSlot": + Run (t); + break; + default: + // Skip the rest for now + break; + } + } + [Theory] [MemberData(nameof(TestDatabase.Libraries), MemberType = typeof(TestDatabase))] public void Libraries(string t) diff --git a/src/tools/illink/src/linker/Linker/TypeMapInfo.cs b/src/tools/illink/src/linker/Linker/TypeMapInfo.cs index 606f3a78a58587..0cdbbfd1746ae0 100644 --- a/src/tools/illink/src/linker/Linker/TypeMapInfo.cs +++ b/src/tools/illink/src/linker/Linker/TypeMapInfo.cs @@ -147,9 +147,12 @@ void MapInterfaceMethodsInTypeHierarchy (TypeDefinition type) // we shouldn't need to run the below logic. This results in ILLink potentially // keeping more methods than needed. + // Static methods on interfaces must be implemented only via explicit method-impl record + // not by a signature match. So there's no point in running the logic below for static methods. + if (!resolvedInterfaceMethod.IsVirtual || resolvedInterfaceMethod.IsFinal - || !resolvedInterfaceMethod.IsNewSlot) + || resolvedInterfaceMethod.IsStatic) continue; // Try to find an implementation with a name/sig match on the current type diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.InterfacesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.InterfacesTests.g.cs index 3ea7c024baf6e6..2e1a2bbcb3454d 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.InterfacesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.InterfacesTests.g.cs @@ -27,5 +27,11 @@ public Task InterfaceVariants () return RunTest (allowMissingWarnings: true); } + [Fact] + public Task InterfaceWithoutNewSlot () + { + return RunTest (allowMissingWarnings: true); + } + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/Dependencies/InterfaceWithoutNewSlot.il b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/Dependencies/InterfaceWithoutNewSlot.il new file mode 100644 index 00000000000000..d31d535fc70e13 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/Dependencies/InterfaceWithoutNewSlot.il @@ -0,0 +1,53 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +.assembly extern mscorlib { } + +.assembly 'library' { } + +.class interface public auto ansi abstract IInterfaceWithoutNewSlot +{ + .method public hidebysig abstract virtual + instance void AbstractNoNewSlot () cil managed + { + } + + .method public hidebysig abstract virtual + instance void AbstractNoNewSlotUnused () cil managed + { + } + + .method public hidebysig newslot abstract virtual + instance void AbstractNewSlot () cil managed + { + } + + .method public hidebysig newslot abstract virtual + instance void AbstractNewSlotUnused () cil managed + { + } + + .method public hidebysig virtual + instance void ImplementedNoNewSlot () cil managed + { + ret; + } + + .method public hidebysig virtual + instance void ImplementedNoNewSlotUnused () cil managed + { + ret; + } + + .method public hidebysig newslot virtual + instance void ImplementedNewSlot () cil managed + { + ret; + } + + .method public hidebysig newslot virtual + instance void ImplementedNewSlotUnused () cil managed + { + ret; + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceWithoutNewSlot.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceWithoutNewSlot.cs new file mode 100644 index 00000000000000..d7d0394919144b --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceWithoutNewSlot.cs @@ -0,0 +1,80 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces +{ + // Tests the case where the interface method doesn't have 'newslot' flag set + [TestCaseRequirements (TestRunCharacteristics.SupportsDefaultInterfaceMethods, "Requires support for default interface methods")] + [SetupLinkerArgument ("--skip-unresolved", "true")] + [Define ("IL_ASSEMBLY_AVAILABLE")] + [SetupCompileBefore ("library.dll", new[] { "Dependencies/InterfaceWithoutNewSlot.il" })] + class InterfaceWithoutNewSlot + { + public static void Main () + { + ImplementationType.Test (); + } + +#if !IL_ASSEMBLY_AVAILABLE + // Declaration for the build of the test suite + // When compiled for actual run the IL version is used instead + // This is because there's no way to express the newslot/no-newslot in C# + interface IInterfaceWithoutNewSlot + { + void AbstractNoNewSlot (); + void AbstractNoNewSlotUnused (); + void AbstractNewSlot (); + void AbstractNewSlotUnused (); + void ImplementedNoNewSlot () { } + void ImplementedNoNewSlotUnused () { } + void ImplementedNewSlot () { } + void ImplementedNewSlotUnused () { } + } +#endif + + [Kept] + [KeptInterface (typeof (IInterfaceWithoutNewSlot))] + [KeptMember (".ctor()")] + class ImplementationType : IInterfaceWithoutNewSlot + { + [Kept] + public void AbstractNoNewSlot () { } + + public void AbstractNoNewSlotUnused () { } + + [Kept] + public void AbstractNewSlot () { } + + public void AbstractNewSlotUnused () { } + + // This is not considered an implementation of the interface method + // CoreCLR doesn't treat it that way either. + public void ImplementedNoNewSlot () { } + + public void ImplementedNoNewSlotUnused () { } + + [Kept] + public void ImplementedNewSlot () { } + + public void ImplementedNewSlotUnused () { } + + [Kept] + public static void Test () + { + IInterfaceWithoutNewSlot instance = new ImplementationType (); + instance.AbstractNoNewSlot (); + instance.AbstractNewSlot (); + instance.ImplementedNoNewSlot (); + instance.ImplementedNewSlot (); + } + } + } +} From fe8a9d00d40cbef9f5642878573af0d5e42ca989 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 22:11:02 -0500 Subject: [PATCH 569/783] [release/8.0-staging] [mono] Fix class initialization spurious wakeups (#96905) * mono_runtime_class_init_full: handle spurious wakeups the condition variable may be signaled even if the initialization by the other thread is not done yet. Handle spurious wakeups the same way as timeouts: go around once more from the beginning. Fixes https://github.com/dotnet/runtime/issues/96872 and https://github.com/dotnet/runtime/issues/96804 * fix unbalanced handle frames if we goto retry_top, don't set up a new handle frame that lacks a matching HANDLE_FUNCTION_RETURN_VAL. Instead setup the handle frame once upfront --------- Co-authored-by: Aleksey Kliger --- src/mono/mono/metadata/object.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index 5d23bb87273ea6..a99369f8bfce5f 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -458,21 +458,24 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error) * on this cond var. */ + HANDLE_FUNCTION_ENTER (); + retry_top: + (void)0; // appease C compiler; label must preceed a statement not a var declaration + + gboolean ret = FALSE; + mono_type_initialization_lock (); /* double check... */ if (vtable->initialized) { mono_type_initialization_unlock (); - return TRUE; + goto return_true; } gboolean do_initialization = FALSE; TypeInitializationLock *lock = NULL; gboolean pending_tae = FALSE; - gboolean ret = FALSE; - - HANDLE_FUNCTION_ENTER (); if (vtable->init_failed) { /* The type initialization already failed once, rethrow the same exception */ @@ -615,8 +618,8 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error) if (!lock->done) { int timeout_ms = 500; int wait_result = mono_coop_cond_timedwait (&lock->cond, &lock->mutex, timeout_ms); - if (wait_result == -1) { - /* timed out - go around again from the beginning. If we got here + if (wait_result == -1 || (wait_result == 0 && !lock->done)) { + /* timed out or spurious wakeup - go around again from the beginning. If we got here * from the "is_blocked = FALSE" case, above (another thread was * blocked on the current thread, but on a lock that was already * done but it didn't get to wake up yet), then it might still be @@ -647,7 +650,7 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error) g_hash_table_remove (type_initialization_hash, vtable); mono_type_initialization_unlock (); goto retry_top; - } else if (wait_result == 0) { + } else if (wait_result == 0 && lock->done) { /* Success: we were signaled that the other thread is done. Proceed */ } else { g_assert_not_reached (); From 95a332e0d40b8d6f27fc0e51ce79d4eb925bb156 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 13 Jan 2024 09:36:44 -0300 Subject: [PATCH 570/783] Fix debug lazy loaded assemblies when webcil is enabled (#96825) Co-authored-by: Thays Grazia --- src/mono/mono/component/mini-wasm-debugger.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/component/mini-wasm-debugger.c b/src/mono/mono/component/mini-wasm-debugger.c index 0e737f420f2a7a..61020ecb573539 100644 --- a/src/mono/mono/component/mini-wasm-debugger.c +++ b/src/mono/mono/component/mini-wasm-debugger.c @@ -215,11 +215,12 @@ assembly_loaded (MonoProfiler *prof, MonoAssembly *assembly) MonoPPDBFile *ppdb = handle->ppdb; if (ppdb && !mono_ppdb_is_embedded (ppdb)) { //if it's an embedded pdb we don't need to send pdb extrated to DebuggerProxy. pdb_image = mono_ppdb_get_image (ppdb); - mono_wasm_asm_loaded (assembly_image->assembly_name, assembly_image->raw_data, assembly_image->raw_data_len, pdb_image->raw_data, pdb_image->raw_data_len); + mono_wasm_asm_loaded (assembly_image->assembly_name, assembly_image->storage->raw_data, assembly_image->storage->raw_data_len, pdb_image->raw_data, pdb_image->raw_data_len); return; } } - mono_wasm_asm_loaded (assembly_image->assembly_name, assembly_image->raw_data, assembly_image->raw_data_len, NULL, 0); + + mono_wasm_asm_loaded (assembly_image->assembly_name, assembly_image->storage->raw_data, assembly_image->storage->raw_data_len, NULL, 0); } } From 46adbbb3b2e347afea8b1b9e0b7b46b04e2840f8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 13 Jan 2024 08:27:20 -0800 Subject: [PATCH 571/783] [release/8.0-staging] GT_STORE_BLK - do not call memset for blocks containg gc pointers on heap (#96514) * Loop-based impl * Add asserts * Add another test case * Update StructWithGC_Zeroing.csproj * Update StructWithGC_Zeroing.cs * clean up * Fix arm32 * Address feedback * Add a small note * Add RISC-V and LA64 * Address feedback * fix build * fix build * CI test * Fix build * Clean up * Apply suggestion * Use REG_R0 on RISC-V and LA64, use ZR on ARM64 * fix build * Clean up * Update src/coreclr/jit/codegenloongarch64.cpp Co-authored-by: Qiao Pengcheng * Apply suggestions for risc-v --------- Co-authored-by: EgorBo Co-authored-by: Qiao Pengcheng --- docs/design/coreclr/botr/clr-abi.md | 44 +++++++++--- src/coreclr/jit/codegen.h | 1 + src/coreclr/jit/codegenarmarch.cpp | 71 +++++++++++++++++++ src/coreclr/jit/codegenloongarch64.cpp | 53 ++++++++++++++ src/coreclr/jit/codegenriscv64.cpp | 60 ++++++++++++++++ src/coreclr/jit/codegenxarch.cpp | 59 +++++++++++++++ src/coreclr/jit/compiler.h | 1 + src/coreclr/jit/gentree.cpp | 5 ++ src/coreclr/jit/gentree.h | 19 ++++- src/coreclr/jit/lower.cpp | 9 +++ src/coreclr/jit/lowerarmarch.cpp | 19 +++++ src/coreclr/jit/lowerloongarch64.cpp | 6 ++ src/coreclr/jit/lowerriscv64.cpp | 6 ++ src/coreclr/jit/lowerxarch.cpp | 16 ++++- src/coreclr/jit/lsraarmarch.cpp | 5 ++ src/coreclr/jit/lsrabuild.cpp | 1 + src/coreclr/jit/lsraloongarch64.cpp | 5 ++ src/coreclr/jit/lsrariscv64.cpp | 5 ++ src/coreclr/jit/lsraxarch.cpp | 5 ++ .../JIT/opt/Structs/StructWithGC_Zeroing.cs | 56 +++++++++++++++ .../opt/Structs/StructWithGC_Zeroing.csproj | 13 ++++ 21 files changed, 445 insertions(+), 14 deletions(-) create mode 100644 src/tests/JIT/opt/Structs/StructWithGC_Zeroing.cs create mode 100644 src/tests/JIT/opt/Structs/StructWithGC_Zeroing.csproj diff --git a/docs/design/coreclr/botr/clr-abi.md b/docs/design/coreclr/botr/clr-abi.md index 825ad5820a920e..9141613db0c0da 100644 --- a/docs/design/coreclr/botr/clr-abi.md +++ b/docs/design/coreclr/botr/clr-abi.md @@ -205,7 +205,7 @@ For non-rude thread abort, the VM walks the stack, running any catch handler tha For example: -``` +```cs try { // try 1 try { // try 2 System.Threading.Thread.CurrentThread.Abort(); @@ -221,7 +221,7 @@ L: In this case, if the address returned in catch 2 corresponding to label L is outside try 1, then the ThreadAbortException re-raised by the VM will not be caught by catch 1, as is expected. The JIT needs to insert a block such that this is the effective code generation: -``` +```cs try { // try 1 try { // try 2 System.Threading.Thread.CurrentThread.Abort(); @@ -238,7 +238,7 @@ L: Similarly, the automatic re-raise address for a ThreadAbortException can't be within a finally handler, or the VM will abort the re-raise and swallow the exception. This can happen due to call-to-finally thunks marked as "cloned finally", as described above. For example (this is pseudo-assembly-code, not C#): -``` +```cs try { // try 1 try { // try 2 System.Threading.Thread.CurrentThread.Abort(); @@ -254,7 +254,7 @@ L: This would generate something like: -``` +```asm // beginning of 'try 1' // beginning of 'try 2' System.Threading.Thread.CurrentThread.Abort(); @@ -279,7 +279,7 @@ Finally1: Note that the JIT must already insert a "step" block so the finally will be called. However, this isn't sufficient to support ThreadAbortException processing, because "L1" is marked as "cloned finally". In this case, the JIT must insert another step block that is within "try 1" but outside the cloned finally block, that will allow for correct re-raise semantics. For example: -``` +```asm // beginning of 'try 1' // beginning of 'try 2' System.Threading.Thread.CurrentThread.Abort(); @@ -397,7 +397,7 @@ To implement this requirement, for any function with EH, we create a frame-local Note that the since a slot on x86 is 4 bytes, the minimum size is 16 bytes. The idea is to have 1 slot for each handler that could be possibly be invoked at the same time. For example, for: -``` +```cs try { ... } catch { @@ -417,7 +417,7 @@ When calling a finally, we set the appropriate level to 0xFC (aka "finally call" Thus, calling a finally from JIT generated code looks like: -``` +```asm mov dword ptr [L_02+0x4 ebp-10H], 0 // This must happen before the 0xFC is written mov dword ptr [L_02+0x8 ebp-0CH], 252 // 0xFC push G_M52300_IG07 @@ -428,7 +428,7 @@ In this case, `G_M52300_IG07` is not the address after the 'jmp', so a simple 'c The code this finally returns to looks like this: -``` +```asm mov dword ptr [L_02+0x8 ebp-0CH], 0 jmp SHORT G_M52300_IG05 ``` @@ -477,7 +477,7 @@ Because a main function body will **always** be on the stack when one of its fun There is one "corner case" in the VM implementation of WantsReportOnlyLeaf model that has implications for the code the JIT is allowed to generate. Consider this function with nested exception handling: -``` +```cs public void runtest() { try { try { @@ -804,3 +804,29 @@ In addition to the usual registers it also preserves all float registers and `rc `CORINFO_HELP_DISPATCH_INDIRECT_CALL` takes the call address in `rax` and it reserves the right to use and trash `r10` and `r11`. The JIT uses the dispatch helper on x64 whenever possible as it is expected that the code size benefits outweighs the less accurate branch prediction. However, note that the use of `r11` in the dispatcher makes it incompatible with VSD calls where the JIT must fall back to the validator and a manual call. + +# Notes on Memset/Memcpy + +Generally, `memset` and `memcpy` do not provide any guarantees of atomicity. This implies that they should only be used when the memory being modified by `memset`/`memcpy` is not observable by any other thread (including GC), or when there are no atomicity requirements according to our [Memory Model](../../specs/Memory-model.md). It's especially important when we modify heap containing managed pointers - those must be updated atomically, e.g. using pointer-sized `mov` instruction (managed pointers are always aligned) - see [Atomic Memory Access](../../specs/Memory-model.md#Atomic-memory-accesses). It's worth noting that by "update" it's implied "set to zero", otherwise, we need a write barrier. + +Examples: + +```cs +struct MyStruct +{ + long a; + string b; +} + +void Test1(ref MyStruct m) +{ + // We're not allowed to use memset here + m = default; +} + +MyStruct Test2() +{ + // We can use memset here + return default; +} +``` \ No newline at end of file diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index eb190f97f0e479..dda0d1871e4bf1 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -1226,6 +1226,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #ifndef TARGET_X86 void genCodeForInitBlkHelper(GenTreeBlk* initBlkNode); #endif + void genCodeForInitBlkLoop(GenTreeBlk* initBlkNode); void genCodeForInitBlkRepStos(GenTreeBlk* initBlkNode); void genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode); void genJumpTable(GenTree* tree); diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 5434ef7b722ef9..562dad738bd3e1 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3114,6 +3114,72 @@ void CodeGen::genCodeForInitBlkHelper(GenTreeBlk* initBlkNode) genEmitHelperCall(CORINFO_HELP_MEMSET, 0, EA_UNKNOWN); } +//------------------------------------------------------------------------ +// genCodeForInitBlkLoop - Generate code for an InitBlk using an inlined for-loop. +// It's needed for cases when size is too big to unroll and we're not allowed +// to use memset call due to atomicity requirements. +// +// Arguments: +// initBlkNode - the GT_STORE_BLK node +// +void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode) +{ + GenTree* const dstNode = initBlkNode->Addr(); + genConsumeReg(dstNode); + const regNumber dstReg = dstNode->GetRegNum(); + +#ifndef TARGET_ARM64 + GenTree* const zeroNode = initBlkNode->Data(); + genConsumeReg(zeroNode); + const regNumber zeroReg = zeroNode->GetRegNum(); +#else + const regNumber zeroReg = REG_ZR; +#endif + + if (initBlkNode->IsVolatile()) + { + // issue a full memory barrier before a volatile initBlock Operation + instGen_MemoryBarrier(); + } + + // str xzr, [dstReg] + // mov offsetReg, + //.LOOP: + // str xzr, [dstReg, offsetReg] + // subs offsetReg, offsetReg, #8 + // bne .LOOP + + const unsigned size = initBlkNode->GetLayout()->GetSize(); + assert((size >= TARGET_POINTER_SIZE) && ((size % TARGET_POINTER_SIZE) == 0)); + + // The loop is reversed - it makes it smaller. + // Although, we zero the first pointer before the loop (the loop doesn't zero it) + // it works as a nullcheck, otherwise the first iteration would try to access + // "null + potentially large offset" and hit AV. + GetEmitter()->emitIns_R_R(INS_str, EA_PTRSIZE, zeroReg, dstReg); + if (size > TARGET_POINTER_SIZE) + { + // Extend liveness of dstReg in case if it gets killed by the store. + gcInfo.gcMarkRegPtrVal(dstReg, dstNode->TypeGet()); + + const regNumber offsetReg = initBlkNode->GetSingleTempReg(); + instGen_Set_Reg_To_Imm(EA_PTRSIZE, offsetReg, size - TARGET_POINTER_SIZE); + + BasicBlock* loop = genCreateTempLabel(); + genDefineTempLabel(loop); + + GetEmitter()->emitIns_R_R_R(INS_str, EA_PTRSIZE, zeroReg, dstReg, offsetReg); +#ifdef TARGET_ARM64 + GetEmitter()->emitIns_R_R_I(INS_subs, EA_PTRSIZE, offsetReg, offsetReg, TARGET_POINTER_SIZE); +#else + GetEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, offsetReg, offsetReg, TARGET_POINTER_SIZE, INS_FLAGS_SET); +#endif + inst_JMP(EJ_ne, loop); + + gcInfo.gcMarkRegSetNpt(genRegMask(dstReg)); + } +} + //------------------------------------------------------------------------ // genCall: Produce code for a GT_CALL node // @@ -4384,6 +4450,11 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp) genCodeForCpObj(blkOp->AsBlk()); break; + case GenTreeBlk::BlkOpKindLoop: + assert(!isCopyBlk); + genCodeForInitBlkLoop(blkOp); + break; + case GenTreeBlk::BlkOpKindHelper: assert(!blkOp->gtBlkOpGcUnsafe); if (isCopyBlk) diff --git a/src/coreclr/jit/codegenloongarch64.cpp b/src/coreclr/jit/codegenloongarch64.cpp index 33bd2a77486c65..2f7444e0825ae4 100644 --- a/src/coreclr/jit/codegenloongarch64.cpp +++ b/src/coreclr/jit/codegenloongarch64.cpp @@ -6375,6 +6375,54 @@ void CodeGen::genCodeForInitBlkHelper(GenTreeBlk* initBlkNode) genEmitHelperCall(CORINFO_HELP_MEMSET, 0, EA_UNKNOWN); } +//------------------------------------------------------------------------ +// genCodeForInitBlkLoop - Generate code for an InitBlk using an inlined for-loop. +// It's needed for cases when size is too big to unroll and we're not allowed +// to use memset call due to atomicity requirements. +// +// Arguments: +// initBlkNode - the GT_STORE_BLK node +// +void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode) +{ + GenTree* const dstNode = initBlkNode->Addr(); + genConsumeReg(dstNode); + const regNumber dstReg = dstNode->GetRegNum(); + + if (initBlkNode->IsVolatile()) + { + // issue a full memory barrier before a volatile initBlock Operation + instGen_MemoryBarrier(); + } + + const unsigned size = initBlkNode->GetLayout()->GetSize(); + assert((size >= TARGET_POINTER_SIZE) && ((size % TARGET_POINTER_SIZE) == 0)); + + // The loop is reversed - it makes it smaller. + // Although, we zero the first pointer before the loop (the loop doesn't zero it) + // it works as a nullcheck, otherwise the first iteration would try to access + // "null + potentially large offset" and hit AV. + GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_R0, dstReg, 0); + if (size > TARGET_POINTER_SIZE) + { + // Extend liveness of dstReg in case if it gets killed by the store. + gcInfo.gcMarkRegPtrVal(dstReg, dstNode->TypeGet()); + + const regNumber offsetReg = initBlkNode->GetSingleTempReg(); + instGen_Set_Reg_To_Imm(EA_PTRSIZE, offsetReg, size - TARGET_POINTER_SIZE); + + // loop begin: + // *(dstReg + offsetReg) = 0 + GetEmitter()->emitIns_R_R_R(INS_stx_d, EA_PTRSIZE, REG_R0, dstReg, offsetReg); + // offsetReg = offsetReg - 8 + GetEmitter()->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, offsetReg, offsetReg, -8); + // if (offsetReg != 0) goto loop; + GetEmitter()->emitIns_R_I(INS_bnez, EA_8BYTE, offsetReg, -2 << 2); + + gcInfo.gcMarkRegSetNpt(genRegMask(dstReg)); + } +} + // Generate code for a load from some address + offset // base: tree node which can be either a local address or arbitrary node // offset: distance from the base from which to load @@ -7286,6 +7334,11 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp) genCodeForCpObj(blkOp->AsBlk()); break; + case GenTreeBlk::BlkOpKindLoop: + assert(!isCopyBlk); + genCodeForInitBlkLoop(blkOp); + break; + case GenTreeBlk::BlkOpKindHelper: if (isCopyBlk) { diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp index 39d25e316e529e..df5b47554d8b95 100644 --- a/src/coreclr/jit/codegenriscv64.cpp +++ b/src/coreclr/jit/codegenriscv64.cpp @@ -5958,6 +5958,61 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode) } } +//------------------------------------------------------------------------ +// genCodeForInitBlkLoop - Generate code for an InitBlk using an inlined for-loop. +// It's needed for cases when size is too big to unroll and we're not allowed +// to use memset call due to atomicity requirements. +// +// Arguments: +// initBlkNode - the GT_STORE_BLK node +// +void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode) +{ + GenTree* const dstNode = initBlkNode->Addr(); + genConsumeReg(dstNode); + const regNumber dstReg = dstNode->GetRegNum(); + + if (initBlkNode->IsVolatile()) + { + // issue a full memory barrier before a volatile initBlock Operation + instGen_MemoryBarrier(); + } + + const unsigned size = initBlkNode->GetLayout()->GetSize(); + assert((size >= TARGET_POINTER_SIZE) && ((size % TARGET_POINTER_SIZE) == 0)); + + // The loop is reversed - it makes it smaller. + // Although, we zero the first pointer before the loop (the loop doesn't zero it) + // it works as a nullcheck, otherwise the first iteration would try to access + // "null + potentially large offset" and hit AV. + GetEmitter()->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_R0, dstReg, 0); + if (size > TARGET_POINTER_SIZE) + { + // Extend liveness of dstReg in case if it gets killed by the store. + gcInfo.gcMarkRegPtrVal(dstReg, dstNode->TypeGet()); + + const regNumber tempReg = initBlkNode->GetSingleTempReg(); + instGen_Set_Reg_To_Imm(EA_PTRSIZE, tempReg, size - TARGET_POINTER_SIZE); + + // tempReg = dstReg + tempReg (a new interior pointer, but in a nongc region) + GetEmitter()->emitIns_R_R_R(INS_add, EA_PTRSIZE, tempReg, dstReg, tempReg); + + BasicBlock* loop = genCreateTempLabel(); + genDefineTempLabel(loop); + GetEmitter()->emitDisableGC(); // TODO: add gcinfo to tempReg and remove nogc + + // *tempReg = 0 + GetEmitter()->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_R0, tempReg, 0); + // tempReg = tempReg - 8 + GetEmitter()->emitIns_R_R_I(INS_addi, EA_PTRSIZE, tempReg, tempReg, -8); + // if (tempReg != dstReg) goto loop; + GetEmitter()->emitIns_J(INS_bne, loop, (int)tempReg | ((int)dstReg << 5)); + GetEmitter()->emitEnableGC(); + + gcInfo.gcMarkRegSetNpt(genRegMask(dstReg)); + } +} + //------------------------------------------------------------------------ // genCodeForInitBlkHelper - Generate code for an InitBlk node by the means of the VM memcpy helper call // @@ -6853,6 +6908,11 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp) genCodeForCpObj(blkOp->AsBlk()); break; + case GenTreeBlk::BlkOpKindLoop: + assert(!isCopyBlk); + genCodeForInitBlkLoop(blkOp); + break; + case GenTreeBlk::BlkOpKindHelper: if (isCopyBlk) { diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 5847b40ffd32e2..12764affdd92e4 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -3034,6 +3034,11 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* storeBlkNode) genCodeForCpObj(storeBlkNode->AsBlk()); break; + case GenTreeBlk::BlkOpKindLoop: + assert(!isCopyBlk); + genCodeForInitBlkLoop(storeBlkNode); + break; + #ifdef TARGET_AMD64 case GenTreeBlk::BlkOpKindHelper: assert(!storeBlkNode->gtBlkOpGcUnsafe); @@ -3312,6 +3317,60 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node) #endif } +//------------------------------------------------------------------------ +// genCodeForInitBlkLoop - Generate code for an InitBlk using an inlined for-loop. +// It's needed for cases when size is too big to unroll and we're not allowed +// to use memset call due to atomicity requirements. +// +// Arguments: +// initBlkNode - the GT_STORE_BLK node +// +void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode) +{ + GenTree* const dstNode = initBlkNode->Addr(); + GenTree* const zeroNode = initBlkNode->Data(); + + genConsumeReg(dstNode); + genConsumeReg(zeroNode); + + const regNumber dstReg = dstNode->GetRegNum(); + const regNumber zeroReg = zeroNode->GetRegNum(); + + // xor zeroReg, zeroReg + // mov qword ptr [dstReg], zeroReg + // mov offsetReg, + //.LOOP: + // mov qword ptr [dstReg + offsetReg], zeroReg + // sub offsetReg, 8 + // jne .LOOP + + const unsigned size = initBlkNode->GetLayout()->GetSize(); + assert((size >= TARGET_POINTER_SIZE) && ((size % TARGET_POINTER_SIZE) == 0)); + + // The loop is reversed - it makes it smaller. + // Although, we zero the first pointer before the loop (the loop doesn't zero it) + // it works as a nullcheck, otherwise the first iteration would try to access + // "null + potentially large offset" and hit AV. + GetEmitter()->emitIns_AR_R(INS_mov, EA_PTRSIZE, zeroReg, dstReg, 0); + if (size > TARGET_POINTER_SIZE) + { + // Extend liveness of dstReg in case if it gets killed by the store. + gcInfo.gcMarkRegPtrVal(dstReg, dstNode->TypeGet()); + + const regNumber offsetReg = initBlkNode->GetSingleTempReg(); + instGen_Set_Reg_To_Imm(EA_PTRSIZE, offsetReg, size - TARGET_POINTER_SIZE); + + BasicBlock* loop = genCreateTempLabel(); + genDefineTempLabel(loop); + + GetEmitter()->emitIns_ARX_R(INS_mov, EA_PTRSIZE, zeroReg, dstReg, offsetReg, 1, 0); + GetEmitter()->emitIns_R_I(INS_sub, EA_PTRSIZE, offsetReg, TARGET_POINTER_SIZE); + inst_JMP(EJ_jne, loop); + + gcInfo.gcMarkRegSetNpt(genRegMask(dstReg)); + } +} + #ifdef TARGET_AMD64 //------------------------------------------------------------------------ // genCodeForInitBlkHelper - Generate code for an InitBlk node by the means of the VM memcpy helper call diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 8339d6d274f4f5..dd23c482559155 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9905,6 +9905,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX STRESS_MODE(IF_CONVERSION_COST) \ STRESS_MODE(IF_CONVERSION_INNER_LOOPS) \ STRESS_MODE(POISON_IMPLICIT_BYREFS) \ + STRESS_MODE(STORE_BLOCK_UNROLLING) \ STRESS_MODE(COUNT) enum compStressArea diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 7c34c51571e66d..31be03bda15b7e 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -12227,6 +12227,11 @@ void Compiler::gtDispTree(GenTree* tree, printf(" (Helper)"); break; #endif + + case GenTreeBlk::BlkOpKindLoop: + printf(" (Loop)"); + break; + default: unreached(); } diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 109da6a15c30d8..5a06113fa8d717 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -7248,6 +7248,7 @@ struct GenTreeBlk : public GenTreeIndir #ifdef TARGET_XARCH BlkOpKindRepInstr, #endif + BlkOpKindLoop, BlkOpKindUnroll, BlkOpKindUnrollMemmove, } gtBlkOpKind; @@ -7256,12 +7257,20 @@ struct GenTreeBlk : public GenTreeIndir bool gtBlkOpGcUnsafe; #endif -#ifdef TARGET_XARCH + bool ContainsReferences() + { + return (m_layout != nullptr) && m_layout->HasGCPtr(); + } + bool IsOnHeapAndContainsReferences() { - return (m_layout != nullptr) && m_layout->HasGCPtr() && !Addr()->OperIs(GT_LCL_ADDR); + return ContainsReferences() && !Addr()->OperIs(GT_LCL_ADDR); + } + + bool IsZeroingGcPointersOnHeap() + { + return OperIs(GT_STORE_BLK) && Data()->IsIntegralConst(0) && IsOnHeapAndContainsReferences(); } -#endif GenTreeBlk(genTreeOps oper, var_types type, GenTree* addr, ClassLayout* layout) : GenTreeIndir(oper, type, addr, nullptr) @@ -7272,6 +7281,10 @@ struct GenTreeBlk : public GenTreeIndir GenTreeBlk(genTreeOps oper, var_types type, GenTree* addr, GenTree* data, ClassLayout* layout) : GenTreeIndir(oper, type, addr, data) { + if (data->IsIntegralConst(0)) + { + data->gtFlags |= GTF_DONT_CSE; + } Initialize(layout); } diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 2e454e64c14eb1..2231a044b04cdb 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -7973,6 +7973,15 @@ void Lowering::LowerBlockStoreCommon(GenTreeBlk* blkNode) { assert(blkNode->OperIs(GT_STORE_BLK, GT_STORE_DYN_BLK)); + if (blkNode->ContainsReferences() && !blkNode->OperIsCopyBlkOp()) + { + // Make sure we don't use GT_STORE_DYN_BLK + assert(blkNode->OperIs(GT_STORE_BLK)); + + // and we only zero it (and that zero is better to be not hoisted/CSE'd) + assert(blkNode->Data()->IsIntegralConst(0)); + } + // Lose the type information stored in the source - we no longer need it. if (blkNode->Data()->OperIs(GT_BLK)) { diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 2536d44aa00c56..c58456940bf5e1 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -554,6 +554,16 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) if (blkNode->OperIsInitBlkOp()) { +#ifdef DEBUG + // Use BlkOpKindLoop for more cases under stress mode + if (comp->compStressCompile(Compiler::STRESS_STORE_BLOCK_UNROLLING, 50) && blkNode->OperIs(GT_STORE_BLK) && + ((blkNode->GetLayout()->GetSize() % TARGET_POINTER_SIZE) == 0) && src->IsIntegralConst(0)) + { + blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindLoop; + return; + } +#endif + if (src->OperIs(GT_INIT_VAL)) { src->SetContained(); @@ -598,6 +608,15 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) ContainBlockStoreAddress(blkNode, size, dstAddr, nullptr); } + else if (blkNode->IsZeroingGcPointersOnHeap()) + { + blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindLoop; +#ifdef TARGET_ARM64 + // On ARM64 we can just use REG_ZR instead of having to load + // the constant into a real register like on ARM32. + src->SetContained(); +#endif + } else { blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper; diff --git a/src/coreclr/jit/lowerloongarch64.cpp b/src/coreclr/jit/lowerloongarch64.cpp index d89c8723e80f66..d522a85ab0f966 100644 --- a/src/coreclr/jit/lowerloongarch64.cpp +++ b/src/coreclr/jit/lowerloongarch64.cpp @@ -326,6 +326,12 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) ContainBlockStoreAddress(blkNode, size, dstAddr, nullptr); } + else if (blkNode->IsZeroingGcPointersOnHeap()) + { + blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindLoop; + // We're going to use REG_R0 for zero + src->SetContained(); + } else { blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper; diff --git a/src/coreclr/jit/lowerriscv64.cpp b/src/coreclr/jit/lowerriscv64.cpp index 37848fc5909de3..0c0f0aafc34bcc 100644 --- a/src/coreclr/jit/lowerriscv64.cpp +++ b/src/coreclr/jit/lowerriscv64.cpp @@ -280,6 +280,12 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) ContainBlockStoreAddress(blkNode, size, dstAddr, nullptr); } + else if (blkNode->IsZeroingGcPointersOnHeap()) + { + blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindLoop; + // We're going to use REG_R0 for zero + src->SetContained(); + } else { blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper; diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 150ad04a55d99f..f9766fe8e7b345 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -310,6 +310,16 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) if (blkNode->OperIsInitBlkOp()) { +#ifdef DEBUG + // Use BlkOpKindLoop for more cases under stress mode + if (comp->compStressCompile(Compiler::STRESS_STORE_BLOCK_UNROLLING, 50) && blkNode->OperIs(GT_STORE_BLK) && + ((blkNode->GetLayout()->GetSize() % TARGET_POINTER_SIZE) == 0) && src->IsIntegralConst(0)) + { + blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindLoop; + return; + } +#endif + if (src->OperIs(GT_INIT_VAL)) { src->SetContained(); @@ -375,10 +385,12 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) { TOO_BIG_TO_UNROLL: #ifdef TARGET_AMD64 - blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper; + blkNode->gtBlkOpKind = + blkNode->IsZeroingGcPointersOnHeap() ? GenTreeBlk::BlkOpKindLoop : GenTreeBlk::BlkOpKindHelper; #else // TODO-X86-CQ: Investigate whether a helper call would be beneficial on x86 - blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindRepInstr; + blkNode->gtBlkOpKind = + blkNode->IsZeroingGcPointersOnHeap() ? GenTreeBlk::BlkOpKindLoop : GenTreeBlk::BlkOpKindRepInstr; #endif } } diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index e72ff23df3375d..b87e0f80539fdc 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -631,6 +631,11 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode) #endif // TARGET_ARM64 break; + case GenTreeBlk::BlkOpKindLoop: + // Needed for offsetReg + buildInternalIntRegisterDefForNode(blkNode, availableIntRegs); + break; + case GenTreeBlk::BlkOpKindHelper: assert(!src->isContained()); dstAddrRegMask = RBM_ARG_0; diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 8c9025f61b703a..22efbf53b82cb9 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -968,6 +968,7 @@ regMaskTP LinearScan::getKillSetForBlockStore(GenTreeBlk* blkNode) #endif case GenTreeBlk::BlkOpKindUnrollMemmove: case GenTreeBlk::BlkOpKindUnroll: + case GenTreeBlk::BlkOpKindLoop: case GenTreeBlk::BlkOpKindInvalid: // for these 'gtBlkOpKind' kinds, we leave 'killMask' = RBM_NONE break; diff --git a/src/coreclr/jit/lsraloongarch64.cpp b/src/coreclr/jit/lsraloongarch64.cpp index 7ab333630c046a..0312342a38914e 100644 --- a/src/coreclr/jit/lsraloongarch64.cpp +++ b/src/coreclr/jit/lsraloongarch64.cpp @@ -1114,6 +1114,11 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode) } break; + case GenTreeBlk::BlkOpKindLoop: + // Needed for offsetReg + buildInternalIntRegisterDefForNode(blkNode, availableIntRegs); + break; + case GenTreeBlk::BlkOpKindHelper: assert(!src->isContained()); dstAddrRegMask = RBM_ARG_0; diff --git a/src/coreclr/jit/lsrariscv64.cpp b/src/coreclr/jit/lsrariscv64.cpp index 4be7a391d26a70..09d8a8daf905a8 100644 --- a/src/coreclr/jit/lsrariscv64.cpp +++ b/src/coreclr/jit/lsrariscv64.cpp @@ -1129,6 +1129,11 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode) } break; + case GenTreeBlk::BlkOpKindLoop: + // Needed for tempReg + buildInternalIntRegisterDefForNode(blkNode, availableIntRegs); + break; + case GenTreeBlk::BlkOpKindHelper: assert(!src->isContained()); dstAddrRegMask = RBM_ARG_0; diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index 5d54c08ebb7902..678aa6bd596bb9 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -1406,6 +1406,11 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode) sizeRegMask = RBM_RCX; break; + case GenTreeBlk::BlkOpKindLoop: + // Needed for offsetReg + buildInternalIntRegisterDefForNode(blkNode, availableIntRegs); + break; + #ifdef TARGET_AMD64 case GenTreeBlk::BlkOpKindHelper: dstAddrRegMask = RBM_ARG_0; diff --git a/src/tests/JIT/opt/Structs/StructWithGC_Zeroing.cs b/src/tests/JIT/opt/Structs/StructWithGC_Zeroing.cs new file mode 100644 index 00000000000000..0a8719a2430a3b --- /dev/null +++ b/src/tests/JIT/opt/Structs/StructWithGC_Zeroing.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public class StructWithGC_Zeroing +{ + [Fact] + public static void StructZeroingShouldNotUseMemset() + { + LargeStructWithGC ls1 = default; + ls1.str = "hello1"; + ls1.z2 = long.MaxValue; + ZeroIt(ref ls1); + + LargeStructWithGC2 ls2 = default; + ls2.str = "hello2"; + ls2.z1 = long.MinValue; + ZeroIt2(ref ls2); + + if (ls1.str != null || ls2.str != null || ls1.z2 != 0 || ls2.z1 != 0) + throw new InvalidOperationException("should be zeroed"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void ZeroIt(ref LargeStructWithGC s) + { + // X64-NOT: CORINFO_HELP_MEMSET + // ARM64-NOT: CORINFO_HELP_MEMSET + s = default; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void ZeroIt2(ref LargeStructWithGC2 s) + { + // X64-NOT: CORINFO_HELP_MEMSET + // ARM64-NOT: CORINFO_HELP_MEMSET + s = default; + } + + struct LargeStructWithGC // 360 bytes (64-bit) + { + public string str; + public long b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, r1, s1, t1, u1, v1, w1, z1; + public long b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, r2, s2, t2, u2, v2, w2, z2; + } + + unsafe struct LargeStructWithGC2 // 4184 bytes (64-bit) + { + public fixed byte data[4000]; + public string str; + public long b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, r1, s1, t1, u1, v1, w1, z1; + } +} diff --git a/src/tests/JIT/opt/Structs/StructWithGC_Zeroing.csproj b/src/tests/JIT/opt/Structs/StructWithGC_Zeroing.csproj new file mode 100644 index 00000000000000..7aa59749804e49 --- /dev/null +++ b/src/tests/JIT/opt/Structs/StructWithGC_Zeroing.csproj @@ -0,0 +1,13 @@ + + + true + true + None + True + + + + true + + + From 9d7719005445dcf2f3c4ce6e9336ce2b93b4e83a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 13 Jan 2024 08:27:51 -0800 Subject: [PATCH 572/783] [release/8.0-staging] Fix hwintrinsicChild->isContained() assert (#96388) * Fix containment * Fix naming * Update src/tests/JIT/Regression/JitBlue/Runtime_90508/Runtime_90508.cs Co-authored-by: Bruce Forstall * better fix * oops, typo * clean up * Update lowerxarch.cpp * Update Runtime_90508.cs * Update Runtime_90508.cs --------- Co-authored-by: EgorBo Co-authored-by: Bruce Forstall --- src/coreclr/jit/lowerxarch.cpp | 5 ++- .../JitBlue/Runtime_90508/Runtime_90508.cs | 39 +++++++++++++++++++ .../Runtime_90508/Runtime_90508.csproj | 8 ++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_90508/Runtime_90508.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_90508/Runtime_90508.csproj diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index f9766fe8e7b345..f0e7fc6322f2be 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -7668,7 +7668,10 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre const unsigned expectedSize = genTypeSize(parentNode->TypeGet()) / 2; const unsigned operandSize = genTypeSize(childNode->TypeGet()); - supportsGeneralLoads = supportsUnalignedSIMDLoads && (operandSize >= expectedSize); + // For broadcasts we can only optimize constants and memory operands + const bool broadcastIsContainable = childNode->OperIsConst() || childNode->isMemoryOp(); + supportsGeneralLoads = + broadcastIsContainable && supportsUnalignedSIMDLoads && (operandSize >= expectedSize); break; } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_90508/Runtime_90508.cs b/src/tests/JIT/Regression/JitBlue/Runtime_90508/Runtime_90508.cs new file mode 100644 index 00000000000000..ce2881a9d67185 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_90508/Runtime_90508.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using Xunit; + +public class Runtime_90508 +{ + [MethodImpl(MethodImplOptions.NoInlining)] + private static Vector128 Test1(Vector128 v, double b) => + v + Sse3.MoveAndDuplicate(Vector128.CreateScalarUnsafe(b)); + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Vector128 Test2(Vector128 v) => + v + Sse3.MoveAndDuplicate(Vector128.CreateScalarUnsafe(1.0)); + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Vector128 Test3(Vector128 v) => + v + Sse3.MoveAndDuplicate(Vector128.Create(1.0)); + + [Fact] + public static int TestEntryPoint() + { + if (!Sse3.IsSupported) + { + return 100; + } + + if (Test1(Vector128.Create(42.0), 1).ToString().Equals("<43, 43>") && + Test2(Vector128.Create(42.0)).ToString().Equals("<43, 43>") && + Test3(Vector128.Create(42.0)).ToString().Equals("<43, 43>")) + { + return 100; + } + return 101; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_90508/Runtime_90508.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_90508/Runtime_90508.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_90508/Runtime_90508.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From 9a5998c6f7f0699fdb78b3e221ccec31b72fdb7b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 12:12:34 -0800 Subject: [PATCH 573/783] [release/8.0-staging] [iOS][tvOS] Fix building runtime tests on iOS-like platforms (#96994) * Do not trim XUnitWrapperGenerator * Avoid including ILLink * Publis trimmed only for exes * Fix duplicates check in merged test runner --------- Co-authored-by: Simon Rozsival --- src/tests/Common/mergedrunner.targets | 6 +++--- src/tests/Directory.Build.props | 6 +++--- src/tests/MergedTestRunner.targets | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/tests/Common/mergedrunner.targets b/src/tests/Common/mergedrunner.targets index 81a9def0117f10..72ae7aeef1f190 100644 --- a/src/tests/Common/mergedrunner.targets +++ b/src/tests/Common/mergedrunner.targets @@ -7,7 +7,7 @@ <_ProjectReferencesUsedByReferencePaths Include="@(ReferencePath->Metadata('ProjectReferenceOriginalItemSpec'))" /> - <_ProjectAssemblyReferences Include="@(ProjectReference)" Condition="'%(ProjectReference.OutputItemType)' == ''" /> + <_ProjectAssemblyReferences Include="@(ProjectReference)" Condition="'%(ProjectReference.OutputItemType)' == '' and '%(ProjectReference.ReferenceOutputAssembly)' != 'false'" /> <_ProjectAssemblyReferences Remove="@(_ReferenceWithDisabledBuild->Metadata('OriginalItemSpec'))" /> <_ProjectReferencesRemovedDueToConflictResolution Include="@(_ProjectAssemblyReferences)" Exclude="@(_ProjectReferencesUsedByReferencePaths)" /> @@ -17,6 +17,6 @@ --> - + - \ No newline at end of file + diff --git a/src/tests/Directory.Build.props b/src/tests/Directory.Build.props index 2d73150fc5f94a..674ab3b0baa180 100644 --- a/src/tests/Directory.Build.props +++ b/src/tests/Directory.Build.props @@ -203,9 +203,9 @@ false - - true - true + + true + true true diff --git a/src/tests/MergedTestRunner.targets b/src/tests/MergedTestRunner.targets index 258b711537d2bf..686ba0d11d4949 100644 --- a/src/tests/MergedTestRunner.targets +++ b/src/tests/MergedTestRunner.targets @@ -12,10 +12,11 @@ true + - \ No newline at end of file + From 806d04b02e42254b0be9b0b85119f3e9133462bd Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Mon, 15 Jan 2024 20:14:30 +0000 Subject: [PATCH 574/783] Add null checks in System.Security.Cryptography --- .../tests/X509Certificates/CertTests.cs | 6 ++++++ .../tests/X509Certificates/TestData.cs | 2 ++ .../apibridge.c | 17 ++++++++++++++++- .../openssl.c | 5 +++++ .../pal_pkcs7.c | 10 ++++++++++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs index c51987b37ca3a6..838398a8b0092c 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs @@ -440,6 +440,12 @@ public static void UseAfterDispose() } } + [Fact] + public static void EmptyPkcs7ThrowsException() + { + Assert.ThrowsAny(() => new X509Certificate2(TestData.EmptyPkcs7)); + } + [Fact] public static void ExportPublicKeyAsPkcs12() { diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs index cf14136eb6e058..0d7633f9992ef2 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs @@ -4273,5 +4273,7 @@ internal static DSAParameters GetDSA1024Params() "C0CC2B115B9D33BD6E528E35670E5A6A8D9CF52199F8D693315C60D9ADAD54EF7FDCED36" + "0C8C79E84D42AB5CB6355A70951B1ABF1F2B3FB8BEB7E3A8D6BA2293C0DB8C86B0BB060F" + "0D6DB9939E88B998662A27F092634BBF21F58EEAAA").HexToByteArray(); + + internal static readonly byte[] EmptyPkcs7 = "300B06092A864886F70D010702".HexToByteArray(); } } diff --git a/src/native/libs/System.Security.Cryptography.Native/apibridge.c b/src/native/libs/System.Security.Cryptography.Native/apibridge.c index bad65ee2b50211..64ed18961fea4c 100644 --- a/src/native/libs/System.Security.Cryptography.Native/apibridge.c +++ b/src/native/libs/System.Security.Cryptography.Native/apibridge.c @@ -112,7 +112,7 @@ int32_t local_X509_get_version(const X509* x509) X509_PUBKEY* local_X509_get_X509_PUBKEY(const X509* x509) { - if (x509) + if (x509 && x509->cert_info) { return x509->cert_info->key; } @@ -123,13 +123,28 @@ X509_PUBKEY* local_X509_get_X509_PUBKEY(const X509* x509) int32_t local_X509_PUBKEY_get0_param( ASN1_OBJECT** palgOid, const uint8_t** pkeyBytes, int* pkeyBytesLen, X509_ALGOR** palg, X509_PUBKEY* pubkey) { + if (!pubkey) + { + return 0; + } + if (palgOid) { + if (!pubkey->algor) + { + return 0; + } + *palgOid = pubkey->algor->algorithm; } if (pkeyBytes) { + if (!pubkey->public_key) + { + return 0; + } + *pkeyBytes = pubkey->public_key->data; *pkeyBytesLen = pubkey->public_key->length; } diff --git a/src/native/libs/System.Security.Cryptography.Native/openssl.c b/src/native/libs/System.Security.Cryptography.Native/openssl.c index ba713b6fdcc212..73822045895425 100644 --- a/src/native/libs/System.Security.Cryptography.Native/openssl.c +++ b/src/native/libs/System.Security.Cryptography.Native/openssl.c @@ -669,6 +669,11 @@ BIO* CryptoNative_GetX509NameInfo(X509* x509, int32_t nameType, int32_t forIssue 0 == strncmp(localOid, szOidUpn, sizeof(szOidUpn))) { // OTHERNAME->ASN1_TYPE->union.field + if (!value->value) + { + return NULL; + } + str = value->value->value.asn1_string; } } diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_pkcs7.c b/src/native/libs/System.Security.Cryptography.Native/pal_pkcs7.c index efb0a738966f55..bc6c1215d632d2 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_pkcs7.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_pkcs7.c @@ -53,9 +53,19 @@ int32_t CryptoNative_GetPkcs7Certificates(PKCS7* p7, X509Stack** certs) switch (OBJ_obj2nid(p7->type)) { case NID_pkcs7_signed: + if (!p7->d.sign) + { + return 0; + } + *certs = p7->d.sign->cert; return 1; case NID_pkcs7_signedAndEnveloped: + if (!p7->d.signed_and_enveloped) + { + return 0; + } + *certs = p7->d.signed_and_enveloped->cert; return 1; } From edf220901fed5dbc32b8cc56158d371ec40343db Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 10:45:22 +0100 Subject: [PATCH 575/783] Fix memory leak on OCSP_Response (#96577) Co-authored-by: Radek Zikmund --- src/native/libs/System.Security.Cryptography.Native/pal_ssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c index 29d478555ce130..e6bd41143c1655 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c @@ -577,7 +577,7 @@ X509* CryptoNative_SslGetPeerCertificate(SSL* ssl) long len = SSL_get_tlsext_status_ocsp_resp(ssl, &data); X509* cert = SSL_get1_peer_certificate(ssl); - if (len > 0 && cert != NULL) + if (len > 0 && cert != NULL && !X509_get_ex_data(cert, g_x509_ocsp_index)) { OCSP_RESPONSE* ocspResp = d2i_OCSP_RESPONSE(NULL, &data, len); From 67fbb6c024e5aab3f5b4bf30d4f448a302d70175 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 10:14:27 -0800 Subject: [PATCH 576/783] Update dependencies from https://github.com/dotnet/source-build-externals build 20240115.1 (#97032) Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24059.4 -> To Version 8.0.0-alpha.1.24065.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3a66ed84acce1d..80223670b2c57e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -104,9 +104,9 @@ 95f83e27806330fec09edd96e06bba3acabe3f35 - + https://github.com/dotnet/source-build-externals - 7134e53b6b1210a1ce8838b12b8f6071e0a3433b + 83274d94c7e2ff21081b0d75ecbec2da2241f831 From 7395a2644266b2d19cd36ed5f8272b994199555c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 10:15:09 -0800 Subject: [PATCH 577/783] Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20240111.1 (#96990) Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.23565.1 -> To Version 8.0.0-alpha.1.24061.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 80223670b2c57e..95c24b9f3675f5 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -99,9 +99,9 @@ 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/source-build-reference-packages - 95f83e27806330fec09edd96e06bba3acabe3f35 + 453a37ef7ae6c335cd49b3b9ab7713c87faeb265 From a5fc8ff9b03ffb2fdb81dad524ad1a20a0714995 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 10:24:41 -0800 Subject: [PATCH 578/783] Disable implicit rejection for RSA PKCS#1 (#95216) Co-authored-by: Kevin Jones --- .../RSA/EncryptDecrypt.cs | 49 +++++++++++++++---- .../opensslshim.h | 6 +++ .../pal_evp_pkey_rsa.c | 13 +++++ 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs index 5b97f468a4271e..39f3ebc82ec678 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs @@ -353,19 +353,10 @@ private void RsaCryptRoundtrip(RSAEncryptionPadding paddingMode, bool expectSucc Assert.Equal(TestData.HelloBytes, output); } - [ConditionalFact] + [ConditionalFact(nameof(PlatformSupportsEmptyRSAEncryption))] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] public void RoundtripEmptyArray() { - if (OperatingSystem.IsIOS() && !OperatingSystem.IsIOSVersionAtLeast(13, 6)) - { - throw new SkipTestException("iOS prior to 13.6 does not reliably support RSA encryption of empty data."); - } - if (OperatingSystem.IsTvOS() && !OperatingSystem.IsTvOSVersionAtLeast(14, 0)) - { - throw new SkipTestException("tvOS prior to 14.0 does not reliably support RSA encryption of empty data."); - } - using (RSA rsa = RSAFactory.Create(TestData.RSA2048Params)) { void RoundtripEmpty(RSAEncryptionPadding paddingMode) @@ -725,6 +716,26 @@ public void NotSupportedValueMethods() } } + [ConditionalTheory] + [InlineData(new byte[] { 1, 2, 3, 4 })] + [InlineData(new byte[0])] + public void Decrypt_Pkcs1_ErrorsForInvalidPadding(byte[] data) + { + if (data.Length == 0 && !PlatformSupportsEmptyRSAEncryption) + { + throw new SkipTestException("Platform does not support RSA encryption of empty data."); + } + + using (RSA rsa = RSAFactory.Create(TestData.RSA2048Params)) + { + byte[] encrypted = Encrypt(rsa, data, RSAEncryptionPadding.Pkcs1); + encrypted[1] ^= 0xFF; + + // PKCS#1, the data, and the key are all deterministic so this should always throw an exception. + Assert.ThrowsAny(() => Decrypt(rsa, encrypted, RSAEncryptionPadding.Pkcs1)); + } + } + public static IEnumerable OaepPaddingModes { get @@ -746,5 +757,23 @@ public static IEnumerable OaepPaddingModes } } } + + public static bool PlatformSupportsEmptyRSAEncryption + { + get + { + if (OperatingSystem.IsIOS() && !OperatingSystem.IsIOSVersionAtLeast(13, 6)) + { + return false; + } + + if (OperatingSystem.IsTvOS() && !OperatingSystem.IsTvOSVersionAtLeast(14, 0)) + { + return false; + } + + return true; + } + } } } diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index cf10d2f794987d..0748e305d5ce0c 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -296,8 +296,10 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len); REQUIRED_FUNCTION(ERR_peek_error) \ REQUIRED_FUNCTION(ERR_peek_error_line) \ REQUIRED_FUNCTION(ERR_peek_last_error) \ + REQUIRED_FUNCTION(ERR_pop_to_mark) \ FALLBACK_FUNCTION(ERR_put_error) \ REQUIRED_FUNCTION(ERR_reason_error_string) \ + REQUIRED_FUNCTION(ERR_set_mark) \ LIGHTUP_FUNCTION(ERR_set_debug) \ LIGHTUP_FUNCTION(ERR_set_error) \ REQUIRED_FUNCTION(EVP_aes_128_cbc) \ @@ -353,6 +355,7 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len); REQUIRED_FUNCTION(EVP_PKCS82PKEY) \ REQUIRED_FUNCTION(EVP_PKEY2PKCS8) \ REQUIRED_FUNCTION(EVP_PKEY_CTX_ctrl) \ + REQUIRED_FUNCTION(EVP_PKEY_CTX_ctrl_str) \ REQUIRED_FUNCTION(EVP_PKEY_CTX_free) \ REQUIRED_FUNCTION(EVP_PKEY_CTX_get0_pkey) \ REQUIRED_FUNCTION(EVP_PKEY_CTX_new) \ @@ -794,8 +797,10 @@ FOR_ALL_OPENSSL_FUNCTIONS #define ERR_peek_error_line ERR_peek_error_line_ptr #define ERR_peek_last_error ERR_peek_last_error_ptr #define ERR_put_error ERR_put_error_ptr +#define ERR_pop_to_mark ERR_pop_to_mark_ptr #define ERR_reason_error_string ERR_reason_error_string_ptr #define ERR_set_debug ERR_set_debug_ptr +#define ERR_set_mark ERR_set_mark_ptr #define ERR_set_error ERR_set_error_ptr #define EVP_aes_128_cbc EVP_aes_128_cbc_ptr #define EVP_aes_128_cfb8 EVP_aes_128_cfb8_ptr @@ -850,6 +855,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #define EVP_PKCS82PKEY EVP_PKCS82PKEY_ptr #define EVP_PKEY2PKCS8 EVP_PKEY2PKCS8_ptr #define EVP_PKEY_CTX_ctrl EVP_PKEY_CTX_ctrl_ptr +#define EVP_PKEY_CTX_ctrl_str EVP_PKEY_CTX_ctrl_str_ptr #define EVP_PKEY_CTX_free EVP_PKEY_CTX_free_ptr #define EVP_PKEY_CTX_get0_pkey EVP_PKEY_CTX_get0_pkey_ptr #define EVP_PKEY_CTX_new EVP_PKEY_CTX_new_ptr diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c index c9ccdf33e3afe0..043bf9f9d1edab 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c @@ -67,6 +67,19 @@ static bool ConfigureEncryption(EVP_PKEY_CTX* ctx, RsaPaddingMode padding, const { return false; } + + // OpenSSL 3.2 introduced a change where PKCS#1 RSA decryption does not fail for invalid padding. + // If the padding is invalid, the decryption operation returns random data. + // See https://github.com/openssl/openssl/pull/13817 for background. + // Some Linux distributions backported this change to previous versions of OpenSSL. + // Here we do a best-effort to set a flag to revert the behavior to failing if the padding is invalid. + ERR_set_mark(); + + EVP_PKEY_CTX_ctrl_str(ctx, "rsa_pkcs1_implicit_rejection", "0"); + + // Undo any changes to the error queue that may have occured while configuring implicit rejection if the + // current version does not support implicit rejection. + ERR_pop_to_mark(); } else { From f9d0a7b6678e667b47833fefd9ae5f32afa49a11 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 10:33:45 -0800 Subject: [PATCH 579/783] [release/8.0-staging] Fix Crossgen2 PDB generation (again) (#96566) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix Crossgen2 PDB generation (again) * Simplify the change per JanK's PR feedback --------- Co-authored-by: Tomáš Rylek --- .../tools/aot/ILCompiler.Diagnostics/PdbWriter.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs index 9ec90146a471c6..0ad1098f21debb 100644 --- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs +++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs @@ -143,9 +143,14 @@ public void WritePDBData(string dllPath, IEnumerable methods) } finally { - if ((_ngenWriter != null) && (_pdbMod != UIntPtr.Zero)) + if (_ngenWriter != null) { - _ngenWriter.CloseMod(_pdbMod); + if (_pdbMod != UIntPtr.Zero) + { + _ngenWriter.CloseMod(_pdbMod); + } + ComObject ngenWriterComObject = (ComObject)(object)_ngenWriter; + ngenWriterComObject.FinalRelease(); } } @@ -211,6 +216,7 @@ private void WritePDBDataHelper(string dllPath, IEnumerable methods) var comWrapper = new StrategyBasedComWrappers(); CreateNGenPdbWriter(dllPath, _pdbFilePath, out var pdbWriterInst); _ngenWriter = (ISymNGenWriter2)comWrapper.GetOrCreateObjectForComInstance(pdbWriterInst, CreateObjectFlags.UniqueInstance); + Marshal.Release(pdbWriterInst); { // PDB file is now created. Get its path and update _pdbFilePath so the PDB file From 683da71a303abf737f763416a8b8c09fab8663ed Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 11:10:59 -0800 Subject: [PATCH 580/783] [release/8.0-staging] Gen0 segment should always be reported as Gen0 for DacHeapWalker (#96861) * Gen0 segment should always be reported as Gen0 for DacHeapWalker * Code review feedback --------- Co-authored-by: Andrew Au --- src/coreclr/debug/daccess/request_svr.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/coreclr/debug/daccess/request_svr.cpp b/src/coreclr/debug/daccess/request_svr.cpp index ac0010e3e9af90..d1dd6f046e8370 100644 --- a/src/coreclr/debug/daccess/request_svr.cpp +++ b/src/coreclr/debug/daccess/request_svr.cpp @@ -335,7 +335,7 @@ HRESULT DacHeapWalker::InitHeapDataSvr(HeapData *&pHeaps, size_t &pCount) for (int i = 0; i < heaps; ++i) { // Basic heap info. - TADDR heapAddress = HeapTableIndex(g_gcDacGlobals->g_heaps, i); + TADDR heapAddress = HeapTableIndex(g_gcDacGlobals->g_heaps, i); dac_gc_heap heap = LoadGcHeapData(heapAddress); dac_gc_heap* pHeap = &heap; dac_generation gen0 = ServerGenerationTableIndex(heapAddress, 0); @@ -395,17 +395,16 @@ HRESULT DacHeapWalker::InitHeapDataSvr(HeapData *&pHeaps, size_t &pCount) seg = gen0.start_segment; for (; seg && (j < count); ++j) { + pHeaps[i].Segments[j].Generation = CorDebug_Gen0; pHeaps[i].Segments[j].Start = (CORDB_ADDRESS)seg->mem; if (seg.GetAddr() == pHeap->ephemeral_heap_segment.GetAddr()) { pHeaps[i].Segments[j].End = (CORDB_ADDRESS)pHeap->alloc_allocated; pHeaps[i].EphemeralSegment = j; - pHeaps[i].Segments[j].Generation = CorDebug_Gen0; } else { pHeaps[i].Segments[j].End = (CORDB_ADDRESS)seg->allocated; - pHeaps[i].Segments[j].Generation = seg->flags & HEAP_SEGMENT_FLAGS_READONLY ? CorDebug_NonGC : CorDebug_Gen2;; } seg = seg->next; @@ -471,11 +470,11 @@ void DacFreeRegionEnumerator::AddServerRegions() TADDR heapAddress = (TADDR)HeapTableIndex(g_gcDacGlobals->g_heaps, i); if (heapAddress == 0) continue; - + dac_gc_heap heap = LoadGcHeapData(heapAddress); for (int i = 0; i < count_free_region_kinds; i++) AddSegmentList(heap.free_regions[i].head_free_region, FreeRegionKind::FreeRegion, i); - + AddSegmentList(heap.freeable_soh_segment, FreeRegionKind::FreeSohSegment, i); AddSegmentList(heap.freeable_uoh_segment, FreeRegionKind::FreeUohSegment, i); } From 85c277284219155c42ef32a1c77c12357cb02f5d Mon Sep 17 00:00:00 2001 From: Radek Zikmund <32671551+rzikm@users.noreply.github.com> Date: Wed, 17 Jan 2024 00:08:05 +0100 Subject: [PATCH 581/783] [release/8.0] Fix server-side OCSP stapling on Linux (#96838) * Add entire issuer chain to trusted X509_STORE when stapling OCSP_Response (#96792) * Add entire issuer chain to trusted X509_STORE when validating OCSP_Response * Code review feedback * More code review feedback * Update src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs Co-authored-by: Jeremy Barton * Fix compilation * Always include root certificate --------- Co-authored-by: Jeremy Barton * Recover from failed OCSP download. (#96448) * Recover from failed OCSP check. * Add 5s back-off after failed OCSP querry * Don't shorten OCSP expriation on failed server OCSP fetch (#96972) * Don't shorten OCSP expriation on failed server OCSP fetch * Code review feedback --------- Co-authored-by: Jeremy Barton --- .../Interop.OCSP.cs | 9 ++- .../SslStreamCertificateContext.Linux.cs | 59 ++++++++++++++----- .../pal_x509.c | 17 ++++-- .../pal_x509.h | 2 +- 4 files changed, 65 insertions(+), 22 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OCSP.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OCSP.cs index 59736b39f47e82..8b07660a3fb657 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OCSP.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OCSP.cs @@ -29,27 +29,30 @@ private static unsafe partial int CryptoNative_X509DecodeOcspToExpiration( int len, SafeOcspRequestHandle req, IntPtr subject, - IntPtr issuer, + IntPtr* issuers, + int issuersLen, ref long expiration); internal static unsafe bool X509DecodeOcspToExpiration( ReadOnlySpan buf, SafeOcspRequestHandle request, IntPtr x509Subject, - IntPtr x509Issuer, + ReadOnlySpan x509Issuers, out DateTimeOffset expiration) { long timeT = 0; int ret; fixed (byte* pBuf = buf) + fixed (IntPtr* pIssuers = x509Issuers) { ret = CryptoNative_X509DecodeOcspToExpiration( pBuf, buf.Length, request, x509Subject, - x509Issuer, + pIssuers, + x509Issuers.Length, ref timeT); } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs index cc80cc6e27badf..9c7902d7948b03 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs @@ -26,13 +26,30 @@ public partial class SslStreamCertificateContext private byte[]? _ocspResponse; private DateTimeOffset _ocspExpiration; private DateTimeOffset _nextDownload; + // Private copy of the intermediate certificates, in case the user decides to dispose the + // instances reachable through IntermediateCertificates property. + private X509Certificate2[] _privateIntermediateCertificates; + private X509Certificate2? _rootCertificate; private Task? _pendingDownload; private List? _ocspUrls; - private X509Certificate2? _ca; private SslStreamCertificateContext(X509Certificate2 target, ReadOnlyCollection intermediates, SslCertificateTrust? trust) { IntermediateCertificates = intermediates; + if (intermediates.Count > 0) + { + _privateIntermediateCertificates = new X509Certificate2[intermediates.Count]; + + for (int i = 0; i < intermediates.Count; i++) + { + _privateIntermediateCertificates[i] = new X509Certificate2(intermediates[i]); + } + } + else + { + _privateIntermediateCertificates = Array.Empty(); + } + TargetCertificate = target; Trust = trust; SslContexts = new ConcurrentDictionary(); @@ -76,15 +93,8 @@ partial void SetNoOcspFetch(bool noOcspFetch) partial void AddRootCertificate(X509Certificate2? rootCertificate, ref bool transferredOwnership) { - if (IntermediateCertificates.Count == 0) - { - _ca = rootCertificate; - transferredOwnership = true; - } - else - { - _ca = IntermediateCertificates[0]; - } + _rootCertificate = rootCertificate; + transferredOwnership = rootCertificate != null; if (!_staplingForbidden) { @@ -149,7 +159,7 @@ partial void AddRootCertificate(X509Certificate2? rootCertificate, ref bool tran return new ValueTask(pending); } - if (_ocspUrls is null && _ca is not null) + if (_ocspUrls is null && _rootCertificate is not null) { foreach (X509Extension ext in TargetCertificate.Extensions) { @@ -192,7 +202,9 @@ partial void AddRootCertificate(X509Certificate2? rootCertificate, ref bool tran private async Task FetchOcspAsync() { - X509Certificate2? caCert = _ca; + Debug.Assert(_rootCertificate != null); + X509Certificate2? caCert = _privateIntermediateCertificates.Length > 0 ? _privateIntermediateCertificates[0] : _rootCertificate; + Debug.Assert(_ocspUrls is not null); Debug.Assert(_ocspUrls.Count > 0); Debug.Assert(caCert is not null); @@ -211,6 +223,13 @@ partial void AddRootCertificate(X509Certificate2? rootCertificate, ref bool tran return null; } + IntPtr[] issuerHandles = ArrayPool.Shared.Rent(_privateIntermediateCertificates.Length + 1); + for (int i = 0; i < _privateIntermediateCertificates.Length; i++) + { + issuerHandles[i] = _privateIntermediateCertificates[i].Handle; + } + issuerHandles[_privateIntermediateCertificates.Length] = _rootCertificate.Handle; + using (SafeOcspRequestHandle ocspRequest = Interop.Crypto.X509BuildOcspRequest(subject, issuer)) { byte[] rentedBytes = ArrayPool.Shared.Rent(Interop.Crypto.GetOcspRequestDerSize(ocspRequest)); @@ -227,7 +246,7 @@ partial void AddRootCertificate(X509Certificate2? rootCertificate, ref bool tran if (ret is not null) { - if (!Interop.Crypto.X509DecodeOcspToExpiration(ret, ocspRequest, subject, issuer, out DateTimeOffset expiration)) + if (!Interop.Crypto.X509DecodeOcspToExpiration(ret, ocspRequest, subject, issuerHandles.AsSpan(0, _privateIntermediateCertificates.Length + 1), out DateTimeOffset expiration)) { ret = null; continue; @@ -247,15 +266,27 @@ partial void AddRootCertificate(X509Certificate2? rootCertificate, ref bool tran _ocspResponse = ret; _ocspExpiration = expiration; _nextDownload = nextCheckA < nextCheckB ? nextCheckA : nextCheckB; - _pendingDownload = null; break; } } + issuerHandles.AsSpan().Clear(); + ArrayPool.Shared.Return(issuerHandles); ArrayPool.Shared.Return(rentedBytes); ArrayPool.Shared.Return(rentedChars.Array!); GC.KeepAlive(TargetCertificate); + GC.KeepAlive(_privateIntermediateCertificates); + GC.KeepAlive(_rootCertificate); GC.KeepAlive(caCert); + + _pendingDownload = null; + if (ret == null) + { + // All download attempts failed, don't try again for 5 seconds. + // This backoff will be applied only if the OCSP staple is not expired. + // If it is expired, we will force-refresh it during next GetOcspResponseAsync call. + _nextDownload = DateTimeOffset.UtcNow.AddSeconds(5); + } return ret; } } diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_x509.c b/src/native/libs/System.Security.Cryptography.Native/pal_x509.c index 40f7c604e8f39d..04c6ba06cd5dce 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_x509.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_x509.c @@ -1302,11 +1302,11 @@ CryptoNative_X509ChainVerifyOcsp(X509_STORE_CTX* storeCtx, OCSP_REQUEST* req, OC return X509ChainVerifyOcsp(storeCtx, subject, issuer, req, resp, cachePath); } -int32_t CryptoNative_X509DecodeOcspToExpiration(const uint8_t* buf, int32_t len, OCSP_REQUEST* req, X509* subject, X509* issuer, int64_t* expiration) +int32_t CryptoNative_X509DecodeOcspToExpiration(const uint8_t* buf, int32_t len, OCSP_REQUEST* req, X509* subject, X509** issuers, int issuersLen, int64_t* expiration) { ERR_clear_error(); - if (buf == NULL || len == 0) + if (buf == NULL || len == 0 || issuersLen == 0) { return 0; } @@ -1329,7 +1329,16 @@ int32_t CryptoNative_X509DecodeOcspToExpiration(const uint8_t* buf, int32_t len, if (bag != NULL) { - if (X509_STORE_add_cert(store, issuer) && sk_X509_push(bag, issuer)) + int i; + for (i = 0; i < issuersLen; i++) + { + if (!X509_STORE_add_cert(store, issuers[i]) || !sk_X509_push(bag, issuers[i])) + { + break; + } + } + + if (i == issuersLen) { ctx = X509_STORE_CTX_new(); } @@ -1343,7 +1352,7 @@ int32_t CryptoNative_X509DecodeOcspToExpiration(const uint8_t* buf, int32_t len, { int canCache = 0; time_t expiration_t = 0; - X509VerifyStatusCode code = CheckOcspGetExpiry(req, resp, subject, issuer, ctx, &canCache, &expiration_t); + X509VerifyStatusCode code = CheckOcspGetExpiry(req, resp, subject, issuers[0], ctx, &canCache, &expiration_t); if (sizeof(time_t) == sizeof(int64_t)) { diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_x509.h b/src/native/libs/System.Security.Cryptography.Native/pal_x509.h index be376882d127f6..bf76a1c2345ffd 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_x509.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_x509.h @@ -412,4 +412,4 @@ PALEXPORT int32_t CryptoNative_X509ChainVerifyOcsp(X509_STORE_CTX* storeCtx, Decode len bytes of buf into an OCSP response, process it against the OCSP request, and return if the bytes were valid. If the bytes were valid, and the OCSP response had a nextUpdate value, assign it to expiration. */ -PALEXPORT int32_t CryptoNative_X509DecodeOcspToExpiration(const uint8_t* buf, int32_t len, OCSP_REQUEST* req, X509* subject, X509* issuer, int64_t* expiration); +PALEXPORT int32_t CryptoNative_X509DecodeOcspToExpiration(const uint8_t* buf, int32_t len, OCSP_REQUEST* req, X509* subject, X509** issuers, int issuersLen, int64_t* expiration); From 96b0a55bd51ad3e45609bcf1fa8ab030ce2c27ba Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Tue, 16 Jan 2024 19:49:19 -0500 Subject: [PATCH 582/783] [release/8.0-staging] macOS: Set certificate as a dependency of private key handles (#96993) * macOS: Set certificate as a dependency of private key handles * [iOS] Skip PublicPrivateKey_IndependentLifetimes_DSA test (#96685) DSA is not supported --------- Co-authored-by: Steve Pfister --- .../Interop.SecKeyRef.cs | 23 +++ .../AppleCertificatePal.Keys.macOS.cs | 1 + .../X509Certificates/AppleCertificatePal.cs | 3 + .../tests/X509Certificates/CertTests.cs | 151 ++++++++++++++++++ 4 files changed, 178 insertions(+) diff --git a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs index ad5a34517b1a52..e7c08596a2c39c 100644 --- a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs +++ b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs @@ -178,15 +178,38 @@ namespace System.Security.Cryptography.Apple { internal sealed class SafeSecKeyRefHandle : SafeHandle { + private SafeHandle? _parentHandle; + public SafeSecKeyRefHandle() : base(IntPtr.Zero, ownsHandle: true) { } + internal void SetParentHandle(SafeHandle parentHandle) + { + Debug.Assert(_parentHandle is null); + + bool added = false; + parentHandle.DangerousAddRef(ref added); + _parentHandle = parentHandle; + + // If we became invalid while the parent handle was being incremented, release the parent handle since + // ReleaseHandle will not get called. + if (IsInvalid) + { + _parentHandle.DangerousRelease(); + _parentHandle = null; + } + } + protected override bool ReleaseHandle() { Interop.CoreFoundation.CFRelease(handle); SetHandle(IntPtr.Zero); + + _parentHandle?.DangerousRelease(); + _parentHandle = null; + return true; } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Keys.macOS.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Keys.macOS.cs index d926074d88c489..228e70098870db 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Keys.macOS.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Keys.macOS.cs @@ -29,6 +29,7 @@ internal sealed partial class AppleCertificatePal : ICertificatePal publicKey = Interop.AppleCrypto.ImportEphemeralKey(_certData.SubjectPublicKeyInfo, false); } + privateKey.SetParentHandle(_certHandle); return new DSAImplementation.DSASecurityTransforms(publicKey, privateKey); } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.cs index 1a6cf9467e4dd5..781e08be5519b7 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.cs @@ -330,6 +330,7 @@ public byte[] SubjectPublicKeyInfo Debug.Assert(!_identityHandle.IsInvalid); SafeSecKeyRefHandle publicKey = Interop.AppleCrypto.X509GetPublicKey(_certHandle); SafeSecKeyRefHandle privateKey = Interop.AppleCrypto.X509GetPrivateKeyFromIdentity(_identityHandle); + privateKey.SetParentHandle(_certHandle); Debug.Assert(!publicKey.IsInvalid); return new RSAImplementation.RSASecurityTransforms(publicKey, privateKey); @@ -343,6 +344,7 @@ public byte[] SubjectPublicKeyInfo Debug.Assert(!_identityHandle.IsInvalid); SafeSecKeyRefHandle publicKey = Interop.AppleCrypto.X509GetPublicKey(_certHandle); SafeSecKeyRefHandle privateKey = Interop.AppleCrypto.X509GetPrivateKeyFromIdentity(_identityHandle); + privateKey.SetParentHandle(_certHandle); Debug.Assert(!publicKey.IsInvalid); return new ECDsaImplementation.ECDsaSecurityTransforms(publicKey, privateKey); @@ -356,6 +358,7 @@ public byte[] SubjectPublicKeyInfo Debug.Assert(!_identityHandle.IsInvalid); SafeSecKeyRefHandle publicKey = Interop.AppleCrypto.X509GetPublicKey(_certHandle); SafeSecKeyRefHandle privateKey = Interop.AppleCrypto.X509GetPrivateKeyFromIdentity(_identityHandle); + privateKey.SetParentHandle(_certHandle); Debug.Assert(!publicKey.IsInvalid); return new ECDiffieHellmanImplementation.ECDiffieHellmanSecurityTransforms(publicKey, privateKey); diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs index c51987b37ca3a6..4d4a46e33efcc4 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; +using System.Security.Cryptography.Dsa.Tests; +using System.Security.Cryptography.X509Certificates.Tests.CertificateCreation; using System.Threading; using Microsoft.DotNet.XUnitExtensions; using Test.Cryptography; @@ -25,6 +27,155 @@ public CertTests(ITestOutputHelper output) _log = output; } + [Fact] + public static void PublicPrivateKey_IndependentLifetimes_ECDsa() + { + X509Certificate2 loaded; + + using (ECDsa ca = ECDsa.Create(ECCurve.NamedCurves.nistP256)) + { + CertificateRequest req = new("CN=potatos", ca, HashAlgorithmName.SHA256); + + using (X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddDays(3))) + { + loaded = new X509Certificate2(cert.Export(X509ContentType.Pkcs12, "carrots"), "carrots"); + } + } + + using (ECDsa verifyKey = loaded.GetECDsaPublicKey()) + { + byte[] signature; + byte[] data = RandomNumberGenerator.GetBytes(32); + + using (ECDsa signingKey = loaded.GetECDsaPrivateKey()) + { + loaded.Dispose(); + signature = signingKey.SignHash(data); + } + + Assert.True(verifyKey.VerifyHash(data, signature), nameof(verifyKey.VerifyHash)); + } + } + + [Fact] + public static void PublicPrivateKey_IndependentLifetimes_ECDiffieHellman() + { + X509Certificate2 loaded; + + using (ECDsa ca = ECDsa.Create(ECCurve.NamedCurves.nistP256)) + using (ECDiffieHellman ecdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256)) + { + CertificateRequest issuerRequest = new CertificateRequest( + new X500DistinguishedName("CN=root"), + ca, + HashAlgorithmName.SHA256); + + issuerRequest.CertificateExtensions.Add( + new X509BasicConstraintsExtension(true, false, 0, true)); + + CertificateRequest request = new CertificateRequest( + new X500DistinguishedName("CN=potato"), + new PublicKey(ecdh), + HashAlgorithmName.SHA256); + + request.CertificateExtensions.Add( + new X509BasicConstraintsExtension(false, false, 0, true)); + request.CertificateExtensions.Add( + new X509KeyUsageExtension(X509KeyUsageFlags.KeyAgreement, true)); + + DateTimeOffset notBefore = DateTimeOffset.UtcNow; + DateTimeOffset notAfter = notBefore.AddDays(30); + byte[] serial = [1, 2, 3, 4, 5, 6, 7, 8]; + + using (X509Certificate2 issuer = issuerRequest.CreateSelfSigned(notBefore, notAfter)) + using (X509Certificate2 cert = request.Create(issuer, notBefore, notAfter, serial)) + using (X509Certificate2 certWithKey = cert.CopyWithPrivateKey(ecdh)) + { + loaded = new X509Certificate2(certWithKey.Export(X509ContentType.Pkcs12, "carrots"), "carrots");; + } + } + + using (ECDiffieHellman partyB = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256)) + using (ECDiffieHellman partyAPrivateKey = loaded.GetECDiffieHellmanPrivateKey()) + using (ECDiffieHellman partyAPublicKey = loaded.GetECDiffieHellmanPublicKey()) + { + loaded.Dispose(); + byte[] derivedB = partyB.DeriveKeyFromHash(partyAPublicKey.PublicKey, HashAlgorithmName.SHA256, null, null); + byte[] derivedA = partyAPrivateKey.DeriveKeyFromHash(partyB.PublicKey, HashAlgorithmName.SHA256, null, null); + Assert.Equal(derivedB, derivedA); + } + } + + [Fact] + public static void PublicPrivateKey_IndependentLifetimes_RSA() + { + X509Certificate2 loaded; + + using (RSA ca = RSA.Create(2048)) + { + CertificateRequest req = new("CN=potatos", ca, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + + using (X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddDays(3))) + { + loaded = new X509Certificate2(cert.Export(X509ContentType.Pkcs12, "carrots"), "carrots"); + } + } + + using (RSA verifyKey = loaded.GetRSAPublicKey()) + { + byte[] signature; + byte[] data = RandomNumberGenerator.GetBytes(32); + + using (RSA signingKey = loaded.GetRSAPrivateKey()) + { + loaded.Dispose(); + signature = signingKey.SignHash(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + } + + Assert.True(verifyKey.VerifyHash(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1), nameof(verifyKey.VerifyHash)); + } + } + + [Fact] + [SkipOnPlatform(PlatformSupport.MobileAppleCrypto, "DSA is not available")] + public static void PublicPrivateKey_IndependentLifetimes_DSA() + { + X509Certificate2 loaded; + + using (DSA ca = DSA.Create()) + { + ca.ImportParameters(DSATestData.GetDSA1024Params()); + DSAX509SignatureGenerator gen = new DSAX509SignatureGenerator(ca); + X500DistinguishedName dn = new X500DistinguishedName("CN=potatos"); + + CertificateRequest req = new CertificateRequest( + dn, + gen.PublicKey, + HashAlgorithmName.SHA1); + + using (X509Certificate2 cert = req.Create(dn, gen, DateTimeOffset.Now, DateTimeOffset.Now.AddDays(3), new byte[] { 1, 2, 3 })) + using (X509Certificate2 certWithKey = cert.CopyWithPrivateKey(ca)) + { + + loaded = new X509Certificate2(certWithKey.Export(X509ContentType.Pkcs12, "carrots"), "carrots"); + } + } + + using (DSA verifyKey = loaded.GetDSAPublicKey()) + { + byte[] signature; + byte[] data = RandomNumberGenerator.GetBytes(20); + + using (DSA signingKey = loaded.GetDSAPrivateKey()) + { + loaded.Dispose(); + signature = signingKey.CreateSignature(data); + } + + Assert.True(verifyKey.VerifySignature(data, signature), nameof(verifyKey.VerifySignature)); + } + } + [Fact] public static void RaceDisposeAndKeyAccess() { From 6d35e39f4f249c627c11586f4769361bde0ed62d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 17:14:57 -0800 Subject: [PATCH 583/783] [release/8.0-staging] UInt64.CreateSaturating truncates instead of saturates (#97047) * UInt64.CreateSaturating truncates instead of saturates * Update src/libraries/System.Private.CoreLib/src/System/Int128.cs --------- Co-authored-by: pedrobsaila Co-authored-by: Stephen Toub --- src/libraries/System.Private.CoreLib/src/System/Int128.cs | 3 ++- .../System.Runtime/tests/System/UInt64Tests.GenericMath.cs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Int128.cs b/src/libraries/System.Private.CoreLib/src/System/Int128.cs index 50dce177e17135..fae7c1b441457b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int128.cs @@ -1899,7 +1899,8 @@ static bool INumberBase.TryConvertToSaturating(Int128 value, [Ma } else if (typeof(TOther) == typeof(ulong)) { - ulong actualResult = (value <= 0) ? ulong.MinValue : (ulong)value; + ulong actualResult = (value >= ulong.MaxValue) ? ulong.MaxValue : + (value <= ulong.MinValue) ? ulong.MinValue : (ulong)value; result = (TOther)(object)actualResult; return true; } diff --git a/src/libraries/System.Runtime/tests/System/UInt64Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System/UInt64Tests.GenericMath.cs index 89639038fd4eeb..614dd54b10255e 100644 --- a/src/libraries/System.Runtime/tests/System/UInt64Tests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System/UInt64Tests.GenericMath.cs @@ -1642,6 +1642,7 @@ public static void CreateSaturatingFromInt128Test() Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating(Int128.MaxValue)); Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Int128.MinValue)); Assert.Equal((ulong)0x0000_0000_0000_0000, NumberBaseHelper.CreateSaturating(Int128.NegativeOne)); + Assert.Equal((ulong)0xFFFF_FFFF_FFFF_FFFF, NumberBaseHelper.CreateSaturating((Int128)ulong.MaxValue + (Int128)10L)); } [Fact] From c987e4f902859d4f80a24b45c5b2a7e4222b6c0e Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Wed, 17 Jan 2024 15:39:20 -0800 Subject: [PATCH 584/783] [release/8.0] Fix Options Source Gen RangeAttribute Thread Safety (#97110) * [release/8.0] Fix Options Source Gen RangeAttribute Thread Safety * Delete un-wanted line --- .../gen/Emitter.cs | 83 ++++++++++--------- .../src/Microsoft.Extensions.Options.csproj | 4 +- .../EmitterWithCustomValidator.netcore.g.cs | 53 +++++++----- .../EmitterWithCustomValidator.netfx.g.cs | 53 +++++++----- ...eneratedAttributesTest.netcore.lang10.g.cs | 71 +++++++++------- ...eneratedAttributesTest.netcore.lang11.g.cs | 71 +++++++++------- .../GeneratedAttributesTest.netfx.lang10.g.cs | 71 +++++++++------- .../GeneratedAttributesTest.netfx.lang11.g.cs | 71 +++++++++------- .../OptionsRuntimeTests.cs | 31 +++++++ .../Baselines/NetCoreApp/Validators.g.cs | 73 ++++++++-------- .../Baselines/NetFX/Validators.g.cs | 73 ++++++++-------- 11 files changed, 374 insertions(+), 280 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs b/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs index 1edc4293785287..1a547dd45ebbb1 100644 --- a/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs +++ b/src/libraries/Microsoft.Extensions.Options/gen/Emitter.cs @@ -382,26 +382,26 @@ public void EmitRangeAttribute(string modifier, string prefix, string className, string initializationString = emitTimeSpanSupport ? """ - if (OperandType == typeof(global::System.TimeSpan)) - { - if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || - !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) - { - throw new global::System.InvalidOperationException(c_minMaxError); - } - Minimum = timeSpanMinimum; - Maximum = timeSpanMaximum; - } - else - { - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); - } + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(MinMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + } """ : """ - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); """; string convertValue = emitTimeSpanSupport ? @@ -470,7 +470,7 @@ public void EmitRangeAttribute(string modifier, string prefix, string className, public {{qualifiedClassName}}(global::System.Type type, string minimum, string maximum) : base() { OperandType = type; - NeedToConvertMinMax = true; + _needToConvertMinMax = true; Minimum = minimum; Maximum = maximum; } @@ -483,33 +483,40 @@ public void EmitRangeAttribute(string modifier, string prefix, string className, public bool ConvertValueInInvariantCulture { get; set; } public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); - private bool NeedToConvertMinMax { get; } - private bool Initialized { get; set; } - private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + private readonly bool _needToConvertMinMax; + private volatile bool _initialized; + private readonly object _lock = new(); + private const string MinMaxError = "The minimum and maximum values must be set to valid values."; public override bool IsValid(object? value) { - if (!Initialized) + if (!_initialized) { - if (Minimum is null || Maximum is null) - { - throw new global::System.InvalidOperationException(c_minMaxError); - } - if (NeedToConvertMinMax) + lock (_lock) { - System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + if (!_initialized) + { + if (Minimum is null || Maximum is null) + { + throw new global::System.InvalidOperationException(MinMaxError); + } + if (_needToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; {{initializationString}} + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + _initialized = true; + } } - int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); - if (cmp > 0) - { - throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); - } - else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) - { - throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); - } - Initialized = true; } if (value is null or string { Length: 0 }) diff --git a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj index de066111eb5797..e35606898e3914 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj +++ b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj @@ -4,8 +4,8 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.1;netstandard2.0;$(NetFrameworkMinimum) true true - false - 1 + true + 2 Provides a strongly typed way of specifying and accessing settings using dependency injection. diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netcore.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netcore.g.cs index 38bacf966df052..b36fff7e49060b 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netcore.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netcore.g.cs @@ -84,7 +84,7 @@ public __SourceGen__RangeAttribute(double minimum, double maximum) : base() public __SourceGen__RangeAttribute(global::System.Type type, string minimum, string maximum) : base() { OperandType = type; - NeedToConvertMinMax = true; + _needToConvertMinMax = true; Minimum = minimum; Maximum = maximum; } @@ -97,34 +97,41 @@ public __SourceGen__RangeAttribute(global::System.Type type, string minimum, str public bool ConvertValueInInvariantCulture { get; set; } public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); - private bool NeedToConvertMinMax { get; } - private bool Initialized { get; set; } - private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + private readonly bool _needToConvertMinMax; + private volatile bool _initialized; + private readonly object _lock = new(); + private const string MinMaxError = "The minimum and maximum values must be set to valid values."; public override bool IsValid(object? value) { - if (!Initialized) + if (!_initialized) { - if (Minimum is null || Maximum is null) + lock (_lock) { - throw new global::System.InvalidOperationException(c_minMaxError); + if (!_initialized) + { + if (Minimum is null || Maximum is null) + { + throw new global::System.InvalidOperationException(MinMaxError); + } + if (_needToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + _initialized = true; + } } - if (NeedToConvertMinMax) - { - System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); - } - int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); - if (cmp > 0) - { - throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); - } - else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) - { - throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); - } - Initialized = true; } if (value is null or string { Length: 0 }) diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netfx.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netfx.g.cs index fe77e3e6bd924a..1fa2f9c2e25770 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netfx.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/EmitterWithCustomValidator.netfx.g.cs @@ -82,7 +82,7 @@ public __SourceGen__RangeAttribute(double minimum, double maximum) : base() public __SourceGen__RangeAttribute(global::System.Type type, string minimum, string maximum) : base() { OperandType = type; - NeedToConvertMinMax = true; + _needToConvertMinMax = true; Minimum = minimum; Maximum = maximum; } @@ -95,34 +95,41 @@ public __SourceGen__RangeAttribute(global::System.Type type, string minimum, str public bool ConvertValueInInvariantCulture { get; set; } public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); - private bool NeedToConvertMinMax { get; } - private bool Initialized { get; set; } - private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + private readonly bool _needToConvertMinMax; + private volatile bool _initialized; + private readonly object _lock = new(); + private const string MinMaxError = "The minimum and maximum values must be set to valid values."; public override bool IsValid(object? value) { - if (!Initialized) + if (!_initialized) { - if (Minimum is null || Maximum is null) + lock (_lock) { - throw new global::System.InvalidOperationException(c_minMaxError); + if (!_initialized) + { + if (Minimum is null || Maximum is null) + { + throw new global::System.InvalidOperationException(MinMaxError); + } + if (_needToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + _initialized = true; + } } - if (NeedToConvertMinMax) - { - System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); - } - int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); - if (cmp > 0) - { - throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); - } - else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) - { - throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); - } - Initialized = true; } if (value is null or string { Length: 0 }) diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang10.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang10.g.cs index 7cf1fe61e1a94b..789d299cf93c5a 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang10.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang10.g.cs @@ -410,7 +410,7 @@ public __SourceGen__2C497155_RangeAttribute(double minimum, double maximum) : ba public __SourceGen__2C497155_RangeAttribute(global::System.Type type, string minimum, string maximum) : base() { OperandType = type; - NeedToConvertMinMax = true; + _needToConvertMinMax = true; Minimum = minimum; Maximum = maximum; } @@ -423,47 +423,54 @@ public __SourceGen__2C497155_RangeAttribute(global::System.Type type, string min public bool ConvertValueInInvariantCulture { get; set; } public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); - private bool NeedToConvertMinMax { get; } - private bool Initialized { get; set; } - private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + private readonly bool _needToConvertMinMax; + private volatile bool _initialized; + private readonly object _lock = new(); + private const string MinMaxError = "The minimum and maximum values must be set to valid values."; public override bool IsValid(object? value) { - if (!Initialized) + if (!_initialized) { - if (Minimum is null || Maximum is null) + lock (_lock) { - throw new global::System.InvalidOperationException(c_minMaxError); - } - if (NeedToConvertMinMax) - { - System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - if (OperandType == typeof(global::System.TimeSpan)) + if (!_initialized) { - if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || - !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException(c_minMaxError); + throw new global::System.InvalidOperationException(MinMaxError); } - Minimum = timeSpanMinimum; - Maximum = timeSpanMaximum; - } - else - { - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + if (_needToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(MinMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + } + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + _initialized = true; } } - int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); - if (cmp > 0) - { - throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); - } - else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) - { - throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); - } - Initialized = true; } if (value is null or string { Length: 0 }) diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang11.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang11.g.cs index f7bba046033420..60d511f2e83561 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang11.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netcore.lang11.g.cs @@ -410,7 +410,7 @@ public __SourceGen__RangeAttribute(double minimum, double maximum) : base() public __SourceGen__RangeAttribute(global::System.Type type, string minimum, string maximum) : base() { OperandType = type; - NeedToConvertMinMax = true; + _needToConvertMinMax = true; Minimum = minimum; Maximum = maximum; } @@ -423,47 +423,54 @@ public __SourceGen__RangeAttribute(global::System.Type type, string minimum, str public bool ConvertValueInInvariantCulture { get; set; } public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); - private bool NeedToConvertMinMax { get; } - private bool Initialized { get; set; } - private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + private readonly bool _needToConvertMinMax; + private volatile bool _initialized; + private readonly object _lock = new(); + private const string MinMaxError = "The minimum and maximum values must be set to valid values."; public override bool IsValid(object? value) { - if (!Initialized) + if (!_initialized) { - if (Minimum is null || Maximum is null) + lock (_lock) { - throw new global::System.InvalidOperationException(c_minMaxError); - } - if (NeedToConvertMinMax) - { - System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - if (OperandType == typeof(global::System.TimeSpan)) + if (!_initialized) { - if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || - !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException(c_minMaxError); + throw new global::System.InvalidOperationException(MinMaxError); } - Minimum = timeSpanMinimum; - Maximum = timeSpanMaximum; - } - else - { - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + if (_needToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(MinMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + } + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + _initialized = true; } } - int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); - if (cmp > 0) - { - throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); - } - else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) - { - throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); - } - Initialized = true; } if (value is null or string { Length: 0 }) diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang10.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang10.g.cs index 4b28eb159d147b..9c20532b17631d 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang10.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang10.g.cs @@ -325,7 +325,7 @@ public __SourceGen__2C497155_RangeAttribute(double minimum, double maximum) : ba public __SourceGen__2C497155_RangeAttribute(global::System.Type type, string minimum, string maximum) : base() { OperandType = type; - NeedToConvertMinMax = true; + _needToConvertMinMax = true; Minimum = minimum; Maximum = maximum; } @@ -338,47 +338,54 @@ public __SourceGen__2C497155_RangeAttribute(global::System.Type type, string min public bool ConvertValueInInvariantCulture { get; set; } public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); - private bool NeedToConvertMinMax { get; } - private bool Initialized { get; set; } - private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + private readonly bool _needToConvertMinMax; + private volatile bool _initialized; + private readonly object _lock = new(); + private const string MinMaxError = "The minimum and maximum values must be set to valid values."; public override bool IsValid(object? value) { - if (!Initialized) + if (!_initialized) { - if (Minimum is null || Maximum is null) + lock (_lock) { - throw new global::System.InvalidOperationException(c_minMaxError); - } - if (NeedToConvertMinMax) - { - System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - if (OperandType == typeof(global::System.TimeSpan)) + if (!_initialized) { - if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || - !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException(c_minMaxError); + throw new global::System.InvalidOperationException(MinMaxError); } - Minimum = timeSpanMinimum; - Maximum = timeSpanMaximum; - } - else - { - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + if (_needToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(MinMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + } + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + _initialized = true; } } - int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); - if (cmp > 0) - { - throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); - } - else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) - { - throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); - } - Initialized = true; } if (value is null or string { Length: 0 }) diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang11.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang11.g.cs index 4c300abc6d05bc..c563c65e821903 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang11.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Baselines/GeneratedAttributesTest.netfx.lang11.g.cs @@ -325,7 +325,7 @@ public __SourceGen__RangeAttribute(double minimum, double maximum) : base() public __SourceGen__RangeAttribute(global::System.Type type, string minimum, string maximum) : base() { OperandType = type; - NeedToConvertMinMax = true; + _needToConvertMinMax = true; Minimum = minimum; Maximum = maximum; } @@ -338,47 +338,54 @@ public __SourceGen__RangeAttribute(global::System.Type type, string minimum, str public bool ConvertValueInInvariantCulture { get; set; } public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); - private bool NeedToConvertMinMax { get; } - private bool Initialized { get; set; } - private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + private readonly bool _needToConvertMinMax; + private volatile bool _initialized; + private readonly object _lock = new(); + private const string MinMaxError = "The minimum and maximum values must be set to valid values."; public override bool IsValid(object? value) { - if (!Initialized) + if (!_initialized) { - if (Minimum is null || Maximum is null) + lock (_lock) { - throw new global::System.InvalidOperationException(c_minMaxError); - } - if (NeedToConvertMinMax) - { - System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - if (OperandType == typeof(global::System.TimeSpan)) + if (!_initialized) { - if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || - !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException(c_minMaxError); + throw new global::System.InvalidOperationException(MinMaxError); } - Minimum = timeSpanMinimum; - Maximum = timeSpanMaximum; - } - else - { - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + if (_needToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(MinMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + } + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + _initialized = true; } } - int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); - if (cmp > 0) - { - throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); - } - else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) - { - throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); - } - Initialized = true; } if (value is null or string { Length: 0 }) diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs index 4c701e4b9f498f..8487570d208b2b 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs @@ -7,6 +7,7 @@ using System.ComponentModel.DataAnnotations; using System.Globalization; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Xunit; @@ -399,6 +400,23 @@ public void TestCustomGeneratedAttributes() Assert.Equal(results.Count(), generatorResult.Failures.Count()); } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + public void TestGeneratedRangeAttributeThreadSafety() + { + OptionsWithTimeSpanRangeAttribute options = new OptionsWithTimeSpanRangeAttribute() { Name = "T1", Period = TimeSpan.FromHours(1) }; + TimeSpanRangeAttributeValidator validator = new TimeSpanRangeAttributeValidator(); + + var barrier = new Barrier(8); + Task.WaitAll( + (from i in Enumerable.Range(0, barrier.ParticipantCount) + select Task.Factory.StartNew(() => + { + barrier.SignalAndWait(); + ValidateOptionsResult result = validator.Validate("T1", options); + Assert.True(result.Succeeded); + }, TaskCreationOptions.LongRunning)).ToArray()); + } } public class FakeCount(int count) { public int Count { get { return count; } } } @@ -605,4 +623,17 @@ public partial class NewAttributesValidator : IValidateOptions + { + } } diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs index 93c101431004ca..81a68c3901647c 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetCoreApp/Validators.g.cs @@ -1,4 +1,4 @@ - + // #nullable enable #pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103 @@ -2195,7 +2195,7 @@ public __SourceGen__RangeAttribute(double minimum, double maximum) : base() public __SourceGen__RangeAttribute(global::System.Type type, string minimum, string maximum) : base() { OperandType = type; - NeedToConvertMinMax = true; + _needToConvertMinMax = true; Minimum = minimum; Maximum = maximum; } @@ -2208,47 +2208,54 @@ public __SourceGen__RangeAttribute(global::System.Type type, string minimum, str public bool ConvertValueInInvariantCulture { get; set; } public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); - private bool NeedToConvertMinMax { get; } - private bool Initialized { get; set; } - private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + private readonly bool _needToConvertMinMax; + private volatile bool _initialized; + private readonly object _lock = new(); + private const string MinMaxError = "The minimum and maximum values must be set to valid values."; public override bool IsValid(object? value) { - if (!Initialized) + if (!_initialized) { - if (Minimum is null || Maximum is null) - { - throw new global::System.InvalidOperationException(c_minMaxError); - } - if (NeedToConvertMinMax) + lock (_lock) { - System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - if (OperandType == typeof(global::System.TimeSpan)) + if (!_initialized) { - if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || - !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException(c_minMaxError); + throw new global::System.InvalidOperationException(MinMaxError); } - Minimum = timeSpanMinimum; - Maximum = timeSpanMaximum; - } - else - { - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + if (_needToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(MinMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + } + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + _initialized = true; } } - int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); - if (cmp > 0) - { - throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); - } - else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) - { - throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); - } - Initialized = true; } if (value is null or string { Length: 0 }) diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs index 3c9f86fd84f8a2..7c388c228a7604 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Baselines/NetFX/Validators.g.cs @@ -1,4 +1,4 @@ - + // #nullable enable #pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103 @@ -2087,7 +2087,7 @@ public __SourceGen__RangeAttribute(double minimum, double maximum) : base() public __SourceGen__RangeAttribute(global::System.Type type, string minimum, string maximum) : base() { OperandType = type; - NeedToConvertMinMax = true; + _needToConvertMinMax = true; Minimum = minimum; Maximum = maximum; } @@ -2100,47 +2100,54 @@ public __SourceGen__RangeAttribute(global::System.Type type, string minimum, str public bool ConvertValueInInvariantCulture { get; set; } public override string FormatErrorMessage(string name) => string.Format(global::System.Globalization.CultureInfo.CurrentCulture, GetValidationErrorMessage(), name, Minimum, Maximum); - private bool NeedToConvertMinMax { get; } - private bool Initialized { get; set; } - private const string c_minMaxError = "The minimum and maximum values must be set to valid values."; + private readonly bool _needToConvertMinMax; + private volatile bool _initialized; + private readonly object _lock = new(); + private const string MinMaxError = "The minimum and maximum values must be set to valid values."; public override bool IsValid(object? value) { - if (!Initialized) + if (!_initialized) { - if (Minimum is null || Maximum is null) - { - throw new global::System.InvalidOperationException(c_minMaxError); - } - if (NeedToConvertMinMax) + lock (_lock) { - System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; - if (OperandType == typeof(global::System.TimeSpan)) + if (!_initialized) { - if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || - !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + if (Minimum is null || Maximum is null) { - throw new global::System.InvalidOperationException(c_minMaxError); + throw new global::System.InvalidOperationException(MinMaxError); } - Minimum = timeSpanMinimum; - Maximum = timeSpanMaximum; - } - else - { - Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); - Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(c_minMaxError); + if (_needToConvertMinMax) + { + System.Globalization.CultureInfo culture = ParseLimitsInInvariantCulture ? global::System.Globalization.CultureInfo.InvariantCulture : global::System.Globalization.CultureInfo.CurrentCulture; + if (OperandType == typeof(global::System.TimeSpan)) + { + if (!global::System.TimeSpan.TryParse((string)Minimum, culture, out global::System.TimeSpan timeSpanMinimum) || + !global::System.TimeSpan.TryParse((string)Maximum, culture, out global::System.TimeSpan timeSpanMaximum)) + { + throw new global::System.InvalidOperationException(MinMaxError); + } + Minimum = timeSpanMinimum; + Maximum = timeSpanMaximum; + } + else + { + Minimum = ConvertValue(Minimum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + Maximum = ConvertValue(Maximum, culture) ?? throw new global::System.InvalidOperationException(MinMaxError); + } + } + int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); + if (cmp > 0) + { + throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); + } + else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) + { + throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); + } + _initialized = true; } } - int cmp = ((global::System.IComparable)Minimum).CompareTo((global::System.IComparable)Maximum); - if (cmp > 0) - { - throw new global::System.InvalidOperationException("The maximum value '{Maximum}' must be greater than or equal to the minimum value '{Minimum}'."); - } - else if (cmp == 0 && (MinimumIsExclusive || MaximumIsExclusive)) - { - throw new global::System.InvalidOperationException("Cannot use exclusive bounds when the maximum value is equal to the minimum value."); - } - Initialized = true; } if (value is null or string { Length: 0 }) From e24179e775a2666dd4b7e0154f95305308c6a400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 19 Jan 2024 09:35:16 +0100 Subject: [PATCH 585/783] [release/8.0-staging] [browser] Use whole assembly name when looking for already loaded assemblies (#97144) --- .../Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs | 4 ++++ .../TestAppScenarios/LazyLoadingTests.cs | 2 +- src/mono/wasm/runtime/lazyLoading.ts | 2 +- src/mono/wasm/runtime/loader/assets.ts | 2 +- .../WasmBasicTestApp/{ => App}/AppSettingsTest.cs | 0 .../WasmBasicTestApp/{ => App}/Common/Program.cs | 0 .../WasmBasicTestApp/{ => App}/Common/TestOutput.cs | 0 .../WasmBasicTestApp/{ => App}/LazyLoadingTest.cs | 3 +-- .../{ => App}/LibraryInitializerTest.cs | 0 .../{ => App}/Properties/AssemblyInfo.cs | 0 .../{ => App}/SatelliteAssembliesTest.cs | 0 .../{ => App}/WasmBasicTestApp.csproj | 6 +++++- .../{ => App}/runtimeconfig.template.json | 0 .../WasmBasicTestApp/{ => App}/words.es-ES.resx | 0 .../testassets/WasmBasicTestApp/{ => App}/words.resx | 0 .../{ => App}/wwwroot/WasmBasicTestApp.lib.module.js | 0 .../{ => App}/wwwroot/appsettings.Development.json | 0 .../{ => App}/wwwroot/appsettings.Production.json | 0 .../{ => App}/wwwroot/appsettings.json | 0 .../WasmBasicTestApp/{ => App}/wwwroot/index.html | 0 .../WasmBasicTestApp/{ => App}/wwwroot/main.js | 2 +- .../wasm/testassets/WasmBasicTestApp/Library/Json.cs | 11 +++++++++++ .../testassets/WasmBasicTestApp/Library/Json.csproj | 8 ++++++++ 23 files changed, 33 insertions(+), 7 deletions(-) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/AppSettingsTest.cs (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/Common/Program.cs (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/Common/TestOutput.cs (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/LazyLoadingTest.cs (91%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/LibraryInitializerTest.cs (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/Properties/AssemblyInfo.cs (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/SatelliteAssembliesTest.cs (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/WasmBasicTestApp.csproj (70%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/runtimeconfig.template.json (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/words.es-ES.resx (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/words.resx (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/wwwroot/WasmBasicTestApp.lib.module.js (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/wwwroot/appsettings.Development.json (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/wwwroot/appsettings.Production.json (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/wwwroot/appsettings.json (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/wwwroot/index.html (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{ => App}/wwwroot/main.js (97%) create mode 100644 src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.cs create mode 100644 src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.csproj diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs index 444d70228b08fa..dc6fb9b490e7f3 100644 --- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs @@ -30,6 +30,10 @@ protected void CopyTestAsset(string assetName, string generatedProjectNamePrefix LogPath = Path.Combine(s_buildEnv.LogRootPath, Id); Utils.DirectoryCopy(Path.Combine(BuildEnvironment.TestAssetsPath, assetName), Path.Combine(_projectDir!)); + + // WasmBasicTestApp consists of App + Library projects + if (assetName == "WasmBasicTestApp") + _projectDir = Path.Combine(_projectDir!, "App"); } protected void BuildProject(string configuration) diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LazyLoadingTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LazyLoadingTests.cs index d2219e9f9e50da..8f37a47e18860a 100644 --- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LazyLoadingTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LazyLoadingTests.cs @@ -42,6 +42,6 @@ public async Task FailOnMissingLazyAssembly() BrowserQueryString: new Dictionary { ["loadRequiredAssembly"] = "false" }, ExpectedExitCode: 1 )); - Assert.True(result.ConsoleOutput.Any(m => m.Contains("Could not load file or assembly") && m.Contains("System.Text.Json")), "The lazy loading test didn't emit expected error message"); + Assert.True(result.ConsoleOutput.Any(m => m.Contains("Could not load file or assembly") && m.Contains("Json")), "The lazy loading test didn't emit expected error message"); } } diff --git a/src/mono/wasm/runtime/lazyLoading.ts b/src/mono/wasm/runtime/lazyLoading.ts index 59c153a9d62365..55bcfd67101e8c 100644 --- a/src/mono/wasm/runtime/lazyLoading.ts +++ b/src/mono/wasm/runtime/lazyLoading.ts @@ -21,7 +21,7 @@ export async function loadLazyAssembly(assemblyNameToLoad: string): Promise f.includes(assemblyNameToLoad))) { + if (loaderHelpers.loadedAssemblies.includes(assemblyNameToLoad)) { return false; } diff --git a/src/mono/wasm/runtime/loader/assets.ts b/src/mono/wasm/runtime/loader/assets.ts index 02e05b1f8a9622..8730988193ffd0 100644 --- a/src/mono/wasm/runtime/loader/assets.ts +++ b/src/mono/wasm/runtime/loader/assets.ts @@ -598,7 +598,7 @@ function download_resource(asset: AssetEntryInternal): LoadingResource { totalResources.add(asset.name!); response.response.then(() => { if (asset.behavior == "assembly") { - loaderHelpers.loadedAssemblies.push(asset.resolvedUrl!); + loaderHelpers.loadedAssemblies.push(asset.name); } resourcesLoaded++; diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/AppSettingsTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/AppSettingsTest.cs similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/AppSettingsTest.cs rename to src/mono/wasm/testassets/WasmBasicTestApp/App/AppSettingsTest.cs diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/Common/Program.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/Common/Program.cs similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/Common/Program.cs rename to src/mono/wasm/testassets/WasmBasicTestApp/App/Common/Program.cs diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/Common/TestOutput.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/Common/TestOutput.cs similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/Common/TestOutput.cs rename to src/mono/wasm/testassets/WasmBasicTestApp/App/Common/TestOutput.cs diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/LazyLoadingTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs similarity index 91% rename from src/mono/wasm/testassets/WasmBasicTestApp/LazyLoadingTest.cs rename to src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs index 0d68b1216816c3..5aba6b1ee48a0f 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/LazyLoadingTest.cs +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Library; using System; using System.Text.Json; using System.Runtime.InteropServices.JavaScript; @@ -15,6 +16,4 @@ public static void Run() var text = JsonSerializer.Serialize(new Person("John", "Doe")); TestOutput.WriteLine(text); } - - public record Person(string FirstName, string LastName); } diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/LibraryInitializerTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/LibraryInitializerTest.cs similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/LibraryInitializerTest.cs rename to src/mono/wasm/testassets/WasmBasicTestApp/App/LibraryInitializerTest.cs diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/Properties/AssemblyInfo.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/Properties/AssemblyInfo.cs similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/Properties/AssemblyInfo.cs rename to src/mono/wasm/testassets/WasmBasicTestApp/App/Properties/AssemblyInfo.cs diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/SatelliteAssembliesTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/SatelliteAssembliesTest.cs similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/SatelliteAssembliesTest.cs rename to src/mono/wasm/testassets/WasmBasicTestApp/App/SatelliteAssembliesTest.cs diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj b/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj similarity index 70% rename from src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj rename to src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj index 761ac6354ce861..a3b9364d4fce80 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj @@ -8,6 +8,10 @@ - + + + + + diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/runtimeconfig.template.json b/src/mono/wasm/testassets/WasmBasicTestApp/App/runtimeconfig.template.json similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/runtimeconfig.template.json rename to src/mono/wasm/testassets/WasmBasicTestApp/App/runtimeconfig.template.json diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/words.es-ES.resx b/src/mono/wasm/testassets/WasmBasicTestApp/App/words.es-ES.resx similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/words.es-ES.resx rename to src/mono/wasm/testassets/WasmBasicTestApp/App/words.es-ES.resx diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/words.resx b/src/mono/wasm/testassets/WasmBasicTestApp/App/words.resx similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/words.resx rename to src/mono/wasm/testassets/WasmBasicTestApp/App/words.resx diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/wwwroot/WasmBasicTestApp.lib.module.js b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/WasmBasicTestApp.lib.module.js similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/wwwroot/WasmBasicTestApp.lib.module.js rename to src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/WasmBasicTestApp.lib.module.js diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/wwwroot/appsettings.Development.json b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/appsettings.Development.json similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/wwwroot/appsettings.Development.json rename to src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/appsettings.Development.json diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/wwwroot/appsettings.Production.json b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/appsettings.Production.json similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/wwwroot/appsettings.Production.json rename to src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/appsettings.Production.json diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/wwwroot/appsettings.json b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/appsettings.json similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/wwwroot/appsettings.json rename to src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/appsettings.json diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/wwwroot/index.html b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/index.html similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/wwwroot/index.html rename to src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/index.html diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/wwwroot/main.js b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js similarity index 97% rename from src/mono/wasm/testassets/WasmBasicTestApp/wwwroot/main.js rename to src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js index 8d537cbdfb4041..076f37a62a6d87 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/wwwroot/main.js +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js @@ -79,7 +79,7 @@ try { break; case "LazyLoadingTest": if (params.get("loadRequiredAssembly") !== "false") { - await INTERNAL.loadLazyAssembly(`System.Text.Json${assemblyExtension}`); + await INTERNAL.loadLazyAssembly(`Json${assemblyExtension}`); } exports.LazyLoadingTest.Run(); exit(0); diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.cs b/src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.cs new file mode 100644 index 00000000000000..cd496b96a3fc9e --- /dev/null +++ b/src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.cs @@ -0,0 +1,11 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Library; + +public record Person(string FirstName, string LastName); + +[JsonSerializable(typeof(Person))] +public partial class PersonJsonSerializerContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.csproj b/src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.csproj new file mode 100644 index 00000000000000..87c4a405521efe --- /dev/null +++ b/src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.csproj @@ -0,0 +1,8 @@ + + + + net8.0 + Library + true + + From 5e9e29f6bb2e76f24bb80e72d39813ee6d3909a1 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Tue, 23 Jan 2024 15:50:09 +0100 Subject: [PATCH 586/783] [release/8.0][browser] BrowserWebSocket.ReceiveAsync after server initiated close (#97002) --- .../Net/WebSockets/WebSocketValidate.cs | 11 ++- .../Handlers/EchoWebSocketHandler.cs | 17 +++- .../BrowserWebSockets/BrowserWebSocket.cs | 87 ++++++++++++------- .../tests/CloseTest.cs | 81 ++++++++++++++--- .../tests/SendReceiveTest.cs | 2 +- src/mono/wasm/runtime/web-socket.ts | 68 ++++++++++++--- 6 files changed, 205 insertions(+), 61 deletions(-) diff --git a/src/libraries/Common/src/System/Net/WebSockets/WebSocketValidate.cs b/src/libraries/Common/src/System/Net/WebSockets/WebSocketValidate.cs index 7c97c082d26f89..e087677be4608e 100644 --- a/src/libraries/Common/src/System/Net/WebSockets/WebSocketValidate.cs +++ b/src/libraries/Common/src/System/Net/WebSockets/WebSocketValidate.cs @@ -23,10 +23,15 @@ internal static partial class WebSocketValidate internal const int MaxDeflateWindowBits = 15; internal const int MaxControlFramePayloadLength = 123; +#if TARGET_BROWSER + private const int ValidCloseStatusCodesFrom = 3000; + private const int ValidCloseStatusCodesTo = 4999; +#else private const int CloseStatusCodeAbort = 1006; private const int CloseStatusCodeFailedTLSHandshake = 1015; private const int InvalidCloseStatusCodesFrom = 0; private const int InvalidCloseStatusCodesTo = 999; +#endif // [0x21, 0x7E] except separators "()<>@,;:\\\"/[]?={} ". private static readonly SearchValues s_validSubprotocolChars = @@ -84,11 +89,15 @@ internal static void ValidateCloseStatus(WebSocketCloseStatus closeStatus, strin } int closeStatusCode = (int)closeStatus; - +#if TARGET_BROWSER + // as defined in https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close#code + if (closeStatus != WebSocketCloseStatus.NormalClosure && (closeStatusCode < ValidCloseStatusCodesFrom || closeStatusCode > ValidCloseStatusCodesTo)) +#else if ((closeStatusCode >= InvalidCloseStatusCodesFrom && closeStatusCode <= InvalidCloseStatusCodesTo) || closeStatusCode == CloseStatusCodeAbort || closeStatusCode == CloseStatusCodeFailedTLSHandshake) +#endif { // CloseStatus 1006 means Aborted - this will never appear on the wire and is reflected by calling WebSocket.Abort throw new ArgumentException(SR.Format(SR.net_WebSockets_InvalidCloseStatusCode, diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHandler.cs b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHandler.cs index f4e5562600015d..8304f2d1156072 100644 --- a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHandler.cs +++ b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHandler.cs @@ -24,11 +24,11 @@ public static async Task InvokeAsync(HttpContext context) if (context.Request.QueryString.HasValue && context.Request.QueryString.Value.Contains("delay10sec")) { - Thread.Sleep(10000); + await Task.Delay(10000); } else if (context.Request.QueryString.HasValue && context.Request.QueryString.Value.Contains("delay20sec")) { - Thread.Sleep(20000); + await Task.Delay(20000); } try @@ -124,14 +124,15 @@ await socket.CloseAsync( } bool sendMessage = false; + string receivedMessage = null; if (receiveResult.MessageType == WebSocketMessageType.Text) { - string receivedMessage = Encoding.UTF8.GetString(receiveBuffer, 0, offset); + receivedMessage = Encoding.UTF8.GetString(receiveBuffer, 0, offset); if (receivedMessage == ".close") { await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, CancellationToken.None); } - if (receivedMessage == ".shutdown") + else if (receivedMessage == ".shutdown") { await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, CancellationToken.None); } @@ -161,6 +162,14 @@ await socket.SendAsync( !replyWithPartialMessages, CancellationToken.None); } + if (receivedMessage == ".closeafter") + { + await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, CancellationToken.None); + } + else if (receivedMessage == ".shutdownafter") + { + await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, CancellationToken.None); + } } } } diff --git a/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserWebSocket.cs b/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserWebSocket.cs index 121fa8595c65d5..879d45ca0da57c 100644 --- a/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserWebSocket.cs +++ b/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserWebSocket.cs @@ -24,6 +24,8 @@ internal sealed class BrowserWebSocket : WebSocket private WebSocketState _state; private bool _disposed; private bool _aborted; + private bool _closeReceived; + private bool _closeSent; private int[] responseStatus = new int[3]; private MemoryHandle? responseStatusHandle; @@ -37,7 +39,7 @@ public override WebSocketState State lock (_thisLock) { #endif - if (_innerWebSocket == null || _disposed || (_state != WebSocketState.Connecting && _state != WebSocketState.Open && _state != WebSocketState.CloseSent)) + if (_innerWebSocket == null || _disposed || _state == WebSocketState.Aborted || _state == WebSocketState.Closed) { return _state; } @@ -46,15 +48,9 @@ public override WebSocketState State #endif #if FEATURE_WASM_THREADS - return FastState = _innerWebSocket!.SynchronizationContext.Send(static (BrowserWebSocket self) => - { - lock (self._thisLock) - { - return GetReadyState(self._innerWebSocket!); - } //lock - }, this); + return _innerWebSocket!.SynchronizationContext.Send(GetReadyState, this); #else - return FastState = GetReadyState(_innerWebSocket!); + return GetReadyState(this); #endif } } @@ -148,7 +144,7 @@ public override Task SendAsync(ArraySegment buffer, WebSocketMessageType m ThrowIfDisposed(); // fast check of previous _state instead of GetReadyState(), the readyState would be validated on JS side - if (FastState != WebSocketState.Open) + if (FastState != WebSocketState.Open && FastState != WebSocketState.CloseReceived) { throw new InvalidOperationException(SR.net_WebSockets_NotConnected); } @@ -240,7 +236,7 @@ public override Task CloseOutputAsync(WebSocketCloseStatus closeStatus, string? { throw new WebSocketException(WebSocketError.InvalidState, SR.Format(SR.net_WebSockets_InvalidState, state, "Connecting, Open, CloseSent, Aborted")); } - if(state != WebSocketState.Open && state != WebSocketState.Connecting && state != WebSocketState.Aborted) + if (state == WebSocketState.CloseSent) { return Task.CompletedTask; } @@ -280,10 +276,6 @@ public override Task CloseAsync(WebSocketCloseStatus closeStatus, string? status { throw new WebSocketException(WebSocketError.InvalidState, SR.Format(SR.net_WebSockets_InvalidState, state, "Connecting, Open, CloseSent, Aborted")); } - if (state != WebSocketState.Open && state != WebSocketState.Connecting && state != WebSocketState.Aborted && state != WebSocketState.CloseSent) - { - return Task.CompletedTask; - } #if FEATURE_WASM_THREADS promise = CloseAsyncCore(closeStatus, statusDescription, state != WebSocketState.Aborted, cancellationToken); @@ -387,12 +379,13 @@ private void CreateCore(Uri uri, List? requestedSubProtocols) string[]? subProtocols = requestedSubProtocols?.ToArray(); var onClose = (int code, string reason) => { - _closeStatus = (WebSocketCloseStatus)code; - _closeStatusDescription = reason; #if FEATURE_WASM_THREADS lock (_thisLock) { #endif + _closeStatus = (WebSocketCloseStatus)code; + _closeStatusDescription = reason; + _closeReceived = true; WebSocketState state = State; if (state == WebSocketState.Connecting || state == WebSocketState.Open || state == WebSocketState.CloseSent) { @@ -545,6 +538,8 @@ private static WebSocketReceiveResult ConvertResponse(BrowserWebSocket self) WebSocketMessageType messageType = (WebSocketMessageType)self.responseStatus[typeIndex]; if (messageType == WebSocketMessageType.Close) { + self._closeReceived = true; + self.FastState = self._closeSent ? WebSocketState.Closed : WebSocketState.CloseReceived; return new WebSocketReceiveResult(self.responseStatus[countIndex], messageType, self.responseStatus[endIndex] != 0, self.CloseStatus, self.CloseStatusDescription); } return new WebSocketReceiveResult(self.responseStatus[countIndex], messageType, self.responseStatus[endIndex] != 0); @@ -552,8 +547,12 @@ private static WebSocketReceiveResult ConvertResponse(BrowserWebSocket self) private async Task CloseAsyncCore(WebSocketCloseStatus closeStatus, string? statusDescription, bool waitForCloseReceived, CancellationToken cancellationToken) { - _closeStatus = closeStatus; - _closeStatusDescription = statusDescription; + if (!_closeReceived) + { + _closeStatus = closeStatus; + _closeStatusDescription = statusDescription; + } + _closeSent = true; var closeTask = BrowserInterop.WebSocketClose(_innerWebSocket!, (int)closeStatus, statusDescription, waitForCloseReceived) ?? Task.CompletedTask; await CancelationHelper(closeTask, cancellationToken, FastState).ConfigureAwait(true); @@ -562,6 +561,10 @@ private async Task CloseAsyncCore(WebSocketCloseStatus closeStatus, string? stat lock (_thisLock) { #endif + if (waitForCloseReceived) + { + _closeReceived = true; + } var state = State; if (state == WebSocketState.Open || state == WebSocketState.Connecting || state == WebSocketState.CloseSent) { @@ -614,18 +617,42 @@ private async Task CancelationHelper(Task jsTask, CancellationToken cancellation } } - private static WebSocketState GetReadyState(JSObject innerWebSocket) + private static WebSocketState GetReadyState(BrowserWebSocket self) { - var readyState = BrowserInterop.GetReadyState(innerWebSocket); - // https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState - return readyState switch - { - 0 => WebSocketState.Connecting, // 0 (CONNECTING) - 1 => WebSocketState.Open, // 1 (OPEN) - 2 => WebSocketState.CloseSent, // 2 (CLOSING) - 3 => WebSocketState.Closed, // 3 (CLOSED) - _ => WebSocketState.None - }; +#if FEATURE_WASM_THREADS + lock (self._thisLock) + { +#endif + var readyState = BrowserInterop.GetReadyState(self._innerWebSocket); + // https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState + var st = readyState switch + { + 0 => WebSocketState.Connecting, // 0 (CONNECTING) + 1 => WebSocketState.Open, // 1 (OPEN) + 2 => WebSocketState.CloseSent, // 2 (CLOSING) + 3 => WebSocketState.Closed, // 3 (CLOSED) + _ => WebSocketState.None + }; + if (st == WebSocketState.Closed || st == WebSocketState.CloseSent) + { + if (self._closeReceived && self._closeSent) + { + st = WebSocketState.Closed; + } + else if (self._closeReceived && !self._closeSent) + { + st = WebSocketState.CloseReceived; + } + else if (!self._closeReceived && self._closeSent) + { + st = WebSocketState.CloseSent; + } + } + self.FastState = st; + return st; +#if FEATURE_WASM_THREADS + } //lock +#endif } #endregion diff --git a/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.cs b/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.cs index 9e33810098f7da..6f1e6faa490192 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.cs @@ -33,12 +33,12 @@ public class CloseTest : ClientWebSocketTestBase public CloseTest(ITestOutputHelper output) : base(output) { } - [ActiveIssue("https://github.com/dotnet/runtime/issues/28957")] + [ActiveIssue("https://github.com/dotnet/runtime/issues/28957", typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServersAndBoolean))] public async Task CloseAsync_ServerInitiatedClose_Success(Uri server, bool useCloseOutputAsync) { - const string closeWebSocketMetaCommand = ".close"; + const string shutdownWebSocketMetaCommand = ".shutdown"; using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) { @@ -46,7 +46,7 @@ public async Task CloseAsync_ServerInitiatedClose_Success(Uri server, bool useCl _output.WriteLine("SendAsync starting."); await cws.SendAsync( - WebSocketData.GetBufferFromText(closeWebSocketMetaCommand), + WebSocketData.GetBufferFromText(shutdownWebSocketMetaCommand), WebSocketMessageType.Text, true, cts.Token); @@ -59,26 +59,27 @@ await cws.SendAsync( // Verify received server-initiated close message. Assert.Equal(WebSocketCloseStatus.NormalClosure, recvResult.CloseStatus); - Assert.Equal(closeWebSocketMetaCommand, recvResult.CloseStatusDescription); + Assert.Equal(shutdownWebSocketMetaCommand, recvResult.CloseStatusDescription); Assert.Equal(WebSocketMessageType.Close, recvResult.MessageType); // Verify current websocket state as CloseReceived which indicates only partial close. Assert.Equal(WebSocketState.CloseReceived, cws.State); Assert.Equal(WebSocketCloseStatus.NormalClosure, cws.CloseStatus); - Assert.Equal(closeWebSocketMetaCommand, cws.CloseStatusDescription); + Assert.Equal(shutdownWebSocketMetaCommand, cws.CloseStatusDescription); // Send back close message to acknowledge server-initiated close. _output.WriteLine("Close starting."); + var closeStatus = PlatformDetection.IsNotBrowser ? WebSocketCloseStatus.InvalidMessageType : (WebSocketCloseStatus)3210; await (useCloseOutputAsync ? - cws.CloseOutputAsync(WebSocketCloseStatus.InvalidMessageType, string.Empty, cts.Token) : - cws.CloseAsync(WebSocketCloseStatus.InvalidMessageType, string.Empty, cts.Token)); + cws.CloseOutputAsync(closeStatus, string.Empty, cts.Token) : + cws.CloseAsync(closeStatus, string.Empty, cts.Token)); _output.WriteLine("Close done."); Assert.Equal(WebSocketState.Closed, cws.State); // Verify that there is no follow-up echo close message back from the server by // making sure the close code and message are the same as from the first server close message. Assert.Equal(WebSocketCloseStatus.NormalClosure, cws.CloseStatus); - Assert.Equal(closeWebSocketMetaCommand, cws.CloseStatusDescription); + Assert.Equal(shutdownWebSocketMetaCommand, cws.CloseStatusDescription); } } @@ -233,8 +234,7 @@ public async Task CloseOutputAsync_ClientInitiated_CanReceive_CanClose(Uri serve { var cts = new CancellationTokenSource(TimeOutMilliseconds); - // See issue for Browser websocket differences https://github.com/dotnet/runtime/issues/45538 - var closeStatus = PlatformDetection.IsBrowser ? WebSocketCloseStatus.NormalClosure : WebSocketCloseStatus.InvalidPayloadData; + var closeStatus = PlatformDetection.IsNotBrowser ? WebSocketCloseStatus.InvalidPayloadData : (WebSocketCloseStatus)3210; string closeDescription = "CloseOutputAsync_Client_InvalidPayloadData"; await cws.SendAsync(WebSocketData.GetBufferFromText(message), WebSocketMessageType.Text, true, cts.Token); @@ -262,7 +262,64 @@ public async Task CloseOutputAsync_ClientInitiated_CanReceive_CanClose(Uri serve } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/28957")] + [ActiveIssue("https://github.com/dotnet/runtime/issues/28957", typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] + [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] + public async Task CloseOutputAsync_ServerInitiated_CanReceive(Uri server) + { + string message = "Hello WebSockets!"; + var expectedCloseStatus = WebSocketCloseStatus.NormalClosure; + var expectedCloseDescription = ".shutdownafter"; + + using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + { + var cts = new CancellationTokenSource(TimeOutMilliseconds); + + await cws.SendAsync( + WebSocketData.GetBufferFromText(expectedCloseDescription), + WebSocketMessageType.Text, + true, + cts.Token); + + // Should be able to receive the message echoed by the server. + var recvBuffer = new byte[100]; + var segmentRecv = new ArraySegment(recvBuffer); + WebSocketReceiveResult recvResult = await cws.ReceiveAsync(segmentRecv, cts.Token); + Assert.Equal(expectedCloseDescription.Length, recvResult.Count); + segmentRecv = new ArraySegment(segmentRecv.Array, 0, recvResult.Count); + Assert.Equal(expectedCloseDescription, WebSocketData.GetTextFromBuffer(segmentRecv)); + Assert.Null(recvResult.CloseStatus); + Assert.Null(recvResult.CloseStatusDescription); + + // Should be able to receive a shutdown message. + segmentRecv = new ArraySegment(recvBuffer); + recvResult = await cws.ReceiveAsync(segmentRecv, cts.Token); + Assert.Equal(0, recvResult.Count); + Assert.Equal(expectedCloseStatus, recvResult.CloseStatus); + Assert.Equal(expectedCloseDescription, recvResult.CloseStatusDescription); + + // Verify WebSocket state + Assert.Equal(expectedCloseStatus, cws.CloseStatus); + Assert.Equal(expectedCloseDescription, cws.CloseStatusDescription); + + Assert.Equal(WebSocketState.CloseReceived, cws.State); + + // Should be able to send. + await cws.SendAsync(WebSocketData.GetBufferFromText(message), WebSocketMessageType.Text, true, cts.Token); + + // Cannot change the close status/description with the final close. + var closeStatus = PlatformDetection.IsNotBrowser ? WebSocketCloseStatus.InvalidPayloadData : (WebSocketCloseStatus)3210; + var closeDescription = "CloseOutputAsync_Client_Description"; + + await cws.CloseAsync(closeStatus, closeDescription, cts.Token); + + Assert.Equal(expectedCloseStatus, cws.CloseStatus); + Assert.Equal(expectedCloseDescription, cws.CloseStatusDescription); + Assert.Equal(WebSocketState.Closed, cws.State); + } + } + + [ActiveIssue("https://github.com/dotnet/runtime/issues/28957", typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] public async Task CloseOutputAsync_ServerInitiated_CanSend(Uri server) @@ -299,7 +356,7 @@ await cws.SendAsync( await cws.SendAsync(WebSocketData.GetBufferFromText(message), WebSocketMessageType.Text, true, cts.Token); // Cannot change the close status/description with the final close. - var closeStatus = WebSocketCloseStatus.InvalidPayloadData; + var closeStatus = PlatformDetection.IsNotBrowser ? WebSocketCloseStatus.InvalidPayloadData : (WebSocketCloseStatus)3210; var closeDescription = "CloseOutputAsync_Client_Description"; await cws.CloseAsync(closeStatus, closeDescription, cts.Token); diff --git a/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.cs b/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.cs index 18694fcd97a1a9..f45ed7fd9c14ca 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.cs @@ -249,7 +249,7 @@ public async Task SendAsync_MultipleOutstandingSendOperations_Throws(Uri server) [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] // This will also pass when no exception is thrown. Current implementation doesn't throw. - [ActiveIssue("https://github.com/dotnet/runtime/issues/83517", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/83517", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] public async Task ReceiveAsync_MultipleOutstandingReceiveOperations_Throws(Uri server) { using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) diff --git a/src/mono/wasm/runtime/web-socket.ts b/src/mono/wasm/runtime/web-socket.ts index 7469d27cd7501e..5cf400aca536a9 100644 --- a/src/mono/wasm/runtime/web-socket.ts +++ b/src/mono/wasm/runtime/web-socket.ts @@ -5,7 +5,7 @@ import MonoWasmThreads from "consts:monoWasmThreads"; import { prevent_timer_throttling } from "./scheduling"; import { Queue } from "./queue"; -import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, createPromiseController, mono_assert } from "./globals"; +import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, createPromiseController, loaderHelpers, mono_assert } from "./globals"; import { setI32, localHeapViewU8 } from "./memory"; import { VoidPtr } from "./types/emscripten"; import { PromiseController } from "./types/internal"; @@ -19,12 +19,15 @@ const wasm_ws_pending_send_buffer_type = Symbol.for("wasm ws_pending_send_buffer const wasm_ws_pending_receive_event_queue = Symbol.for("wasm ws_pending_receive_event_queue"); const wasm_ws_pending_receive_promise_queue = Symbol.for("wasm ws_pending_receive_promise_queue"); const wasm_ws_pending_open_promise = Symbol.for("wasm ws_pending_open_promise"); +const wasm_ws_pending_open_promise_used = Symbol.for("wasm wasm_ws_pending_open_promise_used"); const wasm_ws_pending_close_promises = Symbol.for("wasm ws_pending_close_promises"); const wasm_ws_pending_send_promises = Symbol.for("wasm ws_pending_send_promises"); const wasm_ws_is_aborted = Symbol.for("wasm ws_is_aborted"); const wasm_ws_on_closed = Symbol.for("wasm ws_on_closed"); +const wasm_ws_close_sent = Symbol.for("wasm wasm_ws_close_sent"); +const wasm_ws_close_received = Symbol.for("wasm wasm_ws_close_received"); const wasm_ws_receive_status_ptr = Symbol.for("wasm ws_receive_status_ptr"); -let mono_wasm_web_socket_close_warning = false; + const ws_send_buffer_blocking_threshold = 65536; const emptyBuffer = new Uint8Array(); @@ -58,18 +61,22 @@ export function ws_wasm_create(uri: string, sub_protocols: string[] | null, rece ws.binaryType = "arraybuffer"; const local_on_open = () => { if (ws[wasm_ws_is_aborted]) return; + if (loaderHelpers.is_exited()) return; open_promise_control.resolve(ws); prevent_timer_throttling(); }; const local_on_message = (ev: MessageEvent) => { if (ws[wasm_ws_is_aborted]) return; + if (loaderHelpers.is_exited()) return; _mono_wasm_web_socket_on_message(ws, ev); prevent_timer_throttling(); }; const local_on_close = (ev: CloseEvent) => { ws.removeEventListener("message", local_on_message); if (ws[wasm_ws_is_aborted]) return; + if (loaderHelpers.is_exited()) return; + ws[wasm_ws_close_received] = true; onClosed(ev.code, ev.reason); // this reject would not do anything if there was already "open" before it. @@ -93,6 +100,7 @@ export function ws_wasm_create(uri: string, sub_protocols: string[] | null, rece }; const local_on_error = (ev: any) => { if (ws[wasm_ws_is_aborted]) return; + if (loaderHelpers.is_exited()) return; ws.removeEventListener("message", local_on_message); const error = new Error(ev.message || "WebSocket error"); mono_log_warn("WebSocket error", error); @@ -116,12 +124,23 @@ export function ws_wasm_create(uri: string, sub_protocols: string[] | null, rece export function ws_wasm_open(ws: WebSocketExtension): Promise | null { mono_assert(!!ws, "ERR17: expected ws instance"); const open_promise_control = ws[wasm_ws_pending_open_promise]; + ws[wasm_ws_pending_open_promise_used] = true; return open_promise_control.promise; } export function ws_wasm_send(ws: WebSocketExtension, buffer_ptr: VoidPtr, buffer_length: number, message_type: number, end_of_message: boolean): Promise | null { mono_assert(!!ws, "ERR17: expected ws instance"); + if (ws[wasm_ws_is_aborted] || ws[wasm_ws_close_sent]) { + return Promise.reject(new Error("InvalidState: The WebSocket is not connected.")); + } + + if (ws.readyState === WebSocket.CLOSED) { + // this is server initiated close but not partial close + // because CloseOutputAsync_ServerInitiated_CanSend expectations, we don't fail here + return null; + } + const buffer_view = new Uint8Array(localHeapViewU8().buffer, buffer_ptr, buffer_length); const whole_buffer = _mono_wasm_web_socket_send_buffering(ws, buffer_view, message_type, end_of_message); @@ -135,14 +154,18 @@ export function ws_wasm_send(ws: WebSocketExtension, buffer_ptr: VoidPtr, buffer export function ws_wasm_receive(ws: WebSocketExtension, buffer_ptr: VoidPtr, buffer_length: number): Promise | null { mono_assert(!!ws, "ERR18: expected ws instance"); + // we can't quickly return if wasm_ws_close_received==true, because there could be pending messages + if (ws[wasm_ws_is_aborted]) { + const receive_status_ptr = ws[wasm_ws_receive_status_ptr]; + setI32(receive_status_ptr, 0); // count + setI32(receive_status_ptr + 4, 2); // type:close + setI32(receive_status_ptr + 8, 1);// end_of_message: true + return null; + } + const receive_event_queue = ws[wasm_ws_pending_receive_event_queue]; const receive_promise_queue = ws[wasm_ws_pending_receive_promise_queue]; - const readyState = ws.readyState; - if (readyState != WebSocket.OPEN && readyState != WebSocket.CLOSING) { - throw new Error(`InvalidState: ${readyState} The WebSocket is not connected.`); - } - if (receive_event_queue.getLength()) { mono_assert(receive_promise_queue.getLength() == 0, "ERR20: Invalid WS state"); @@ -151,6 +174,16 @@ export function ws_wasm_receive(ws: WebSocketExtension, buffer_ptr: VoidPtr, buf return null; } + + const readyState = ws.readyState; + if (readyState == WebSocket.CLOSED) { + const receive_status_ptr = ws[wasm_ws_receive_status_ptr]; + setI32(receive_status_ptr, 0); // count + setI32(receive_status_ptr + 4, 2); // type:close + setI32(receive_status_ptr + 8, 1);// end_of_message: true + return null; + } + const { promise, promise_control } = createPromiseController(); const receive_promise_control = promise_control as ReceivePromiseControl; receive_promise_control.buffer_ptr = buffer_ptr; @@ -163,10 +196,11 @@ export function ws_wasm_receive(ws: WebSocketExtension, buffer_ptr: VoidPtr, buf export function ws_wasm_close(ws: WebSocketExtension, code: number, reason: string | null, wait_for_close_received: boolean): Promise | null { mono_assert(!!ws, "ERR19: expected ws instance"); - if (ws.readyState == WebSocket.CLOSED) { + if (ws[wasm_ws_is_aborted] || ws[wasm_ws_close_sent] || ws.readyState == WebSocket.CLOSED) { return null; } + ws[wasm_ws_close_sent] = true; if (wait_for_close_received) { const { promise, promise_control } = createPromiseController(); ws[wasm_ws_pending_close_promises].push(promise_control); @@ -179,10 +213,6 @@ export function ws_wasm_close(ws: WebSocketExtension, code: number, reason: stri return promise; } else { - if (!mono_wasm_web_socket_close_warning) { - mono_wasm_web_socket_close_warning = true; - mono_log_warn("WARNING: Web browsers do not support closing the output side of a WebSocket. CloseOutputAsync has closed the socket and discarded any incoming messages."); - } if (typeof reason === "string") { ws.close(code, reason); } else { @@ -195,6 +225,10 @@ export function ws_wasm_close(ws: WebSocketExtension, code: number, reason: stri export function ws_wasm_abort(ws: WebSocketExtension): void { mono_assert(!!ws, "ERR18: expected ws instance"); + if (ws[wasm_ws_is_aborted] || ws[wasm_ws_close_sent]) { + return; + } + ws[wasm_ws_is_aborted] = true; reject_promises(ws, new Error("OperationCanceledException")); @@ -211,7 +245,12 @@ export function ws_wasm_abort(ws: WebSocketExtension): void { function reject_promises(ws: WebSocketExtension, error: Error) { const open_promise_control = ws[wasm_ws_pending_open_promise]; - if (open_promise_control) { + const open_promise_used = ws[wasm_ws_pending_open_promise_used]; + + // when `open_promise_used` is false, we should not reject it, + // because it would be unhandled rejection. Nobody is subscribed yet. + // The subscription comes on the next call, which is `ws_wasm_open`, but cancelation/abort could happen in the meantime. + if (open_promise_control && open_promise_used) { open_promise_control.reject(error); } for (const close_promise_control of ws[wasm_ws_pending_close_promises]) { @@ -399,10 +438,13 @@ type WebSocketExtension = WebSocket & { [wasm_ws_pending_receive_event_queue]: Queue; [wasm_ws_pending_receive_promise_queue]: Queue; [wasm_ws_pending_open_promise]: PromiseController + [wasm_ws_pending_open_promise_used]: boolean [wasm_ws_pending_send_promises]: PromiseController[] [wasm_ws_pending_close_promises]: PromiseController[] [wasm_ws_is_aborted]: boolean [wasm_ws_on_closed]: IDisposable + [wasm_ws_close_received]: boolean + [wasm_ws_close_sent]: boolean [wasm_ws_receive_status_ptr]: VoidPtr [wasm_ws_pending_send_buffer_offset]: number [wasm_ws_pending_send_buffer_type]: number From fe443a9f8fdbb19cdb6a955a65c4b700d261ef3d Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Wed, 24 Jan 2024 15:47:46 -0300 Subject: [PATCH 587/783] [release/8.0][mono][debugger] Debugger improvements on .net8 (#97160) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [mono][hotreload] Generate seq_points if we don't have pdb information from HotReload (#93039) * Generating seq_points if we don't have pdb information from HotReload * Apply suggestions from code review Co-authored-by: Aleksey Kliger (λgeek) * Addressing @lambdageek comments --------- Co-authored-by: Aleksey Kliger (λgeek) * Fix CMD_OBJECT_REF_GET_VALUES_BY_FIELD_TOKEN behavior (#93363) * [mono] Simplify of OffsetToStringData as it's done on coreclr (#93987) * Change implementation of OffsetToStringData as it's done on coreclr * Fix comment * Remove more comments * completely remove the comments * Update RuntimeHelpers.Mono.cs * Addressing comments * Addressing @lambdageek comment. * [mono] Trying to fix performance regression. (#94358) * Trying to fix performance regression. * Fix performance issue * [mono][debugger] Improve debugger features (#94066) * Creating new messages, changing some olds, and fixing when jit_end is called while running a invoke_method * Fix compilation error * Fix compilation * Applying suggestions from @lambdageek and adding more changes. * Addressing @lambdageek suggestions. * Addressing @lambdageek comment * Addressing @lambdageek comments * adding mono_component_api to function added. * Bump protocol version to check if we are in correct version that has all the things to make icordebug work. (#97161) --------- Co-authored-by: Aleksey Kliger (λgeek) --- .../CompilerServices/RuntimeHelpers.Mono.cs | 6 +- .../src/System/String.Mono.cs | 6 + src/mono/mono/component/debugger-agent.c | 193 ++++++++++++------ src/mono/mono/component/debugger-engine.c | 28 ++- src/mono/mono/component/debugger-engine.h | 2 + src/mono/mono/component/debugger-protocol.h | 8 +- src/mono/mono/metadata/class-internals.h | 2 +- src/mono/mono/metadata/debug-internals.h | 2 + src/mono/mono/metadata/icall.c | 11 +- src/mono/mono/metadata/mono-debug.c | 15 ++ src/mono/mono/metadata/object-internals.h | 3 + src/mono/mono/metadata/object.c | 14 ++ src/mono/mono/mini/interp/transform.c | 21 +- src/mono/mono/mini/intrinsics.c | 5 +- 14 files changed, 229 insertions(+), 87 deletions(-) diff --git a/src/mono/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.Mono.cs index 8fa80262e4903c..1564b301210bf2 100644 --- a/src/mono/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.Mono.cs @@ -30,11 +30,7 @@ public static void InitializeArray(Array array, RuntimeFieldHandle fldHandle) } [Obsolete("OffsetToStringData has been deprecated. Use string.GetPinnableReference() instead.")] - public static int OffsetToStringData - { - [Intrinsic] - get => OffsetToStringData; - } + public static int OffsetToStringData => string.OFFSET_TO_STRING; [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern int InternalGetHashCode(object? o); diff --git a/src/mono/System.Private.CoreLib/src/System/String.Mono.cs b/src/mono/System.Private.CoreLib/src/System/String.Mono.cs index 35e2aef4f2fbbf..7314504aff9a22 100644 --- a/src/mono/System.Private.CoreLib/src/System/String.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/String.Mono.cs @@ -30,6 +30,12 @@ public static string IsInterned(string str) [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern string InternalIntern(string str); +#if TARGET_64BIT + internal const int OFFSET_TO_STRING = 20; +#else + internal const int OFFSET_TO_STRING = 12; +#endif + // TODO: Should be pointing to Buffer instead #region Runtime method-to-ir dependencies diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index 1e8e27686a287e..7cc565cbf5ffd2 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -3812,7 +3812,7 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx default: g_assert_not_reached (); } -#ifdef HOST_WASI + #ifdef HOST_WASI resumed_from_wasi = FALSE; while (suspend_policy != SUSPEND_POLICY_NONE && !resumed_from_wasi) { @@ -4147,7 +4147,14 @@ jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo) dbg_unlock (); if (assembly) { - process_profiler_event (EVENT_KIND_ASSEMBLY_LOAD, assembly); + DebuggerTlsData *tls; + tls = (DebuggerTlsData *)mono_native_tls_get_value (debugger_tls_id); + if (tls->invoke == NULL) { + process_profiler_event (EVENT_KIND_ASSEMBLY_LOAD, assembly); + } else { + assembly_load(prof, assembly); //send later + break; + } } else { break; } @@ -5068,20 +5075,16 @@ buffer_add_info_for_null_value (Buffer* buf, MonoType* t, MonoDomain* domain) { buffer_add_byte (buf, t->type); switch (t->type) { - case MONO_TYPE_CLASS: - case MONO_TYPE_STRING: - buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (t)); - break; - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - buffer_add_byte (buf, m_class_get_byval_arg (m_class_get_element_class (mono_class_from_mono_type_internal (t)))->type); - buffer_add_int (buf, m_class_get_rank (mono_class_from_mono_type_internal (t))); - if (m_class_get_byval_arg (m_class_get_element_class (mono_class_from_mono_type_internal (t)))->type == MONO_TYPE_CLASS) - buffer_add_typeid (buf, domain, m_class_get_element_class (mono_class_from_mono_type_internal (t))); - buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (t)); - break; - default: - buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (t)); + case MONO_TYPE_SZARRAY: + case MONO_TYPE_ARRAY: + buffer_add_byte (buf, m_class_get_byval_arg (m_class_get_element_class (mono_class_from_mono_type_internal (t)))->type); + buffer_add_int (buf, m_class_get_rank (mono_class_from_mono_type_internal (t))); + if (m_class_get_byval_arg (m_class_get_element_class (mono_class_from_mono_type_internal (t)))->type == MONO_TYPE_CLASS) + buffer_add_typeid (buf, domain, m_class_get_element_class (mono_class_from_mono_type_internal (t))); + buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (t)); + break; + default: + buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (t)); } } /* @@ -5098,6 +5101,9 @@ buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain, MonoObject *obj; gboolean boxed_vtype = FALSE; + if (CHECK_ICORDBG (TRUE)) + buffer_add_byte (buf, !!m_type_is_byref (t)); + if (m_type_is_byref (t)) { if (!(*(void**)addr)) { /* This can happen with compiler generated locals */ @@ -5298,6 +5304,8 @@ buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain, if (mono_vtype_get_field_addr (addr, f) == addr && mono_class_from_mono_type_internal (t) == mono_class_from_mono_type_internal (f->type) && !boxed_vtype) //to avoid infinite recursion { gssize val = *(gssize*)addr; + if (CHECK_ICORDBG (TRUE)) + buffer_add_byte (buf, !!m_type_is_byref (f->type)); buffer_add_byte (buf, MONO_TYPE_PTR); buffer_add_long (buf, val); if (CHECK_PROTOCOL_VERSION(2, 46)) @@ -7097,6 +7105,8 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) minor_version = decode_int (p, &p, end); if (p < end) using_icordbg = decode_byte (p, &p, end); + if (using_icordbg) + mono_de_set_using_icordbg (); protocol_version_set = TRUE; PRINT_DEBUG_MSG (1, "[dbg] Protocol version %d.%d, client protocol version %d.%d.\n", MAJOR_VERSION, MINOR_VERSION, major_version, minor_version); break; @@ -7120,7 +7130,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) wait_for_suspend (); break; case CMD_VM_RESUME: -#ifndef HOST_WASI + #ifndef HOST_WASI if (suspend_count == 0) { if (agent_config.defer && !agent_config.suspend) // Workaround for issue in debugger-libs when running in defer attach mode. @@ -7708,7 +7718,7 @@ event_commands (int command, guint8 *p, guint8 *end, Buffer *buf) if (req->event_kind == EVENT_KIND_BREAKPOINT) { g_assert (method); - + req->info = mono_de_set_breakpoint (method, location, req, error); if (!is_ok (error)) { g_free (req); @@ -7945,6 +7955,42 @@ domain_commands (int command, guint8 *p, guint8 *end, Buffer *buf) buffer_add_objid (buf, o); break; } + case MDBGPROT_CMD_APPDOMAIN_GET_ARRAY_OR_POINTER_TYPE: { + MonoClass *klass; + domain = decode_domainid (p, &p, end, NULL, &err); + MonoTypeEnum type = decode_int (p, &p, end); + klass = decode_typeid (p, &p, end, NULL, &err); + int rank = decode_int (p, &p, end); + if (type == MONO_TYPE_SZARRAY || type == MONO_TYPE_ARRAY) + klass = mono_class_create_array (klass, rank); + else + return ERR_INVALID_ARGUMENT; + buffer_add_typeid (buf, domain, klass); + break; + } + + case MDBGPROT_CMD_APPDOMAIN_CREATE_ARRAY: { + ERROR_DECL (error); + MonoClass *klass; + MonoArray *arr; + domain = decode_domainid (p, &p, end, NULL, &err); + klass = decode_typeid (p, &p, end, NULL, &err); + int rank = decode_int (p, &p, end); + uintptr_t *lengths = g_newa (uintptr_t, rank); + intptr_t *lower_bounds = g_newa (intptr_t, rank); + for (int i = 0 ; i < rank; i++) + { + lengths [i] = decode_int (p, &p, end); + } + for (int i = 0 ; i < rank; i++) + { + lower_bounds [i] = decode_int (p, &p, end); + } + arr = mono_array_new_full_checked (klass, lengths, lower_bounds, error); + buffer_add_objid (buf, (MonoObject*) arr); + break; + } + default: return ERR_NOT_IMPLEMENTED; } @@ -8287,6 +8333,21 @@ field_commands (int command, guint8 *p, guint8 *end, Buffer *buf) } break; } + case MDBGPROT_CMD_FIELD_GET_TOKEN_AND_TYPE: { + MonoClassField *f = decode_fieldid (p, &p, end, &domain, &err); + if (G_UNLIKELY (!f->type)) { + ERROR_DECL(field_error); + mono_field_resolve_type (f, field_error); + mono_error_cleanup (field_error); + if (!f->type) + return ERR_INVALID_OBJECT; + } + buffer_add_int (buf, mono_class_get_field_token (f)); + buffer_add_byte(buf, GINT_TO_UINT8(m_class_is_valuetype (mono_class_from_mono_type_internal (f->type)))); + buffer_add_int (buf, f->type->type); + buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (f->type)); + break; + } default: return ERR_NOT_IMPLEMENTED; } @@ -8476,6 +8537,19 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint buffer_add_int (buf, 0); } } + if (CHECK_ICORDBG (TRUE)) + { + if (type->type == MONO_TYPE_FNPTR) + { + buffer_add_int (buf, 1 + type->data.method->param_count); + buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (type->data.method->ret)); + for (int j = 0; j < type->data.method->param_count; ++j) { + buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (type->data.method->params[j])); + } + } else { + buffer_add_int (buf, 0); + } + } break; } case CMD_TYPE_GET_METHODS: { @@ -8890,44 +8964,9 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint buffer_add_objid (buf, obj); if (CHECK_ICORDBG (TRUE)) { - buffer_add_byte(buf, m_class_is_valuetype (klass)); - if (m_class_is_valuetype (klass)) - { - int nfields = 0; - gpointer iter = NULL; - while ((f = mono_class_get_fields_internal (klass, &iter))) { - if (G_UNLIKELY (!f->type)) { - ERROR_DECL(field_error); - mono_field_resolve_type (f, field_error); - mono_error_cleanup (field_error); - if (!f->type) - continue; - } - if (f->type->attrs & FIELD_ATTRIBUTE_STATIC) - continue; - if (mono_field_is_deleted (f)) - continue; - nfields ++; - } - buffer_add_int (buf, nfields); - - iter = NULL; - while ((f = mono_class_get_fields_internal (klass, &iter))) { - if (G_UNLIKELY (!f->type)) { - ERROR_DECL(field_error); - mono_field_resolve_type (f, field_error); - mono_error_cleanup (field_error); - if (!f->type) - continue; - } - if (f->type->attrs & FIELD_ATTRIBUTE_STATIC) - continue; - if (mono_field_is_deleted (f)) - continue; - buffer_add_int (buf, mono_class_get_field_token (f)); - buffer_add_byte (buf, f->type->type); - } - } + buffer_add_byte(buf, GINT_TO_UINT8(m_class_is_valuetype (klass))); + buffer_add_int (buf, m_class_get_byval_arg (klass)->type); + buffer_add_typeid (buf, domain, klass); } break; } @@ -9007,6 +9046,33 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint buffer_add_byte (buf, m_class_get_rank (klass)); break; } + case MDBGPROT_CMD_TYPE_GET_FIELD_RVA: + { + gpointer iter = NULL; + int field_token = decode_int (p, &p, end); + while ((f = mono_class_get_fields_internal (klass, &iter))) { + if (mono_class_get_field_token (f) == field_token) + { + if (G_UNLIKELY (!f->type)) { + ERROR_DECL(field_error); + mono_field_resolve_type (f, field_error); + mono_error_cleanup (field_error); + if (!f->type) + continue; + } + if (f->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) + { + gint32 count = 0; + const char* arr = mono_get_span_data_from_field (f, f->type, f->type, &count); + m_dbgprot_buffer_add_byte_array (buf, (uint8_t *)arr, count); + err = ERR_NONE; + goto exit; + } + } + } + m_dbgprot_buffer_add_int (buf, 0); + break; + } default: err = ERR_NOT_IMPLEMENTED; goto exit; @@ -10186,7 +10252,7 @@ array_commands (int command, guint8 *p, guint8 *end, Buffer *buf) MonoTypeEnum type = m_class_get_byval_arg (m_class_get_element_class (arr->obj.vtable->klass))->type; buffer_add_byte(buf, type); buffer_add_int (buf, m_class_get_rank (arr->obj.vtable->klass)); - if (type == MONO_TYPE_CLASS || type == MONO_TYPE_GENERICINST || type == MONO_TYPE_OBJECT) + if (type == MONO_TYPE_CLASS || type == MONO_TYPE_GENERICINST || type == MONO_TYPE_OBJECT || (CHECK_ICORDBG (TRUE) && (type == MONO_TYPE_VALUETYPE || type == MONO_TYPE_PTR))) { buffer_add_typeid (buf, arr->obj.vtable->domain, m_class_get_element_class (arr->obj.vtable->klass)); if (CHECK_ICORDBG (TRUE)) @@ -10385,13 +10451,20 @@ object_commands (int command, guint8 *p, guint8 *end, Buffer *buf) case CMD_OBJECT_REF_GET_VALUES_BY_FIELD_TOKEN: { len = 1; i = 0; - MonoClass* klass = decode_typeid (p, &p, end, NULL, &err); + int class_token = decode_int (p, &p, end); int field_token = decode_int (p, &p, end); gpointer iter = NULL; - while ((f = mono_class_get_fields_internal (klass, &iter))) { - if (mono_class_get_field_token (f) == field_token) + for (k = obj_type; k; k = m_class_get_parent (k)) { + if (m_class_get_type_token (k) == class_token) { + break; + } + } + + while ((f = mono_class_get_fields_internal (k, &iter))) { + if (mono_class_get_field_token (f) == field_token) { goto get_field_value; + } } goto invalid_fieldid; } diff --git a/src/mono/mono/component/debugger-engine.c b/src/mono/mono/component/debugger-engine.c index 02f7eb090f6aec..5ec3e68b62aee4 100644 --- a/src/mono/mono/component/debugger-engine.c +++ b/src/mono/mono/component/debugger-engine.c @@ -35,6 +35,7 @@ static DebuggerEngineCallbacks rt_callbacks; static int log_level; static FILE *log_file; +static bool using_icordbg = FALSE; /* * Locking @@ -160,6 +161,19 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo } } + if (!it_has_sp && using_icordbg) + { + mono_seq_point_iterator_init (&it, seq_points); + while (mono_seq_point_iterator_next (&it)) { + if (it.seq_point.il_offset != METHOD_ENTRY_IL_OFFSET && + it.seq_point.il_offset != METHOD_EXIT_IL_OFFSET && + it.seq_point.il_offset > bp->il_offset) { + it_has_sp = TRUE; + break; + } + } + } + if (!it_has_sp) { char *s = g_strdup_printf ("Unable to insert breakpoint at %s:%ld", mono_method_full_name (jinfo_get_method (ji), TRUE), bp->il_offset); @@ -581,10 +595,10 @@ ss_req_cleanup (void) void mono_de_start_single_stepping (void) { - int val = mono_atomic_inc_i32 (&ss_count); + int val = mono_atomic_inc_i32 (&ss_count); if (val == 1) { -#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED + #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED mono_arch_start_single_stepping (); #endif mini_get_interp_callbacks_api ()->start_single_stepping (); @@ -594,10 +608,10 @@ mono_de_start_single_stepping (void) void mono_de_stop_single_stepping (void) { - int val = mono_atomic_dec_i32 (&ss_count); + int val = mono_atomic_dec_i32 (&ss_count); if (val == 0) { -#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED + #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED mono_arch_stop_single_stepping (); #endif mini_get_interp_callbacks_api ()->stop_single_stepping (); @@ -1534,6 +1548,12 @@ mono_de_set_log_level (int level, FILE *file) log_file = file; } +void +mono_de_set_using_icordbg () +{ + using_icordbg = TRUE; +} + /* * mono_de_init: * diff --git a/src/mono/mono/component/debugger-engine.h b/src/mono/mono/component/debugger-engine.h index b0f6c5ca729b38..d3c9b0696be5d1 100644 --- a/src/mono/mono/component/debugger-engine.h +++ b/src/mono/mono/component/debugger-engine.h @@ -345,6 +345,8 @@ mono_debugger_get_thread_state (DebuggerTlsData *ref); void mono_de_cleanup (void); void mono_de_set_log_level (int level, FILE *file); +void mono_de_set_using_icordbg (void); + //locking - we expose the lock object from the debugging engine to ensure we keep the same locking semantics of sdb. void mono_de_lock (void); void mono_de_unlock (void); diff --git a/src/mono/mono/component/debugger-protocol.h b/src/mono/mono/component/debugger-protocol.h index 9fe3c690c93e72..5948cef59c2c1a 100644 --- a/src/mono/mono/component/debugger-protocol.h +++ b/src/mono/mono/component/debugger-protocol.h @@ -11,7 +11,7 @@ */ #define MAJOR_VERSION 2 -#define MINOR_VERSION 65 +#define MINOR_VERSION 66 typedef enum { MDBGPROT_CMD_COMPOSITE = 100 @@ -132,6 +132,8 @@ typedef enum { MDBGPROT_CMD_APPDOMAIN_GET_CORLIB = 6, MDBGPROT_CMD_APPDOMAIN_CREATE_BOXED_VALUE = 7, MDBGPROT_CMD_APPDOMAIN_CREATE_BYTE_ARRAY = 8, + MDBGPROT_CMD_APPDOMAIN_GET_ARRAY_OR_POINTER_TYPE = 9, + MDBGPROT_CMD_APPDOMAIN_CREATE_ARRAY = 10 } MdbgProtCmdAppDomain; typedef enum { @@ -162,6 +164,7 @@ typedef enum { typedef enum { MDBGPROT_CMD_FIELD_GET_INFO = 1, + MDBGPROT_CMD_FIELD_GET_TOKEN_AND_TYPE = 2 } MdbgProtCmdField; typedef enum { @@ -215,7 +218,8 @@ typedef enum { MDBGPROT_CMD_TYPE_BIND_GENERIC_PARAMETERS = 24, MDBGPROT_CMD_TYPE_ELEMENT_TYPE = 25, MDBGPROT_CMD_TYPE_RANK = 26, - MDBGPROT_CMD_TYPE_SET_VALUES_BY_FIELD_TOKEN = 27 + MDBGPROT_CMD_TYPE_SET_VALUES_BY_FIELD_TOKEN = 27, + MDBGPROT_CMD_TYPE_GET_FIELD_RVA = 28 } MdbgProtCmdType; typedef enum { diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index 3b758b2acf6658..7a6a8ddc0080aa 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -1450,7 +1450,7 @@ mono_class_get_object_finalize_slot (void); MonoMethod * mono_class_get_default_finalize_method (void); -const char * +MONO_COMPONENT_API const char * mono_field_get_rva (MonoClassField *field, int swizzle); MONO_COMPONENT_API void diff --git a/src/mono/mono/metadata/debug-internals.h b/src/mono/mono/metadata/debug-internals.h index e08b767b4c3748..e03c2cffb9f35d 100644 --- a/src/mono/mono/metadata/debug-internals.h +++ b/src/mono/mono/metadata/debug-internals.h @@ -112,4 +112,6 @@ mono_debug_lookup_source_location_by_il (MonoMethod *method, guint32 il_offset, MONO_COMPONENT_API char* mono_debug_image_get_sourcelink (MonoImage *image); +mono_bool +mono_debug_generate_enc_seq_points_without_debug_info (MonoDebugMethodInfo *minfo); #endif /* __DEBUG_INTERNALS_H__ */ diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index f3ef9b74f26c65..2f612be9859985 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -989,16 +989,7 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetSpanDataFrom (MonoCl mono_error_set_argument (error, "array", "Cannot initialize array of non-primitive type"); return NULL; } - - int swizzle = 1; - int align; -#if G_BYTE_ORDER != G_LITTLE_ENDIAN - swizzle = mono_type_size (type, &align); -#endif - - int dummy; - *count = mono_type_size (field_type, &dummy)/mono_type_size (type, &align); - return (gpointer)mono_field_get_rva (field_handle, swizzle); + return mono_get_span_data_from_field (field_handle, field_type, type, count); } void diff --git a/src/mono/mono/metadata/mono-debug.c b/src/mono/mono/metadata/mono-debug.c index e49089b3e4652c..392581889def56 100644 --- a/src/mono/mono/metadata/mono-debug.c +++ b/src/mono/mono/metadata/mono-debug.c @@ -1149,6 +1149,21 @@ mono_debug_enabled (void) return mono_debug_format != MONO_DEBUG_FORMAT_NONE; } + +//Returns true if the method has updates but doesn't have ppdb information then we should generate the seq points using the coreclr rules +mono_bool +mono_debug_generate_enc_seq_points_without_debug_info (MonoDebugMethodInfo *minfo) +{ + MonoImage* img = m_class_get_image (minfo->method->klass); + if (G_UNLIKELY (img->has_updates)) { + guint32 idx = mono_metadata_token_index (minfo->method->token); + MonoDebugInformationEnc *mdie = (MonoDebugInformationEnc *) mono_metadata_update_get_updated_method_ppdb (img, idx); + if (mdie == NULL) + return TRUE; + } + return FALSE; +} + void mono_debug_get_seq_points (MonoDebugMethodInfo *minfo, char **source_file, GPtrArray **source_file_list, int **source_files, MonoSymSeqPoint **seq_points, int *n_seq_points) { diff --git a/src/mono/mono/metadata/object-internals.h b/src/mono/mono/metadata/object-internals.h index 2f62c2530e8e46..1909411c7d03ef 100644 --- a/src/mono/mono/metadata/object-internals.h +++ b/src/mono/mono/metadata/object-internals.h @@ -2161,4 +2161,7 @@ mono_method_get_unmanaged_wrapper_ftnptr_internal (MonoMethod *method, gboolean void mono_runtime_run_startup_hooks (void); +MONO_COMPONENT_API gpointer +mono_get_span_data_from_field (MonoClassField *field_handle, MonoType *field_type, MonoType *target_type, gint32 *count); + #endif /* __MONO_OBJECT_INTERNALS_H__ */ diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index a99369f8bfce5f..36be06dca981d0 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -8178,6 +8178,20 @@ mono_runtime_run_startup_hooks (void) mono_error_raise_exception_deprecated (error); } +gpointer +mono_get_span_data_from_field (MonoClassField *field_handle, MonoType *field_type, MonoType *target_type, gint32 *count) +{ + int swizzle = 1; + int align; +#if G_BYTE_ORDER != G_LITTLE_ENDIAN + swizzle = mono_type_size (target_type, &align); +#endif + + int dummy; + *count = mono_type_size (field_type, &dummy)/mono_type_size (target_type, &align); + return (gpointer)mono_field_get_rva (field_handle, swizzle); +} + #if NEVER_DEFINED /* * The following section is purely to declare prototypes and diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 67034e9c59c81c..06396bc063fbcf 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -4786,6 +4786,19 @@ is_ip_protected (MonoMethodHeader *header, int offset) return FALSE; } +static gboolean +should_insert_seq_point (TransformData *td) +{ + //following the CoreCLR's algorithm for adding the sequence points + if ((*td->ip == CEE_NOP) || + (*td->ip == CEE_CALLVIRT) || + (*td->ip == CEE_CALLI) || + (*td->ip == CEE_CALL) || + (GPTRDIFF_TO_INT (td->sp - td->stack) == 0)) + return TRUE; + return FALSE; +} + static gboolean generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, MonoGenericContext *generic_context, MonoError *error) { @@ -4817,6 +4830,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, gboolean save_last_error = FALSE; gboolean link_bblocks = TRUE; gboolean inlining = td->method != method; + gboolean generate_enc_seq_points_without_debug_info = FALSE; InterpBasicBlock *exit_bb = NULL; original_bb = bb = mono_basic_block_split (method, error, header); @@ -4863,6 +4877,8 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, int n_il_offsets; mono_debug_get_seq_points (minfo, NULL, NULL, NULL, &sps, &n_il_offsets); + if (n_il_offsets == 0) + generate_enc_seq_points_without_debug_info = mono_debug_generate_enc_seq_points_without_debug_info (minfo); // FIXME: Free seq_point_locs = mono_bitset_mem_new (mono_mempool_alloc0 (td->mempool, mono_bitset_alloc_size (header->code_size, 0)), header->code_size, 0); sym_seq_points = TRUE; @@ -5092,6 +5108,9 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, WRITE64_INS (td->last_ins, 0, &counter); } + if (G_UNLIKELY (generate_enc_seq_points_without_debug_info) && should_insert_seq_point (td)) + last_seq_point = interp_add_ins (td, MINT_SDB_SEQ_POINT); + switch (*td->ip) { case CEE_NOP: /* lose it */ @@ -5361,7 +5380,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, if (!interp_transform_call (td, method, NULL, generic_context, constrained_class, readonly, error, TRUE, save_last_error, tailcall)) goto exit; - if (need_seq_point) { + if (need_seq_point && !generate_enc_seq_points_without_debug_info) { // check if it is a nested call and remove the MONO_INST_NONEMPTY_STACK of the last breakpoint, only for non native methods if (!(method->flags & METHOD_IMPL_ATTRIBUTE_NATIVE)) { if (emitted_funccall_seq_point) { diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index ef77b7dc89f2ee..eca90a0e6abbf9 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -934,10 +934,7 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign } else return NULL; } else if (cmethod->klass == runtime_helpers_class) { - if (strcmp (cmethod->name, "get_OffsetToStringData") == 0 && fsig->param_count == 0) { - EMIT_NEW_ICONST (cfg, ins, MONO_STRUCT_OFFSET (MonoString, chars)); - return ins; - } else if (!strcmp (cmethod->name, "GetRawData")) { + if (!strcmp (cmethod->name, "GetRawData")) { int dreg = alloc_preg (cfg); EMIT_NEW_BIALU_IMM (cfg, ins, OP_PADD_IMM, dreg, args [0]->dreg, MONO_ABI_SIZEOF (MonoObject)); return ins; From d7a411899645fd5385b4c0efea4e0ec02f6b9ade Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 16:36:11 -0800 Subject: [PATCH 588/783] [release/8.0-staging] Add additionalSize for the DisableOptData (#97479) * add additionalSize for the DisableOptData * adding STRESS_LOG --------- Co-authored-by: Mikelle --- src/coreclr/debug/shared/dbgtransportsession.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/debug/shared/dbgtransportsession.cpp b/src/coreclr/debug/shared/dbgtransportsession.cpp index fa8b06618362d9..8b8ca6203c9571 100644 --- a/src/coreclr/debug/shared/dbgtransportsession.cpp +++ b/src/coreclr/debug/shared/dbgtransportsession.cpp @@ -2499,9 +2499,11 @@ DWORD DbgTransportSession::GetEventSize(DebuggerIPCEvent *pEvent) break; case DB_IPCE_DISABLE_OPTS: + cbAdditionalSize = sizeof(pEvent->DisableOptData); + break; default: - printf("Unknown debugger event type: 0x%x\n", (pEvent->type & DB_IPCE_TYPE_MASK)); + STRESS_LOG1(LF_CORDB, LL_INFO1000, "Unknown debugger event type: 0x%x\n", (pEvent->type & DB_IPCE_TYPE_MASK)); _ASSERTE(!"Unknown debugger event type"); } From 1901707289706ad9ffdc00be86e2b73bd9aa4898 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 17:46:38 +0100 Subject: [PATCH 589/783] [release/8.0-staging] Bump to new Ubuntu 22.04 queue for PPC64 (#97555) * Bump to new Ubuntu 22.04 queue for PPC64 * ActiveIssue for PPC64 generally, not limited to Ubuntu 20.04 This test errors out on the new 22.04 queue as well, it is not 20.04 specific --------- Co-authored-by: Jo Shields --- eng/pipelines/libraries/helix-queues-setup.yml | 2 +- .../tests/FunctionalTests/MsQuicPlatformDetectionTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index dd80cdc85095ad..5b37825df0867d 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -87,7 +87,7 @@ jobs: # Linux PPC64le - ${{ if eq(parameters.platform, 'linux_ppc64le') }}: - - Ubuntu.2004.PPC64le.Experimental.Open + - Ubuntu.2204.PPC64le.Experimental.Open # OSX arm64 - ${{ if eq(parameters.platform, 'osx_arm64') }}: diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicPlatformDetectionTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicPlatformDetectionTests.cs index 8dd026596c77fc..16f267fc719535 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicPlatformDetectionTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicPlatformDetectionTests.cs @@ -57,7 +57,7 @@ public async Task SupportedLinuxPlatformsWithMsQuic_IsSupportedIsTrue() } [ActiveIssue("https://github.com/dotnet/runtime/issues/82154", typeof(PlatformDetection), nameof(PlatformDetection.IsRaspbian10), nameof(PlatformDetection.IsArmv6Process), nameof(PlatformDetection.IsInContainer))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/82154", typeof(PlatformDetection), nameof(PlatformDetection.IsUbuntu2004), nameof(PlatformDetection.IsPpc64leProcess))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/82154", typeof(PlatformDetection), nameof(PlatformDetection.IsPpc64leProcess))] [ActiveIssue("https://github.com/dotnet/runtime/issues/82154", typeof(PlatformDetection), nameof(PlatformDetection.IsUbuntu2004), nameof(PlatformDetection.IsS390xProcess))] [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsInHelix))] [PlatformSpecific(TestPlatforms.Linux)] From b54886b4b7e4b8617b1710459efc3a75b8c24235 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 09:30:40 -0800 Subject: [PATCH 590/783] [release/8.0-staging] Fix compilation error with generic type attributes (#97717) * Fix compilation error with generic type attributes Strip generic type parameter attributes from partial classes emitted by the logging source generated to avoid CS0579 errors from duplicate attributes. Fixes #97498. * Update comment Update comment as suggested by code review. * Verify type parameters retained Verify that attributes on generic type parameters are not lost. * Add package authoring --------- Co-authored-by: martincostello Co-authored-by: Tarek Mahmoud Sayed --- .../gen/LoggerMessageGenerator.Parser.cs | 27 ++++++++++++- ...oft.Extensions.Logging.Abstractions.csproj | 2 + ...thGenericTypesWithAttributes.generated.txt | 24 ++++++++++++ .../LoggerMessageGeneratorEmitterTests.cs | 36 +++++++++++++++++- .../LoggerMessageGeneratorParserTests.cs | 38 +++++++++++++++++++ .../TestClasses/NestedClassTestsExtensions.cs | 29 ++++++++++++++ 6 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithNestedClassWithGenericTypesWithAttributes.generated.txt diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs index 038b71bef0759b..1bc6ff6c323873 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs @@ -536,7 +536,7 @@ potentialNamespaceParent is not NamespaceDeclarationSyntax { Keyword = classDec.Keyword.ValueText, Namespace = nspace, - Name = classDec.Identifier.ToString() + classDec.TypeParameterList, + Name = GenerateClassName(classDec), ParentClass = null, }; @@ -554,7 +554,7 @@ static bool IsAllowedKind(SyntaxKind kind) => { Keyword = parentLoggerClass.Keyword.ValueText, Namespace = nspace, - Name = parentLoggerClass.Identifier.ToString() + parentLoggerClass.TypeParameterList, + Name = GenerateClassName(parentLoggerClass), ParentClass = null, }; @@ -601,6 +601,29 @@ static bool IsAllowedKind(SyntaxKind kind) => return results; } + private static string GenerateClassName(TypeDeclarationSyntax typeDeclaration) + { + if (typeDeclaration.TypeParameterList != null && + typeDeclaration.TypeParameterList.Parameters.Count != 0) + { + // The source generator produces a partial class that the compiler merges with the original + // class definition in the user code. If the user applies attributes to the generic types + // of the class, it is necessary to remove these attribute annotations from the generated + // code. Failure to do so may result in a compilation error (CS0579: Duplicate attribute). + for (int i = 0; i < typeDeclaration.TypeParameterList.Parameters.Count; i++) + { + TypeParameterSyntax parameter = typeDeclaration.TypeParameterList.Parameters[i]; + + if (parameter.AttributeLists.Count > 0) + { + typeDeclaration = typeDeclaration.ReplaceNode(parameter, parameter.WithAttributeLists([])); + } + } + } + + return typeDeclaration.Identifier.ToString() + typeDeclaration.TypeParameterList; + } + private (string? loggerField, bool multipleLoggerFields) FindLoggerField(SemanticModel sm, TypeDeclarationSyntax classDec, ITypeSymbol loggerSymbol) { string? loggerField = null; diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj index 085cade3966b96..052e5b9e0c0f60 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj @@ -5,6 +5,8 @@ true true true + true + 1 Logging abstractions for Microsoft.Extensions.Logging. Commonly Used Types: diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithNestedClassWithGenericTypesWithAttributes.generated.txt b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithNestedClassWithGenericTypesWithAttributes.generated.txt new file mode 100644 index 00000000000000..c7ddd086fcf27e --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithNestedClassWithGenericTypesWithAttributes.generated.txt @@ -0,0 +1,24 @@ +// +#nullable enable + +namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses +{ + partial class GenericTypeWithAttribute + { + partial class Log + { + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")] + private static readonly global::System.Action __M0Callback = + global::Microsoft.Extensions.Logging.LoggerMessage.Define(global::Microsoft.Extensions.Logging.LogLevel.Debug, new global::Microsoft.Extensions.Logging.EventId(42, nameof(M0)), "a = {a}; b = {b}; c = {c}", new global::Microsoft.Extensions.Logging.LogDefineOptions() { SkipEnabledCheck = true }); + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")] + public static partial void M0(global::Microsoft.Extensions.Logging.ILogger logger, A a, B b, C c) + { + if (logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Debug)) + { + __M0Callback(logger, a, b, c, null); + } + } + } + } +} \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs index b1d767536653f5..30cf036fdd8606 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs @@ -3,8 +3,8 @@ using System; using System.IO; +using System.Reflection; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Text; using SourceGenerators.Tests; using Xunit; @@ -163,6 +163,40 @@ internal static partial class TestWithDefaultValues } #endif + [Fact] + public async Task TestBaseline_TestWithNestedClassWithGenericTypesWithAttributes_Success() + { + string testSourceCode = @" +namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses +{ + public partial class GenericTypeWithAttribute<[Foo] A, [Bar] B, C> + { + public void M0(A a, B b, C c, ILogger logger) => Log.M0(logger, a, b, c); + private static partial class Log<[Foo] D> + { + [LoggerMessage(EventId = 42, Level = LogLevel.Debug, Message = ""a = {a}; b = {b}; c = {c}"")] + public static partial void M0(ILogger logger, A a, B b, C c); + } + } + + [AttributeUsage(AttributeTargets.GenericParameter)] + public sealed class FooAttribute : Attribute { } + [AttributeUsage(AttributeTargets.GenericParameter)] + public sealed class BarAttribute : Attribute { } +}"; + await VerifyAgainstBaselineUsingFile("TestWithNestedClassWithGenericTypesWithAttributes.generated.txt", testSourceCode); + } + + [Fact] + public void GenericTypeParameterAttributesAreRetained() + { + var type = typeof(TestClasses.NestedClassWithGenericTypesWithAttributesTestsExtensions<,,>).GetTypeInfo(); + + Assert.Equal(3, type.GenericTypeParameters.Length); + Assert.NotNull(type.GenericTypeParameters[0].GetCustomAttribute()); + Assert.NotNull(type.GenericTypeParameters[1].GetCustomAttribute()); + } + private async Task VerifyAgainstBaselineUsingFile(string filename, string testSourceCode) { string baseline = LineEndingsHelper.Normalize(await File.ReadAllTextAsync(Path.Combine("Baselines", filename)).ConfigureAwait(false)); diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs index dc677e81cfc4a0..d0d5fc30af573f 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs @@ -359,6 +359,44 @@ public partial class Nested Assert.Empty(diagnostics); } + [Fact] + public async Task NestedTypeWithGenericParameterOK() + { + IReadOnlyList diagnostics = await RunGenerator(@" + partial class C + { + public partial class Nested + { + [LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M1"")] + static partial void M1(ILogger logger); + } + } + "); + + Assert.Empty(diagnostics); + } + + [Fact] + public async Task NestedTypeWithGenericParameterWithAttributeOK() + { + IReadOnlyList diagnostics = await RunGenerator(@" + using System; + using System.Diagnostics.CodeAnalysis; + partial class C<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T> + { + public partial class Nested<[MarkerAttribute] U> + { + [LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M1"")] + static partial void M1(ILogger logger); + } + } + [AttributeUsage(AttributeTargets.GenericParameter)] + class MarkerAttribute : Attribute { } + "); + + Assert.Empty(diagnostics); + } + #if ROSLYN4_0_OR_GREATER [Fact] public async Task FileScopedNamespaceOK() diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/NestedClassTestsExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/NestedClassTestsExtensions.cs index ba6b87f6d5308a..ea8cde78d566df 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/NestedClassTestsExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/NestedClassTestsExtensions.cs @@ -3,8 +3,20 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses { + using System; using NamespaceForABC; + public partial class NestedClassWithNoTypeConstraintTestsExtensions + { + public void M7(ILogger logger) => Log.M7(logger); + + private static partial class Log + { + [LoggerMessage(EventId = 7, Level = LogLevel.Debug, Message = "M7")] + public static partial void M7(ILogger logger); + } + } + internal static partial class NestedClassTestsExtensions where T : ABC { internal static partial class NestedMiddleParentClass @@ -61,6 +73,23 @@ internal static partial class Logger } } } + + public partial class NestedClassWithGenericTypesWithAttributesTestsExtensions<[Foo] A, [Bar] B, C> + { + public void M13(A a, B b, C c, ILogger logger) => Log.M13(logger, a, b, c); + + private static partial class Log<[Foo] D> + { + [LoggerMessage(EventId = 13, Level = LogLevel.Debug, Message = "M13: A = {a}; B = {b}; C = {c}")] + public static partial void M13(ILogger logger, A a, B b, C c); + } + } + + [AttributeUsage(AttributeTargets.GenericParameter)] + public sealed class FooAttribute : Attribute { } + + [AttributeUsage(AttributeTargets.GenericParameter)] + public sealed class BarAttribute : Attribute { } } namespace NamespaceForABC From e6d8079d09491f4779a28e22f6b1702e9d98fe56 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 09:03:20 -0800 Subject: [PATCH 591/783] Remove use of NewHolder as field. (#97843) Co-authored-by: Aaron R Robinson --- src/coreclr/vm/syncblk.cpp | 4 ++++ src/coreclr/vm/syncblk.h | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/coreclr/vm/syncblk.cpp b/src/coreclr/vm/syncblk.cpp index bd235093b2d9c9..d0743994b7a86c 100644 --- a/src/coreclr/vm/syncblk.cpp +++ b/src/coreclr/vm/syncblk.cpp @@ -69,6 +69,10 @@ InteropSyncBlockInfo::~InteropSyncBlockInfo() CONTRACTL_END; FreeUMEntryThunk(); + +#if defined(FEATURE_COMWRAPPERS) + delete m_managedObjectComWrapperMap; +#endif // FEATURE_COMWRAPPERS } #ifndef TARGET_UNIX diff --git a/src/coreclr/vm/syncblk.h b/src/coreclr/vm/syncblk.h index 7fba11541532ff..c5464e73f24bb8 100644 --- a/src/coreclr/vm/syncblk.h +++ b/src/coreclr/vm/syncblk.h @@ -826,7 +826,7 @@ class InteropSyncBlockInfo if (m_managedObjectComWrapperMap == NULL) { NewHolder map = new ManagedObjectComWrapperByIdMap(); - if (InterlockedCompareExchangeT((ManagedObjectComWrapperByIdMap**)&m_managedObjectComWrapperMap, (ManagedObjectComWrapperByIdMap *)map, NULL) == NULL) + if (InterlockedCompareExchangeT(&m_managedObjectComWrapperMap, (ManagedObjectComWrapperByIdMap *)map, NULL) == NULL) { map.SuppressRelease(); } @@ -917,7 +917,7 @@ class InteropSyncBlockInfo void* m_externalComObjectContext; CrstExplicitInit m_managedObjectComWrapperLock; - NewHolder m_managedObjectComWrapperMap; + ManagedObjectComWrapperByIdMap* m_managedObjectComWrapperMap; #endif // FEATURE_COMWRAPPERS #ifdef FEATURE_OBJCMARSHAL From 31691ff0c81d82b19a38e4b6c8474cc369ef2ad5 Mon Sep 17 00:00:00 2001 From: vseanreesermsft <78103370+vseanreesermsft@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:23:12 -0800 Subject: [PATCH 592/783] Update branding to 8.0.3 (#98059) --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 55ce55ada067df..c202a5bbb52706 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,11 +1,11 @@ - 8.0.2 + 8.0.3 8 0 - 2 + 3 8.0.100 7.0.$([MSBuild]::Add($(PatchVersion),14)) 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) From b0025c75590df174971f4c69c26a7380849c634d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:01:01 -0800 Subject: [PATCH 593/783] [release/8.0-staging] Update dependencies from dotnet/runtime-assets (#97212) * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240118.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24060.2 -> To Version 8.0.0-beta.24068.2 --------- Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 3 +++ eng/Version.Details.xml | 56 ++++++++++++++++++++--------------------- eng/Versions.props | 28 ++++++++++----------- 3 files changed, 45 insertions(+), 42 deletions(-) diff --git a/NuGet.config b/NuGet.config index 76ed5a30293c3a..12fa8c8879cdb6 100644 --- a/NuGet.config +++ b/NuGet.config @@ -10,6 +10,9 @@ + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 95c24b9f3675f5..d9219e152c7cad 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -185,57 +185,57 @@ https://github.com/dotnet/arcade 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 https://github.com/dotnet/llvm-project @@ -358,9 +358,9 @@ https://github.com/dotnet/hotreload-utils 3b7da338c73b31b943c5512dcf0e2f6dd75f601c - + https://github.com/dotnet/runtime-assets - 3b165c269b12cc194f48fde6a1a7694bece8931b + 15009138ff960446092497b67a13cc3dc00445f7 https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index 55ce55ada067df..90ba26b4c2823c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -143,20 +143,20 @@ 4.5.0 8.0.0-rc.1.23406.6 - 8.0.0-beta.24060.2 - 8.0.0-beta.24060.2 - 8.0.0-beta.24060.2 - 8.0.0-beta.24060.2 - 8.0.0-beta.24060.2 - 8.0.0-beta.24060.2 - 8.0.0-beta.24060.2 - 8.0.0-beta.24060.2 - 8.0.0-beta.24060.2 - 8.0.0-beta.24060.2 - 8.0.0-beta.24060.2 - 8.0.0-beta.24060.2 - 8.0.0-beta.24060.2 - 8.0.0-beta.24060.2 + 8.0.0-beta.24068.2 + 8.0.0-beta.24068.2 + 8.0.0-beta.24068.2 + 8.0.0-beta.24068.2 + 8.0.0-beta.24068.2 + 8.0.0-beta.24068.2 + 8.0.0-beta.24068.2 + 8.0.0-beta.24068.2 + 8.0.0-beta.24068.2 + 8.0.0-beta.24068.2 + 8.0.0-beta.24068.2 + 8.0.0-beta.24068.2 + 8.0.0-beta.24068.2 + 8.0.0-beta.24068.2 1.0.0-prerelease.23566.3 1.0.0-prerelease.23566.3 From d8042d4384ca9ce5a6118a1bd87c6073a5f1052f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:01:39 -0800 Subject: [PATCH 594/783] Update dependencies from https://github.com/dotnet/hotreload-utils build 20240122.2 (#97322) Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.24060.1 -> To Version 8.0.0-alpha.0.24072.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d9219e152c7cad..1e47771d2b3a7c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -354,9 +354,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 67613417f5e1af250e6ddfba79f8f2885d8e90fb - + https://github.com/dotnet/hotreload-utils - 3b7da338c73b31b943c5512dcf0e2f6dd75f601c + bc857c64c5c5f1fc73048261e8f471c3310224d2 https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index 90ba26b4c2823c..907392a3ee011d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -186,7 +186,7 @@ 8.0.0-prerelease.24060.1 8.0.0-prerelease.24060.1 8.0.0-prerelease.24060.1 - 8.0.0-alpha.0.24060.1 + 8.0.0-alpha.0.24072.2 2.4.2 1.0.0 2.4.5 From c2415d7e96f1bbc8864a2bbb7035fbcac2eb5100 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Thu, 8 Feb 2024 09:46:07 +0000 Subject: [PATCH 595/783] [release/8.0] Fix STJ SG regression in handling of property names that are reserved keywords. (#98082) * Fix #98050. (#98058) * bump servicing version --- .../gen/JsonSourceGenerator.Emitter.cs | 2 +- .../src/System.Text.Json.csproj | 2 +- .../JsonSourceGeneratorTests.cs | 27 +++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs index 90575721c507d7..692f90741b0373 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs @@ -798,7 +798,7 @@ private void GenerateFastPathFuncForObject(SourceWriter writer, ContextGeneratio if (defaultCheckType != DefaultCheckType.None) { // Use temporary variable to evaluate property value only once - string localVariableName = $"__value_{propertyGenSpec.NameSpecifiedInSourceCode}"; + string localVariableName = $"__value_{propertyGenSpec.NameSpecifiedInSourceCode.TrimStart('@')}"; writer.WriteLine($"{propertyGenSpec.PropertyType.FullyQualifiedName} {localVariableName} = {objectExpr}.{propertyGenSpec.NameSpecifiedInSourceCode};"); propValueExpr = localVariableName; } diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index 29409f7f886293..9c492f0c6e0348 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -9,7 +9,7 @@ true true true - 2 + 3 Provides high-performance and low-allocating types that serialize objects to JavaScript Object Notation (JSON) text and deserialize JSON text to objects, with UTF-8 support built-in. Also provides types to read and write JSON text encoded as UTF-8, and to create an in-memory document object model (DOM), that is read-only, for random access of the JSON elements within a structured view of the data. The System.Text.Json library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks. diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorTests.cs index ce27630b6ab692..332f718ce3ff49 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorTests.cs @@ -737,5 +737,32 @@ public class MyClass Compilation compilation = CompilationHelper.CreateCompilation(source, parseOptions: CompilationHelper.CreateParseOptions(languageVersion)); CompilationHelper.RunJsonSourceGenerator(compilation); } + + [Fact] + public void FastPathWithReservedKeywordPropertyNames_CompilesSuccessfully() + { + // Regression test for https://github.com/dotnet/runtime/issues/98050 + + string source = """ + using System.Text.Json.Serialization; + + public class Model + { + public string type { get; set; } + public string alias { get; set; } + public string @class { get; set; } + public string @struct { get; set; } + } + + [JsonSourceGenerationOptions(DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] + [JsonSerializable(typeof(Model))] + internal partial class ModelContext : JsonSerializerContext + { + } + """; + + Compilation compilation = CompilationHelper.CreateCompilation(source); + CompilationHelper.RunJsonSourceGenerator(compilation); + } } } From 2663ba64a5a75eabb467da29fc9fad68393efdb5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 14:31:55 -0800 Subject: [PATCH 596/783] Update SystemDataSqlClientVersion from 4.8.5 -> 4.8.6 for component governance warning. (#97882) Co-authored-by: Parker Bibus --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 907392a3ee011d..c50a1008b5f25f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -126,7 +126,7 @@ 4.5.1 7.0.0 5.0.0 - 4.8.5 + 4.8.6 8.0.0 5.0.0 4.5.5 From d62ff0ba2487e15b0d62ecadb7471019682b61d0 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 8 Feb 2024 15:11:29 -0800 Subject: [PATCH 597/783] Disable jiterpreter_do_jit_call to address issues with disabling Wasm EH on 8.0. (#98051) --- src/mono/mono/mini/interp/interp.c | 13 ------------- src/mono/mono/mini/interp/jiterpreter.c | 15 ++------------- src/mono/mono/mini/interp/jiterpreter.h | 6 ------ 3 files changed, 2 insertions(+), 32 deletions(-) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 6fb6bdd582d29d..c7d47719714de1 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -2726,21 +2726,8 @@ do_jit_call (ThreadContext *context, stackval *ret_sp, stackval *sp, InterpFrame interp_push_lmf (&ext, frame); if (mono_aot_mode == MONO_AOT_MODE_LLVMONLY_INTERP) { -#if JITERPRETER_ENABLE_SPECIALIZED_JIT_CALL - /* - * invoke jit_call_cb via a single indirect function call that dispatches to - * either a specialized JS implementation or a specialized WASM EH version - * see jiterpreter-jit-call.ts and do-jit-call.wat - * NOTE: the first argument must ALWAYS be jit_call_cb for the specialization. - * the actual implementation cannot verify this at runtime, so get it right - * this is faster than mono_llvm_cpp_catch_exception by avoiding the use of - * emscripten invoke_vi to find and invoke jit_call_cb indirectly - */ - jiterpreter_do_jit_call(jit_call_cb, &cb_data, &thrown); -#else /* Catch the exception thrown by the native code using a try-catch */ mono_llvm_cpp_catch_exception (jit_call_cb, &cb_data, &thrown); -#endif } else { jit_call_cb (&cb_data); } diff --git a/src/mono/mono/mini/interp/jiterpreter.c b/src/mono/mono/mini/interp/jiterpreter.c index d3deb54f825659..82930e5737ac9c 100644 --- a/src/mono/mono/mini/interp/jiterpreter.c +++ b/src/mono/mono/mini/interp/jiterpreter.c @@ -53,10 +53,6 @@ void jiterp_preserve_module (void); static gint32 jiterpreter_abort_counts[MINT_LASTOP + 1] = { 0 }; static int64_t jiterp_trace_bailout_counts[256] = { 0 }; -// This function pointer is used by interp.c to invoke jit_call_cb for exception handling purposes -// See jiterpreter-jit-call.ts mono_jiterp_do_jit_call_indirect -WasmDoJitCall jiterpreter_do_jit_call = mono_jiterp_do_jit_call_indirect; - // We disable this diagnostic because EMSCRIPTEN_KEEPALIVE makes it a false alarm, the keepalive // functions are being used externally. Having a bunch of prototypes is pointless since these // functions are not consumed by C anywhere else @@ -951,15 +947,8 @@ mono_jiterp_get_options_as_json () EMSCRIPTEN_KEEPALIVE void mono_jiterp_update_jit_call_dispatcher (WasmDoJitCall dispatcher) { - // If we received a 0 dispatcher that means the TS side failed to compile - // any kind of dispatcher - this likely indicates that content security policy - // blocked the use of Module.addFunction - if (!dispatcher) - dispatcher = (WasmDoJitCall)mono_llvm_cpp_catch_exception; - else if (((int)(void*)dispatcher)==-1) - dispatcher = mono_jiterp_do_jit_call_indirect; - - jiterpreter_do_jit_call = dispatcher; + // Disabled in 8.0 to address issues when building with Wasm EH disabled. + // This system is entirely gone in 9.0. -kg } EMSCRIPTEN_KEEPALIVE int diff --git a/src/mono/mono/mini/interp/jiterpreter.h b/src/mono/mono/mini/interp/jiterpreter.h index 2f4d9a632a664b..a1b4cfd8e59570 100644 --- a/src/mono/mono/mini/interp/jiterpreter.h +++ b/src/mono/mono/mini/interp/jiterpreter.h @@ -5,12 +5,8 @@ #ifdef DISABLE_THREADS #define JITERPRETER_ENABLE_JIT_CALL_TRAMPOLINES 1 -// enables specialized mono_llvm_cpp_catch_exception replacement (see jiterpreter-jit-call.ts) -// works even if the jiterpreter is otherwise disabled. -#define JITERPRETER_ENABLE_SPECIALIZED_JIT_CALL 1 #else #define JITERPRETER_ENABLE_JIT_CALL_TRAMPOLINES 0 -#define JITERPRETER_ENABLE_SPECIALIZED_JIT_CALL 0 #endif // DISABLE_THREADS // mono_interp_tier_prepare_jiterpreter will return these special values if it doesn't @@ -149,8 +145,6 @@ mono_jiterp_monitor_trace (const guint16 *ip, void *frame, void *locals); #endif // __MONO_MINI_INTERPRETER_INTERNALS_H__ -extern WasmDoJitCall jiterpreter_do_jit_call; - #endif // HOST_BROWSER #endif // __MONO_MINI_JITERPRETER_H__ From 53c1d13c3a4f9fdf368bbff950da39ec71396525 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 20:25:45 -0600 Subject: [PATCH 598/783] Fixes exception while debugging on Chrome as IDE (#97871) Co-authored-by: Thays Grazia --- src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs index bbf199f0e79b63..d072301f84259c 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -1591,7 +1591,8 @@ internal virtual async Task OnSourceFileAdded(SessionId sessionId, SourceFile so await SendEvent(sessionId, "Debugger.scriptParsed", scriptSource, token); if (!resolveBreakpoints) return; - foreach (var req in context.BreakpointRequests.Values) + var breakpointRequests = context.BreakpointRequests.Values.ToList(); //this can be changed while we are looping it and cause an exception + foreach (var req in breakpointRequests) { if (req.TryResolve(source)) { From ea2b2e86419f2879c38f80a940b7d9f81209e7b5 Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Thu, 8 Feb 2024 23:28:50 -0300 Subject: [PATCH 599/783] Backport #97418 (#97568) --- src/mono/mono/component/debugger-agent.c | 59 ++++++++++-- .../BrowserDebugProxy/JObjectValueCreator.cs | 95 ++++++++++++++++++- .../BrowserDebugProxy/ValueTypeClass.cs | 20 +++- .../EvaluateOnCallFrame2Tests.cs | 23 +++++ .../debugger-test/debugger-evaluate-test.cs | 46 +++++++++ 5 files changed, 230 insertions(+), 13 deletions(-) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index 7cc565cbf5ffd2..c9199635d15d59 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -5477,6 +5477,52 @@ decode_fixed_size_array_internal (MonoType *t, int type, MonoDomain *domain, gui return err; } +static int +decode_fixed_size_array_compute_size_internal (MonoType *t, int type, MonoDomain *domain, guint8 *buf, guint8 **endbuf, guint8 *limit) +{ + int ret = 0; + int fixedSizeLen = 1; + int newType = MONO_TYPE_END; + if (CHECK_PROTOCOL_VERSION (2, 53)) { + newType = decode_byte (buf, &buf, limit); + fixedSizeLen = decode_int (buf, &buf, limit); + //t->type = newType; + } + for (int i = 0 ; i < fixedSizeLen; i++) { + switch (newType) { + case MONO_TYPE_BOOLEAN: + case MONO_TYPE_I1: + case MONO_TYPE_U1: + decode_int (buf, &buf, limit); + ret += sizeof(guint8); + break; + case MONO_TYPE_CHAR: + decode_int (buf, &buf, limit); + ret += sizeof(gunichar2); + break; + case MONO_TYPE_I2: + case MONO_TYPE_U2: + decode_int (buf, &buf, limit); + ret += sizeof(guint16); + break; + case MONO_TYPE_I4: + case MONO_TYPE_U4: + case MONO_TYPE_R4: + decode_int (buf, &buf, limit); + ret += sizeof(guint32); + break; + case MONO_TYPE_I8: + case MONO_TYPE_U8: + case MONO_TYPE_R8: + decode_long (buf, &buf, limit); + ret += sizeof(guint64); + break; + } + } + *endbuf = buf; + return ret; +} + static int decode_vtype_compute_size (MonoType *t, MonoDomain *domain, gpointer void_buf, guint8 **endbuf, guint8 *limit, gboolean from_by_ref_value_type) { @@ -5540,7 +5586,6 @@ decode_value_compute_size (MonoType *t, int type, MonoDomain *domain, guint8 *bu if (type == 0) type = decode_byte (buf, &buf, limit); int ret = 0; - ErrorCode err; if (type != t->type && !MONO_TYPE_IS_REFERENCE (t) && !(t->type == MONO_TYPE_I && type == MONO_TYPE_VALUETYPE) && !(type == VALUE_TYPE_ID_FIXED_ARRAY) && @@ -5555,7 +5600,7 @@ decode_value_compute_size (MonoType *t, int type, MonoDomain *domain, guint8 *bu goto end; } if (type == VALUE_TYPE_ID_FIXED_ARRAY && t->type != MONO_TYPE_VALUETYPE) { - //decode_fixed_size_array_internal (t, type, domain, addr, buf, endbuf, limit, check_field_datatype); + ret += decode_fixed_size_array_compute_size_internal (t, type, domain, buf, &buf, limit); goto end; } switch (t->type) { @@ -5626,13 +5671,6 @@ decode_value_compute_size (MonoType *t, int type, MonoDomain *domain, guint8 *bu decode_int (buf, &buf, limit); //not used } } else if (type == MONO_TYPE_VALUETYPE) { - MonoDomain *d; - decode_byte (buf, &buf, limit); - if (CHECK_PROTOCOL_VERSION(2, 61)) - decode_byte (buf, &buf, limit); //ignore is boxed - if (CHECK_PROTOCOL_VERSION(2, 65)) - decode_int (buf, &buf, limit); //ignore inline array - decode_typeid (buf, &buf, limit, &d, &err); ret += decode_vtype_compute_size (NULL, domain, buf, &buf, limit, from_by_ref_value_type); } else { goto end; @@ -5678,7 +5716,8 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr, return ERR_INVALID_ARGUMENT; } if (type == VALUE_TYPE_ID_FIXED_ARRAY && t->type != MONO_TYPE_VALUETYPE) { - decode_fixed_size_array_internal (t, type, domain, addr, buf, endbuf, limit, check_field_datatype); + decode_fixed_size_array_internal (t, type, domain, addr, buf, &buf, limit, check_field_datatype); + *endbuf = buf; return ERR_NONE; } diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/JObjectValueCreator.cs b/src/mono/wasm/debugger/BrowserDebugProxy/JObjectValueCreator.cs index 4231ac31967fa9..722c5a4aac3660 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/JObjectValueCreator.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/JObjectValueCreator.cs @@ -104,7 +104,6 @@ public async Task ReadAsVariableValue( case ElementType.U: case ElementType.Void: case (ElementType)ValueTypeId.VType: - case (ElementType)ValueTypeId.FixedArray: ret = Create(value: "void", type: "void", description: "void"); break; case ElementType.Boolean: @@ -419,4 +418,98 @@ private async Task ReadAsArray(MonoBinaryReader retDebuggerCmdReader, C objectId: "dotnet:array:" + objectId, subtype: length.Rank == 1 ? "array" : null); } + + public async Task CreateFixedArrayElement(MonoBinaryReader retDebuggerCmdReader, ElementType etype, string name, CancellationToken token) + { + JObject ret = null; + switch (etype) + { + case ElementType.I: + case ElementType.U: + case ElementType.Void: + case (ElementType)ValueTypeId.VType: + ret = Create(value: "void", type: "void", description: "void"); + break; + case ElementType.Boolean: + { + var value = retDebuggerCmdReader.ReadInt32(); + ret = CreateFromPrimitiveType(value == 1); + break; + } + case ElementType.I1: + { + var value = retDebuggerCmdReader.ReadSByte(); + ret = CreateJObjectForNumber(value); + break; + } + case ElementType.I2: + case ElementType.I4: + { + var value = retDebuggerCmdReader.ReadInt32(); + ret = CreateJObjectForNumber(value); + break; + } + case ElementType.U1: + { + var value = retDebuggerCmdReader.ReadUByte(); + ret = CreateJObjectForNumber(value); + break; + } + case ElementType.U2: + { + var value = retDebuggerCmdReader.ReadUShort(); + ret = CreateJObjectForNumber(value); + break; + } + case ElementType.U4: + { + var value = retDebuggerCmdReader.ReadUInt32(); + ret = CreateJObjectForNumber(value); + break; + } + case ElementType.R4: + { + float value = retDebuggerCmdReader.ReadSingle(); + ret = CreateJObjectForNumber(value); + break; + } + case ElementType.Char: + { + var value = retDebuggerCmdReader.ReadInt32(); + ret = CreateJObjectForChar(value); + break; + } + case ElementType.I8: + { + long value = retDebuggerCmdReader.ReadInt64(); + ret = CreateJObjectForNumber(value); + break; + } + case ElementType.U8: + { + ulong value = retDebuggerCmdReader.ReadUInt64(); + ret = CreateJObjectForNumber(value); + break; + } + case ElementType.R8: + { + double value = retDebuggerCmdReader.ReadDouble(); + ret = CreateJObjectForNumber(value); + break; + } + case ElementType.FnPtr: + case ElementType.Ptr: + { + ret = await ReadAsPtrValue(etype, retDebuggerCmdReader, name, token); + break; + } + default: + { + _logger.LogDebug($"Could not evaluate CreateFixedArrayElement invalid type {etype}"); + break; + } + } + ret["name"] = name; + return ret; + } } diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/ValueTypeClass.cs b/src/mono/wasm/debugger/BrowserDebugProxy/ValueTypeClass.cs index 59bc7b580ead93..85050d584f4279 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/ValueTypeClass.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/ValueTypeClass.cs @@ -83,8 +83,24 @@ public static async Task CreateFromReader( && !f.Attributes.HasFlag(FieldAttributes.Static)); foreach (var field in writableFields) { - lastWritableFieldValue = await sdbAgent.ValueCreator.ReadAsVariableValue(cmdReader, field.Name, token, isOwn: true, field.TypeId, forDebuggerDisplayAttribute: false); - fields.Add(GetFieldWithMetadata(field, lastWritableFieldValue, isStatic: false)); + //check if it's fixed size array and behave as a inline array + ElementType etype = (ElementType)cmdReader.ReadByte(); + if (etype == (ElementType)ValueTypeId.FixedArray && writableFields.Count() == 1) + { + ElementType elementType = (ElementType)cmdReader.ReadByte(); + var arraySize = cmdReader.ReadInt32(); + inlineArray = new(arraySize + 1); + for (int i = 0; i < arraySize; i++) + { + inlineArray.Add(await sdbAgent.ValueCreator.CreateFixedArrayElement(cmdReader, elementType, $"{i}", token)); + } + } + else + { + cmdReader.BaseStream.Position-=sizeof(byte); + lastWritableFieldValue = await sdbAgent.ValueCreator.ReadAsVariableValue(cmdReader, field.Name, token, isOwn: true, field.TypeId, forDebuggerDisplayAttribute: false); + fields.Add(GetFieldWithMetadata(field, lastWritableFieldValue, isStatic: false)); + } } if (inlineArraySize > 0) { diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs index b1a79b28ceeefe..ed034d91468665 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs @@ -749,5 +749,28 @@ await EvaluateOnCallFrameAndCheck(id, ("f[f.numArray[f.numList[0]], f.numArray[f.numArray[i]]]", TNumber("4")) ); }); + + [Fact] + public async Task EvaluateValueTypeWithFixedArrayAndMoreFields() => await CheckInspectLocalsAtBreakpointSite( + "DebuggerTests.EvaluateValueTypeWithFixedArray", "run", 3, "DebuggerTests.EvaluateValueTypeWithFixedArray.run", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateValueTypeWithFixedArray:run'); })", + wait_for_event_fn: async (pause_location) => + { + await RuntimeEvaluateAndCheck( + ("myVar.MyMethod()", TNumber(13)), + ("myVar.myIntArray[0]", TNumber(1)), + ("myVar.myIntArray[1]", TNumber(2)), + ("myVar.myCharArray[2]", TChar('a'))); + }); + + [Fact] + public async Task EvaluateValueTypeWithObjectValueType() => await CheckInspectLocalsAtBreakpointSite( + "DebuggerTests.EvaluateValueTypeWithObjectValueType", "run", 3, "DebuggerTests.EvaluateValueTypeWithObjectValueType.run", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateValueTypeWithObjectValueType:run'); })", + wait_for_event_fn: async (pause_location) => + { + await RuntimeEvaluateAndCheck( + ("myVar.MyMethod()", TNumber(10))); + }); } } diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs index e46177ecc925b5..4f36197af79b42 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs @@ -2182,4 +2182,50 @@ public static void run() Console.WriteLine(dt); } } + public unsafe struct EvaluateValueTypeWithFixedArray + { + private fixed int myIntArray[4]; + private fixed char myCharArray[3]; + double myDouble; + public EvaluateValueTypeWithFixedArray() + { + myDouble = 10; + myIntArray[0] = 1; + myIntArray[1] = 2; + myCharArray[2] = 'a'; + } + public int MyMethod() + { + Console.WriteLine(myDouble); + return myIntArray[0] + myIntArray[1] + (int)myDouble; + } + public static void run() + { + var myVar = new EvaluateValueTypeWithFixedArray(); + Console.WriteLine("pause here"); + myVar.MyMethod(); + } + } + + public struct EvaluateValueTypeWithObjectValueType + { + private object myObject; + double myDouble; + public EvaluateValueTypeWithObjectValueType() + { + myObject = new int(); + myDouble = 10; + } + public int MyMethod() + { + Console.WriteLine(myDouble); + return (int)myObject + (int)myDouble; + } + public static void run() + { + var myVar = new EvaluateValueTypeWithObjectValueType(); + Console.WriteLine("pause here"); + myVar.MyMethod(); + } + } } \ No newline at end of file From 279fe234c7dda7faaaa693644f7de4e029e77c29 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 10:42:06 -0800 Subject: [PATCH 600/783] Update dependencies from https://github.com/dotnet/runtime-assets build 20240208.4 (#98224) Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24068.2 -> To Version 8.0.0-beta.24108.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 56 ++++++++++++++++++++--------------------- eng/Versions.props | 28 ++++++++++----------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1e47771d2b3a7c..04a7792f12c29a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -185,57 +185,57 @@ https://github.com/dotnet/arcade 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 https://github.com/dotnet/llvm-project @@ -358,9 +358,9 @@ https://github.com/dotnet/hotreload-utils bc857c64c5c5f1fc73048261e8f471c3310224d2 - + https://github.com/dotnet/runtime-assets - 15009138ff960446092497b67a13cc3dc00445f7 + ca6c46012f68934198ce0d303196c3ae179230f5 https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index c50a1008b5f25f..05d877f78822fa 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -143,20 +143,20 @@ 4.5.0 8.0.0-rc.1.23406.6 - 8.0.0-beta.24068.2 - 8.0.0-beta.24068.2 - 8.0.0-beta.24068.2 - 8.0.0-beta.24068.2 - 8.0.0-beta.24068.2 - 8.0.0-beta.24068.2 - 8.0.0-beta.24068.2 - 8.0.0-beta.24068.2 - 8.0.0-beta.24068.2 - 8.0.0-beta.24068.2 - 8.0.0-beta.24068.2 - 8.0.0-beta.24068.2 - 8.0.0-beta.24068.2 - 8.0.0-beta.24068.2 + 8.0.0-beta.24108.4 + 8.0.0-beta.24108.4 + 8.0.0-beta.24108.4 + 8.0.0-beta.24108.4 + 8.0.0-beta.24108.4 + 8.0.0-beta.24108.4 + 8.0.0-beta.24108.4 + 8.0.0-beta.24108.4 + 8.0.0-beta.24108.4 + 8.0.0-beta.24108.4 + 8.0.0-beta.24108.4 + 8.0.0-beta.24108.4 + 8.0.0-beta.24108.4 + 8.0.0-beta.24108.4 1.0.0-prerelease.23566.3 1.0.0-prerelease.23566.3 From eded9a50a7ba49dfb371d5d3a0eb0845b9339a69 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 12:01:13 -0800 Subject: [PATCH 601/783] [release/8.0-staging] Ensure that the Create(Dot(...)) optimization doesn't kick in for Vector2 pre SSE4.1 (#97074) * Ensure that the Create(Dot(...)) optimization doesn't kick in for Vector2 pre SSE4.1 * Make sure to use #if defined(...) * Add missing using * Fix a type in the test --------- Co-authored-by: Tanner Gooding --- src/coreclr/jit/morph.cpp | 10 +++++ .../JitBlue/Runtime_96939/Runtime_96939.cs | 38 +++++++++++++++++++ .../Runtime_96939/Runtime_96939.csproj | 10 +++++ 3 files changed, 58 insertions(+) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_96939/Runtime_96939.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_96939/Runtime_96939.csproj diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 3deada8eec085b..b20cd585882b87 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -10724,6 +10724,16 @@ GenTree* Compiler::fgOptimizeHWIntrinsic(GenTreeHWIntrinsic* node) break; } +#if defined(TARGET_XARCH) + if ((node->GetSimdSize() == 8) && !compOpportunisticallyDependsOn(InstructionSet_SSE41)) + { + // When SSE4.1 isn't supported then Vector2 only needs a single horizontal add + // which means the result isn't broadcast across the entire vector and we can't + // optimize + break; + } +#endif // TARGET_XARCH + GenTree* op1 = node->Op(1); GenTree* sqrt = nullptr; GenTree* toScalar = nullptr; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_96939/Runtime_96939.cs b/src/tests/JIT/Regression/JitBlue/Runtime_96939/Runtime_96939.cs new file mode 100644 index 00000000000000..ac26af680eea80 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_96939/Runtime_96939.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using Xunit; + +public static class Runtime_96939 +{ + [Fact] + [MethodImpl(MethodImplOptions.AggressiveOptimization)] + public static void Problem() + { + Assert.Equal(new Vector2(13), TestVector2(new Vector2(2, 3))); + Assert.Equal(new Vector3(29), TestVector3(new Vector3(2, 3, 4))); + Assert.Equal(new Vector4(54), TestVector4(new Vector4(2, 3, 4, 5))); + } + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + public static Vector2 TestVector2(Vector2 value) + { + return Vector2.Dot(value, value) * new Vector2(1, 1); + } + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + public static Vector3 TestVector3(Vector3 value) + { + return Vector3.Dot(value, value) * new Vector3(1, 1, 1); + } + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + public static Vector4 TestVector4(Vector4 value) + { + return Vector4.Dot(value, value) * new Vector4(1, 1, 1, 1); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_96939/Runtime_96939.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_96939/Runtime_96939.csproj new file mode 100644 index 00000000000000..596f2374a8fb3b --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_96939/Runtime_96939.csproj @@ -0,0 +1,10 @@ + + + True + None + true + + + + + From a143568343ac8956caf9f64264af877e2cf288e8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 12:01:23 -0800 Subject: [PATCH 602/783] Don't clean up thread list on shutdown (#97188) Co-authored-by: David Mason --- src/native/eventpipe/ep-thread.c | 13 ------------- src/native/eventpipe/ep-thread.h | 3 --- src/native/eventpipe/ep.c | 15 --------------- 3 files changed, 31 deletions(-) diff --git a/src/native/eventpipe/ep-thread.c b/src/native/eventpipe/ep-thread.c index 93c87d4b8b4965..b720bf592d0c4d 100644 --- a/src/native/eventpipe/ep-thread.c +++ b/src/native/eventpipe/ep-thread.c @@ -93,19 +93,6 @@ ep_thread_init (void) EP_UNREACHABLE ("Failed to allocate threads list."); } -void -ep_thread_fini (void) -{ - // If threads are still included in list (depending on runtime shutdown order), - // don't clean up since TLS destructor migh callback freeing items, no new - // threads should however not be added to list at this stage. - if (dn_list_empty (_ep_threads)) { - dn_list_free (_ep_threads); - _ep_threads = NULL; - ep_rt_spin_lock_free (&_ep_threads_lock); - } -} - bool ep_thread_register (EventPipeThread *thread) { diff --git a/src/native/eventpipe/ep-thread.h b/src/native/eventpipe/ep-thread.h index c3f8fd7cd71a74..44c683b52d57f8 100644 --- a/src/native/eventpipe/ep-thread.h +++ b/src/native/eventpipe/ep-thread.h @@ -92,9 +92,6 @@ ep_thread_release (EventPipeThread *thread); void ep_thread_init (void); -void -ep_thread_fini (void); - bool ep_thread_register (EventPipeThread *thread); diff --git a/src/native/eventpipe/ep.c b/src/native/eventpipe/ep.c index d007702dde463f..34c84e874458aa 100644 --- a/src/native/eventpipe/ep.c +++ b/src/native/eventpipe/ep.c @@ -1453,21 +1453,6 @@ ep_shutdown (void) dn_vector_free (_ep_deferred_disable_session_ids); _ep_deferred_disable_session_ids = NULL; - ep_thread_fini (); - - // dotnet/coreclr: issue 24850: EventPipe shutdown race conditions - // Deallocating providers/events here might cause AV if a WriteEvent - // was to occur. Thus, we are not doing this cleanup. - - /*EP_LOCK_ENTER (section1) - ep_sample_profiler_shutdown (); - EP_LOCK_EXIT (section1)*/ - - // // Remove EventPipeEventSource first since it tries to use the data structures that we remove below. - // // We need to do this after disabling sessions since those try to write to EventPipeEventSource. - // ep_event_source_fini (ep_event_source_get ()); - // ep_config_shutdown (ep_config_get ()); - ep_on_exit: ep_requires_lock_not_held (); ep_rt_shutdown (); From 2767a15a0817dd9858a3cc90ac3aa44f37e8e7da Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Fri, 9 Feb 2024 22:01:52 +0200 Subject: [PATCH 603/783] [mono][interp] Fix inlining of ldarga (#97650) When inlining a method, all arguments are first copied to new vars. Ldarga is going to be applied on these copies. We were loading the address of the wrong var due to typo. --- src/mono/mono/mini/interp/transform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 06396bc063fbcf..0d5ef5380de266 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -8018,7 +8018,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, } else { int loc_n = arg_locals [n]; interp_add_ins (td, MINT_LDLOCA_S); - interp_ins_set_sreg (td->last_ins, n); + interp_ins_set_sreg (td->last_ins, loc_n); td->locals [loc_n].indirects++; } push_simple_type (td, STACK_TYPE_MP); From ef1b0d681999223ad6ecd493fbc02792346861f3 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Fri, 9 Feb 2024 15:02:02 -0500 Subject: [PATCH 604/783] [release/8.0-staging] [mono][jit] Fix passing of byref arguments in mono_gsharedvt_constrained_call (). (#97721) (#97850) Fixes https://github.com/dotnet/runtime/issues/97625. Co-authored-by: Larry Ewing --- src/mono/mono/mini/jit-icalls.c | 3 ++- .../JitBlue/Runtime_97625/Runtime_97625.cs | 23 +++++++++++++++++++ .../Runtime_97625/Runtime_97625.csproj | 8 +++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_97625/Runtime_97625.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_97625/Runtime_97625.csproj diff --git a/src/mono/mono/mini/jit-icalls.c b/src/mono/mono/mini/jit-icalls.c index 628d18abe35cfd..24ec1b65dcf566 100644 --- a/src/mono/mono/mini/jit-icalls.c +++ b/src/mono/mono/mini/jit-icalls.c @@ -1482,7 +1482,8 @@ mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *kl g_assert (fsig->param_count < 16); memcpy (new_args, args, fsig->param_count * sizeof (gpointer)); for (int i = 0; i < fsig->param_count; ++i) { - if (deref_args [i]) + // If the argument is not a vtype or nullable, deref it + if (deref_args [i] && (deref_args [i] != MONO_GSHAREDVT_BOX_TYPE_VTYPE && deref_args [i] != MONO_GSHAREDVT_BOX_TYPE_NULLABLE)) new_args [i] = *(gpointer*)new_args [i]; } args = new_args; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_97625/Runtime_97625.cs b/src/tests/JIT/Regression/JitBlue/Runtime_97625/Runtime_97625.cs new file mode 100644 index 00000000000000..2a2ad6b87873a1 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_97625/Runtime_97625.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +public static class Runtime_97625 +{ + public class CustomModel + { + public decimal Cost { get; set; } + } + + [Fact] + public static int Test() + { + List models = new List(); + models.Add(new CustomModel { Cost = 1 }); + return models.Average (x => x.Cost) == 1 ? 100 : -1; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_97625/Runtime_97625.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_97625/Runtime_97625.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_97625/Runtime_97625.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From 4b040aa6f0ed16c9c75e02e9d71a22b2afe49383 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Fri, 9 Feb 2024 12:02:11 -0800 Subject: [PATCH 605/783] Stop trying to format HOST_RUNTIME_CONTRACT property with locale settings (#97891) --- src/native/corehost/hostpolicy/deps_resolver.cpp | 3 ++- src/native/corehost/hostpolicy/hostpolicy_context.cpp | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/native/corehost/hostpolicy/deps_resolver.cpp b/src/native/corehost/hostpolicy/deps_resolver.cpp index beedcef62cd06b..66d44f0c17dae0 100644 --- a/src/native/corehost/hostpolicy/deps_resolver.cpp +++ b/src/native/corehost/hostpolicy/deps_resolver.cpp @@ -280,7 +280,8 @@ bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::str for (const auto& config : m_probes) { - trace::verbose(_X(" Using probe config: %s"), config.as_str().c_str()); + if (trace::is_enabled()) + trace::verbose(_X(" Using probe config: %s"), config.as_str().c_str()); if (config.is_servicing() && !entry.is_serviceable) { diff --git a/src/native/corehost/hostpolicy/hostpolicy_context.cpp b/src/native/corehost/hostpolicy/hostpolicy_context.cpp index f8d220d8130e07..1ceb961f8df367 100644 --- a/src/native/corehost/hostpolicy/hostpolicy_context.cpp +++ b/src/native/corehost/hostpolicy/hostpolicy_context.cpp @@ -378,9 +378,9 @@ int hostpolicy_context_t::initialize(const hostpolicy_init_t &hostpolicy_init, c } host_contract.get_runtime_property = &get_runtime_property; - pal::stringstream_t ptr_stream; - ptr_stream << "0x" << std::hex << (size_t)(&host_contract); - if (!coreclr_properties.add(_STRINGIFY(HOST_PROPERTY_RUNTIME_CONTRACT), ptr_stream.str().c_str())) + pal::char_t buffer[STRING_LENGTH("0xffffffffffffffff")]; + pal::snwprintf(buffer, ARRAY_SIZE(buffer), _X("0x%zx"), (size_t)(&host_contract)); + if (!coreclr_properties.add(_STRINGIFY(HOST_PROPERTY_RUNTIME_CONTRACT), buffer)) { log_duplicate_property_error(_STRINGIFY(HOST_PROPERTY_RUNTIME_CONTRACT)); return StatusCode::LibHostDuplicateProperty; From 6cd0eddba867045259663f3c83b9567eb7dc3b46 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 9 Feb 2024 12:02:38 -0800 Subject: [PATCH 606/783] Backport of Handle open types to appear in interface maps (#97733) to release/8.0-staging (#98182) - Reflection IsAssignableFrom api - As well as constraint checking --- src/coreclr/vm/methodtable.cpp | 13 +-- src/coreclr/vm/methodtable.h | 15 +++- src/coreclr/vm/methodtable.inl | 3 +- src/coreclr/vm/methodtablebuilder.cpp | 5 ++ .../CuriouslyRecurringThroughInterface.cs | 85 ++++++++++++++++++- 5 files changed, 107 insertions(+), 14 deletions(-) diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 688bf29079e08d..76aab1f8b2d312 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -1433,7 +1433,7 @@ BOOL MethodTable::CanCastToInterface(MethodTable *pTargetMT, TypeHandlePairList if (CanCastByVarianceToInterfaceOrDelegate(pTargetMT, pVisited)) return TRUE; - if (pTargetMT->IsSpecialMarkerTypeForGenericCasting()) + if (pTargetMT->IsSpecialMarkerTypeForGenericCasting() && !GetWriteableData()->MayHaveOpenInterfacesInInterfaceMap()) return FALSE; // The special marker types cannot be cast to (at this time, they are the open generic types, so they are however, valid input to this method). InterfaceMapIterator it = IterateInterfaceMap(); @@ -1470,7 +1470,7 @@ BOOL MethodTable::CanCastByVarianceToInterfaceOrDelegate(MethodTable *pTargetMT, // Shortcut for generic approx type scenario if (pMTInterfaceMapOwner != NULL && - !pMTInterfaceMapOwner->ContainsGenericVariables() && + !pMTInterfaceMapOwner->GetWriteableData()->MayHaveOpenInterfacesInInterfaceMap() && IsSpecialMarkerTypeForGenericCasting() && GetTypeDefRid() == pTargetMT->GetTypeDefRid() && GetModule() == pTargetMT->GetModule() && @@ -1497,7 +1497,7 @@ BOOL MethodTable::CanCastByVarianceToInterfaceOrDelegate(MethodTable *pTargetMT, for (DWORD i = 0; i < inst.GetNumArgs(); i++) { TypeHandle thArg = inst[i]; - if (IsSpecialMarkerTypeForGenericCasting() && pMTInterfaceMapOwner && !pMTInterfaceMapOwner->ContainsGenericVariables()) + if (IsSpecialMarkerTypeForGenericCasting() && pMTInterfaceMapOwner && !pMTInterfaceMapOwner->GetWriteableData()->MayHaveOpenInterfacesInInterfaceMap()) { thArg = pMTInterfaceMapOwner; } @@ -1957,7 +1957,7 @@ NOINLINE BOOL MethodTable::ImplementsInterface(MethodTable *pInterface) { WRAPPER_NO_CONTRACT; - if (pInterface->IsSpecialMarkerTypeForGenericCasting()) + if (pInterface->IsSpecialMarkerTypeForGenericCasting() && !GetWriteableData()->MayHaveOpenInterfacesInInterfaceMap()) return FALSE; // The special marker types cannot be cast to (at this time, they are the open generic types, so they are however, valid input to this method). return ImplementsInterfaceInline(pInterface); @@ -1974,7 +1974,7 @@ BOOL MethodTable::ImplementsEquivalentInterface(MethodTable *pInterface) } CONTRACTL_END; - if (pInterface->IsSpecialMarkerTypeForGenericCasting()) + if (pInterface->IsSpecialMarkerTypeForGenericCasting() && !GetWriteableData()->MayHaveOpenInterfacesInInterfaceMap()) return FALSE; // The special marker types cannot be cast to (at this time, they are the open generic types, so they are however, valid input to this method). // look for exact match first (optimize for success) @@ -9568,12 +9568,13 @@ PTR_MethodTable MethodTable::InterfaceMapIterator::GetInterface(MethodTable* pMT GC_TRIGGERS; THROWS; PRECONDITION(m_i != (DWORD) -1 && m_i < m_count); + PRECONDITION(CheckPointer(pMTOwner)); POSTCONDITION(CheckPointer(RETVAL)); } CONTRACT_END; MethodTable *pResult = m_pMap->GetMethodTable(); - if (pResult->IsSpecialMarkerTypeForGenericCasting() && !pMTOwner->ContainsGenericVariables()) + if (pResult->IsSpecialMarkerTypeForGenericCasting() && !pMTOwner->GetWriteableData()->MayHaveOpenInterfacesInInterfaceMap()) { TypeHandle ownerAsInst[MaxGenericParametersForSpecialMarkerType]; for (DWORD i = 0; i < MaxGenericParametersForSpecialMarkerType; i++) diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 69f16bec6ebdd4..f30fd7190f93c5 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -302,7 +302,7 @@ struct MethodTableWriteableData enum_flag_IsNotFullyLoaded = 0x00000040, enum_flag_DependenciesLoaded = 0x00000080, // class and all dependencies loaded up to CLASS_LOADED_BUT_NOT_VERIFIED - // enum_unused = 0x00000100, + enum_flag_MayHaveOpenInterfaceInInterfaceMap = 0x00000100, enum_flag_CanCompareBitsOrUseFastGetHashCode = 0x00000200, // Is any field type or sub field type overrode Equals or GetHashCode enum_flag_HasCheckedCanCompareBitsOrUseFastGetHashCode = 0x00000400, // Whether we have checked the overridden Equals or GetHashCode @@ -393,6 +393,17 @@ struct MethodTableWriteableData m_dwFlags &= ~(MethodTableWriteableData::enum_flag_HasApproxParent); } + + inline void SetMayHaveOpenInterfacesInInterfaceMap() + { + LIMITED_METHOD_CONTRACT; + InterlockedOr((LONG*)&m_dwFlags, MethodTableWriteableData::enum_flag_MayHaveOpenInterfaceInInterfaceMap); + } + + inline bool MayHaveOpenInterfacesInInterfaceMap() const + { + return !!(m_dwFlags & MethodTableWriteableData::enum_flag_MayHaveOpenInterfaceInInterfaceMap); + } }; // struct MethodTableWriteableData typedef DPTR(MethodTableWriteableData) PTR_MethodTableWriteableData; @@ -1970,7 +1981,7 @@ class MethodTable if (pCurrentMethodTable->HasSameTypeDefAs(pMT) && pMT->HasInstantiation() && pCurrentMethodTable->IsSpecialMarkerTypeForGenericCasting() && - !pMTOwner->ContainsGenericVariables() && + !pMTOwner->GetWriteableData()->MayHaveOpenInterfacesInInterfaceMap() && pMT->GetInstantiation().ContainsAllOneType(pMTOwner)) { exactMatch = true; diff --git a/src/coreclr/vm/methodtable.inl b/src/coreclr/vm/methodtable.inl index 777080c7590179..f8b62de3e35d44 100644 --- a/src/coreclr/vm/methodtable.inl +++ b/src/coreclr/vm/methodtable.inl @@ -1395,7 +1395,6 @@ FORCEINLINE BOOL MethodTable::ImplementsInterfaceInline(MethodTable *pInterface) NOTHROW; GC_NOTRIGGER; PRECONDITION(pInterface->IsInterface()); // class we are looking up should be an interface - PRECONDITION(!pInterface->IsSpecialMarkerTypeForGenericCasting()); } CONTRACTL_END; @@ -1428,7 +1427,7 @@ FORCEINLINE BOOL MethodTable::ImplementsInterfaceInline(MethodTable *pInterface) while (--numInterfaces); // Second scan, looking for the curiously recurring generic scenario - if (pInterface->HasInstantiation() && !ContainsGenericVariables() && pInterface->GetInstantiation().ContainsAllOneType(this)) + if (pInterface->HasInstantiation() && !GetWriteableData()->MayHaveOpenInterfacesInInterfaceMap() && pInterface->GetInstantiation().ContainsAllOneType(this)) { numInterfaces = GetNumInterfaces(); pInfo = GetInterfaceMap(); diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 47024106985eee..76ac3e7601768c 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -9341,6 +9341,10 @@ MethodTableBuilder::LoadExactInterfaceMap(MethodTable *pMT) // to represent a type instantiated over its own generic variables, and the special marker type is currently the open type // and we make this case distinguishable by simply disallowing the optimization in those cases. bool retryWithExactInterfaces = !pMT->IsValueType() || pMT->IsSharedByGenericInstantiations() || pMT->ContainsGenericVariables(); + if (retryWithExactInterfaces) + { + pMT->GetWriteableDataForWrite()->SetMayHaveOpenInterfacesInInterfaceMap(); + } DWORD nAssigned = 0; do @@ -9407,6 +9411,7 @@ MethodTableBuilder::LoadExactInterfaceMap(MethodTable *pMT) if (retry) { + pMT->GetWriteableDataForWrite()->SetMayHaveOpenInterfacesInInterfaceMap(); retryWithExactInterfaces = true; } } while (retry); diff --git a/src/tests/Loader/classloader/generics/Instantiation/Positive/CuriouslyRecurringThroughInterface.cs b/src/tests/Loader/classloader/generics/Instantiation/Positive/CuriouslyRecurringThroughInterface.cs index 0a091e138a876b..e74a23632c7b9a 100644 --- a/src/tests/Loader/classloader/generics/Instantiation/Positive/CuriouslyRecurringThroughInterface.cs +++ b/src/tests/Loader/classloader/generics/Instantiation/Positive/CuriouslyRecurringThroughInterface.cs @@ -1,3 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; + namespace CuriouslyRecurringPatternThroughInterface { interface IGeneric @@ -10,14 +16,85 @@ class CuriouslyRecurringThroughInterface : { } - class Program + class BaseClassWhereAImplementsB where A : B {} + interface ICuriouslyRecurring2 : IGeneric> + { + } + class DerivedCuriouslyRecurringThroughInterface : BaseClassWhereAImplementsB,ICuriouslyRecurring2>, ICuriouslyRecurring2 + { + } + + public class Program { static object _o; - static int Main() + + public static int Main() + { + TestIfCuriouslyRecurringInterfaceCanBeLoaded(); + TestIfCuriouslyRecurringInterfaceCanCast(); + TestIfCuriouslyRecurringInterfaceCanBeUsedAsConstraint(); + TestIfCuriouslyRecurringInterfaceCanBeUsedAsConstraintWorker(); + return 100; // Failures cause exceptions + } + + public static void TestIfCuriouslyRecurringInterfaceCanBeLoaded() { + Console.WriteLine("TestIfCuriouslyRecurringInterfaceCanBeLoaded"); + // Test that the a generic using a variant of the curiously recurring pattern involving an interface can be loaded. _o = typeof(CuriouslyRecurringThroughInterface); - return 100; + Console.WriteLine("Found type: {0}", _o); + Console.WriteLine("Curiously recurring interface: {0}", typeof(ICuriouslyRecurring<>)); + Console.WriteLine("typeof(ICuriouslyRecurring<>).GetGenericArguments()[0]: {0}", typeof(ICuriouslyRecurring<>).GetGenericArguments()[0]); + Console.WriteLine("typeof(ICuriouslyRecurring<>).GetInterfaces().Length: {0}", typeof(ICuriouslyRecurring<>).GetInterfaces().Length); + Console.WriteLine("typeof(ICuriouslyRecurring<>).GetInterfaces()[0]: {0}", typeof(ICuriouslyRecurring<>).GetInterfaces()[0]); + Console.WriteLine("typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments().Length: {0}", typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments().Length); + Console.WriteLine("typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0]: {0}", typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0]); + Console.WriteLine("typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetGenericArguments()[0]: {0}", typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetGenericArguments()[0]); + Console.WriteLine("typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetGenericArguments()[0]==typeof(ICuriouslyRecurring<>).GetGenericArguments()[0]: {0}", typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetGenericArguments()[0]==typeof(ICuriouslyRecurring<>).GetGenericArguments()[0]); + if (!(typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetGenericArguments()[0]==typeof(ICuriouslyRecurring<>).GetGenericArguments()[0])) + { + throw new Exception("Fail checking for condition that should be true - 2"); + } + + Console.WriteLine("typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetInterfaces().Length: {0}", typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetInterfaces().Length); + + // On CoreCLR this gets the Open type, which isn't really correct, but it has been that way for a very long time + Console.WriteLine("typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetInterfaces()[0]: {0}", typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetInterfaces()[0]); + Console.WriteLine("typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetInterfaces()[0]==typeof(ICuriouslyRecurring<>): {0}", typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetInterfaces()[0]==typeof(ICuriouslyRecurring<>)); + + Console.WriteLine("typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetInterfaces()[0].GetGenericTypeDefinition()==typeof(ICuriouslyRecurring<>): {0}", typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetInterfaces()[0].GetGenericTypeDefinition()==typeof(ICuriouslyRecurring<>)); + + Console.WriteLine("typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetInterfaces()[0].GetGenericArguments()[0]==typeof(ICuriouslyRecurring<>)GetGenericArguments()[0]: {0}", typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetInterfaces()[0].GetGenericArguments()[0]==typeof(ICuriouslyRecurring<>).GetGenericArguments()[0]); + if (!(typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0].GetInterfaces()[0].GetGenericArguments()[0]==typeof(ICuriouslyRecurring<>).GetGenericArguments()[0])) + { + throw new Exception("Fail checking for condition that should be true - 2"); + } + } + + public static void TestIfCuriouslyRecurringInterfaceCanCast() + { + Console.WriteLine("TestIfCuriouslyRecurringInterfaceCanCast"); + Console.WriteLine("typeof(ICuriouslyRecurring<>).MakeGenericType(typeof(ICuriouslyRecurring<>).GetGenericArguments()[0]).IsAssignableFrom(typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0]): {0}", typeof(ICuriouslyRecurring<>).MakeGenericType(typeof(ICuriouslyRecurring<>).GetGenericArguments()[0]).IsAssignableFrom(typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0])); + if (!(typeof(ICuriouslyRecurring<>).MakeGenericType(typeof(ICuriouslyRecurring<>).GetGenericArguments()[0]).IsAssignableFrom(typeof(ICuriouslyRecurring<>).GetInterfaces()[0].GetGenericArguments()[0]))) + { + throw new Exception("Fail"); + } + } + + public static void TestIfCuriouslyRecurringInterfaceCanBeUsedAsConstraint() + { + Console.WriteLine("TestIfCuriouslyRecurringInterfaceCanBeUsedAsConstraint"); + TestIfCuriouslyRecurringInterfaceCanBeUsedAsConstraintWorker(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void TestIfCuriouslyRecurringInterfaceCanBeUsedAsConstraintWorker() + { + // Test that the a generic using a variant of the curiously recurring pattern involving an interface and constraint can be loaded. + // This test is just like TestIfCuriouslyRecurringInterfaceCanBeLoaded, except that it is structured so that we perform a cast via a constraint at type load time + _o = typeof(DerivedCuriouslyRecurringThroughInterface); + Console.WriteLine("Found type: {0}", _o); } } -} \ No newline at end of file +} From c804f58a6e594202c711a25281c80249e16079c2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 12:24:41 -0800 Subject: [PATCH 607/783] [release/8.0-staging] Move a lock to protect m_pDynamicStaticsInfo (#97352) * Move a lock to protect m_pDynamicStaticsInfo * apply feedback * cast to LONG * Fix access to m_pDynamicStaticsInfo (#97353) - Remove race condition where it is possible that an updated dynamic statics info pointer is published without ensuring that the data is also considered written. - Use VolatileLoadWithoutBarrier at the read site (where locks are not taken) to ensure that there are no difficult to examine reads of this pointer. --------- Co-authored-by: Hyungju Lee Co-authored-by: David Wrighton --- src/coreclr/vm/ceeload.cpp | 30 +++++++++++++----------------- src/coreclr/vm/ceeload.inl | 2 +- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp index 709ec1e5042984..f6e1cf37e4ebb5 100644 --- a/src/coreclr/vm/ceeload.cpp +++ b/src/coreclr/vm/ceeload.cpp @@ -1550,29 +1550,25 @@ DWORD Module::AllocateDynamicEntry(MethodTable *pMT) } CONTRACTL_END; - DWORD newId = InterlockedExchangeAdd((LONG*)&m_cDynamicEntries, 1); + CrstHolder ch(&m_Crst); + DWORD newId = (LONG)m_cDynamicEntries++; - if (newId >= VolatileLoad(&m_maxDynamicEntries)) + if (newId >= m_maxDynamicEntries) { - CrstHolder ch(&m_Crst); - - if (newId >= m_maxDynamicEntries) + SIZE_T maxDynamicEntries = max(16, m_maxDynamicEntries); + while (maxDynamicEntries <= newId) { - SIZE_T maxDynamicEntries = max(16, m_maxDynamicEntries); - while (maxDynamicEntries <= newId) - { - maxDynamicEntries *= 2; - } + maxDynamicEntries *= 2; + } - DynamicStaticsInfo* pNewDynamicStaticsInfo = (DynamicStaticsInfo*) - (void*)GetLoaderAllocator()->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(DynamicStaticsInfo)) * S_SIZE_T(maxDynamicEntries)); + DynamicStaticsInfo* pNewDynamicStaticsInfo = (DynamicStaticsInfo*) + (void*)GetLoaderAllocator()->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(DynamicStaticsInfo)) * S_SIZE_T(maxDynamicEntries)); - if (m_pDynamicStaticsInfo) - memcpy(pNewDynamicStaticsInfo, m_pDynamicStaticsInfo, sizeof(DynamicStaticsInfo) * m_maxDynamicEntries); + if (m_pDynamicStaticsInfo) + memcpy(pNewDynamicStaticsInfo, m_pDynamicStaticsInfo, sizeof(DynamicStaticsInfo) * m_maxDynamicEntries); - m_pDynamicStaticsInfo = pNewDynamicStaticsInfo; - VolatileStore(&m_maxDynamicEntries, maxDynamicEntries); - } + VolatileStore(&m_pDynamicStaticsInfo, pNewDynamicStaticsInfo); + m_maxDynamicEntries = maxDynamicEntries; } m_pDynamicStaticsInfo[newId].pEnclosingMT = pMT; diff --git a/src/coreclr/vm/ceeload.inl b/src/coreclr/vm/ceeload.inl index 8cd5189791b8c0..10bc879927a166 100644 --- a/src/coreclr/vm/ceeload.inl +++ b/src/coreclr/vm/ceeload.inl @@ -463,7 +463,7 @@ inline MethodTable* Module::GetDynamicClassMT(DWORD dynamicClassID) { LIMITED_METHOD_CONTRACT; _ASSERTE(m_cDynamicEntries > dynamicClassID); - return m_pDynamicStaticsInfo[dynamicClassID].pEnclosingMT; + return VolatileLoadWithoutBarrier(&m_pDynamicStaticsInfo)[dynamicClassID].pEnclosingMT; } #ifdef FEATURE_CODE_VERSIONING From f4075f3df6bc17138b591f99a151def41a7aa907 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sat, 10 Feb 2024 09:32:52 -0800 Subject: [PATCH 608/783] Ensure that constant folding for SIMD shifts on xarch follow the correct behavior on overshift (#98001) (#98066) * Ensure that constant folding for SIMD shifts on xarch follow the correct behavior on overshift * Ensure we test Sse2.IsSupported --- src/coreclr/jit/hwintrinsicxarch.cpp | 2 +- src/coreclr/jit/simd.h | 54 ++++++++++++- src/coreclr/jit/valuenum.cpp | 75 +++++++++++++++++++ .../JitBlue/Runtime_93698/Runtime_93698.cs | 49 ++++++++++++ .../Runtime_93698/Runtime_93698.csproj | 8 ++ 5 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_93698/Runtime_93698.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_93698/Runtime_93698.csproj diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 065999982a87a9..3c8410a47ae353 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -924,7 +924,7 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT GenTree* op2 = impPopStack().val; GenTree* op1 = impSIMDPopStack(); - GenTree* tmpOp = gtNewSimdCreateScalarUnsafeNode(TYP_SIMD16, op2, CORINFO_TYPE_INT, 16); + GenTree* tmpOp = gtNewSimdCreateScalarNode(TYP_SIMD16, op2, CORINFO_TYPE_INT, 16); return gtNewSimdHWIntrinsicNode(simdType, op1, tmpOp, intrinsic, simdBaseJitType, genTypeSize(simdType)); } diff --git a/src/coreclr/jit/simd.h b/src/coreclr/jit/simd.h index 478b0a1af4f4a3..9e8781714dbc41 100644 --- a/src/coreclr/jit/simd.h +++ b/src/coreclr/jit/simd.h @@ -453,7 +453,23 @@ void EvaluateUnarySimd(genTreeOps oper, bool scalar, var_types baseType, TSimd* template TBase EvaluateBinaryScalarRSZ(TBase arg0, TBase arg1) { - return arg0 >> (arg1 & ((sizeof(TBase) * 8) - 1)); +#if defined(TARGET_XARCH) + if ((arg1 < 0) || (arg1 >= (sizeof(TBase) * 8))) + { + // For SIMD, xarch allows overshifting and treats + // it as zeroing. So ensure we do the same here. + // + // The xplat APIs ensure the shiftAmount is masked + // to be within range, so we can't hit this for them. + + return static_cast(0); + } +#else + // Other platforms enforce masking in their encoding + assert((arg1 >= 0) && (arg1 < (sizeof(TBase) * 8))); +#endif + + return arg0 >> arg1; } template <> @@ -513,7 +529,22 @@ TBase EvaluateBinaryScalarSpecialized(genTreeOps oper, TBase arg0, TBase arg1) case GT_LSH: { - return arg0 << (arg1 & ((sizeof(TBase) * 8) - 1)); +#if defined(TARGET_XARCH) + if ((arg1 < 0) || (arg1 >= (sizeof(TBase) * 8))) + { + // For SIMD, xarch allows overshifting and treats + // it as zeroing. So ensure we do the same here. + // + // The xplat APIs ensure the shiftAmount is masked + // to be within range, so we can't hit this for them. + + return static_cast(0); + } +#else + // Other platforms enforce masking in their encoding + assert((arg1 >= 0) && (arg1 < (sizeof(TBase) * 8))); +#endif + return arg0 << arg1; } case GT_OR: @@ -535,7 +566,24 @@ TBase EvaluateBinaryScalarSpecialized(genTreeOps oper, TBase arg0, TBase arg1) case GT_RSH: { - return arg0 >> (arg1 & ((sizeof(TBase) * 8) - 1)); +#if defined(TARGET_XARCH) + if ((arg1 < 0) || (arg1 >= (sizeof(TBase) * 8))) + { + // For SIMD, xarch allows overshifting and treats + // it as propagating the sign bit (returning Zero + // or AllBitsSet). So ensure we do the same here. + // + // The xplat APIs ensure the shiftAmount is masked + // to be within range, so we can't hit this for them. + + arg0 >>= ((sizeof(TBase) * 8) - 1); + arg1 = static_cast(1); + } +#else + // Other platforms enforce masking in their encoding + assert((arg1 >= 0) && (arg1 < (sizeof(TBase) * 8))); +#endif + return arg0 >> arg1; } case GT_RSZ: diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 6943c3c5e07e26..259305a6aac7b1 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -7518,6 +7518,31 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary(var_types type, case NI_AVX512BW_ShiftLeftLogical: #endif { +#ifdef TARGET_XARCH + if (TypeOfVN(arg1VN) == TYP_SIMD16) + { + // The xarch shift instructions support taking the shift amount as + // a simd16, in which case they take the shift amount from the lower + // 64-bits. + + uint64_t shiftAmount = GetConstantSimd16(arg1VN).u64[0]; + + if (genTypeSize(baseType) != 8) + { + if (shiftAmount > INT_MAX) + { + // Ensure we don't lose track the the amount is an overshift + shiftAmount = -1; + } + arg1VN = VNForIntCon(static_cast(shiftAmount)); + } + else + { + arg1VN = VNForLongCon(static_cast(shiftAmount)); + } + } +#endif // TARGET_XARCH + return EvaluateBinarySimd(this, GT_LSH, /* scalar */ false, type, baseType, arg0VN, arg1VN); } @@ -7531,6 +7556,31 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary(var_types type, case NI_AVX512BW_ShiftRightArithmetic: #endif { +#ifdef TARGET_XARCH + if (TypeOfVN(arg1VN) == TYP_SIMD16) + { + // The xarch shift instructions support taking the shift amount as + // a simd16, in which case they take the shift amount from the lower + // 64-bits. + + uint64_t shiftAmount = GetConstantSimd16(arg1VN).u64[0]; + + if (genTypeSize(baseType) != 8) + { + if (shiftAmount > INT_MAX) + { + // Ensure we don't lose track the the amount is an overshift + shiftAmount = -1; + } + arg1VN = VNForIntCon(static_cast(shiftAmount)); + } + else + { + arg1VN = VNForLongCon(static_cast(shiftAmount)); + } + } +#endif // TARGET_XARCH + return EvaluateBinarySimd(this, GT_RSH, /* scalar */ false, type, baseType, arg0VN, arg1VN); } @@ -7543,6 +7593,31 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary(var_types type, case NI_AVX512BW_ShiftRightLogical: #endif { +#ifdef TARGET_XARCH + if (TypeOfVN(arg1VN) == TYP_SIMD16) + { + // The xarch shift instructions support taking the shift amount as + // a simd16, in which case they take the shift amount from the lower + // 64-bits. + + uint64_t shiftAmount = GetConstantSimd16(arg1VN).u64[0]; + + if (genTypeSize(baseType) != 8) + { + if (shiftAmount > INT_MAX) + { + // Ensure we don't lose track the the amount is an overshift + shiftAmount = -1; + } + arg1VN = VNForIntCon(static_cast(shiftAmount)); + } + else + { + arg1VN = VNForLongCon(static_cast(shiftAmount)); + } + } +#endif // TARGET_XARCH + return EvaluateBinarySimd(this, GT_RSZ, /* scalar */ false, type, baseType, arg0VN, arg1VN); } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_93698/Runtime_93698.cs b/src/tests/JIT/Regression/JitBlue/Runtime_93698/Runtime_93698.cs new file mode 100644 index 00000000000000..012387e9c656bc --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_93698/Runtime_93698.cs @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using Xunit; + +public static class Runtime_93698 +{ + [Fact] + public static void TestShiftLeftLogicalOvershift() + { + if (Sse2.IsSupported) + { + var result1 = Sse2.ShiftLeftLogical(Vector128.Create(-1, +2, -3, +4), 32); + Assert.Equal(Vector128.Zero, result1); + + var result2 = Sse2.ShiftLeftLogical(Vector128.Create(-5, +6, -7, +8), Vector128.Create(0, 32, 0, 0)); + Assert.Equal(Vector128.Zero, result2); + } + } + + [Fact] + public static void TestShiftRightLogicalOvershift() + { + if (Sse2.IsSupported) + { + var result1 = Sse2.ShiftRightLogical(Vector128.Create(-1, +2, -3, +4), 32); + Assert.Equal(Vector128.Zero, result1); + + var result2 = Sse2.ShiftRightLogical(Vector128.Create(-5, +6, -7, +8), Vector128.Create(0, 32, 0, 0)); + Assert.Equal(Vector128.Zero, result2); + } + } + + [Fact] + public static void TestShiftRightArithmeticOvershift() + { + if (Sse2.IsSupported) + { + var result1 = Sse2.ShiftRightArithmetic(Vector128.Create(-1, +2, -3, +4), 32); + Assert.Equal(Vector128.Create(-1, 0, -1, 0), result1); + + var result2 = Sse2.ShiftRightArithmetic(Vector128.Create(-5, +6, -7, +8), Vector128.Create(0, 32, 0, 0)); + Assert.Equal(Vector128.Create(-1, 0, -1, 0), result2); + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_93698/Runtime_93698.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_93698/Runtime_93698.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_93698/Runtime_93698.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From d45a5762713620f859f6f671cd39cdccc0bb1497 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 10 Feb 2024 18:33:08 +0100 Subject: [PATCH 609/783] [release/8.0-staging] Ensure that the various `Max*Number` and `Min*Number` APIs optimize correctly (#98159) * Ensure that the various `Max*Number` and `Min*Number` APIs optimize correctly * Don't mark the test methods as AO * Add a missing using statement to the test --------- Co-authored-by: Tanner Gooding --- src/coreclr/jit/importercalls.cpp | 3 +- .../JitBlue/Runtime_98068/Runtime_98068.cs | 753 ++++++++++++++++++ .../Runtime_98068/Runtime_98068.csproj | 8 + 3 files changed, 763 insertions(+), 1 deletion(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_98068/Runtime_98068.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_98068/Runtime_98068.csproj diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index fc2d2376541445..e0c5cbb94e4733 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -8290,7 +8290,8 @@ GenTree* Compiler::impMinMaxIntrinsic(CORINFO_METHOD_HANDLE method, if (isNumber) { - std::swap(op1, op2); + // Swap the operands so that the cnsNode is op1, this prevents + // the unknown value (which could be NaN) from being selected. retNode->AsHWIntrinsic()->Op(1) = op2; retNode->AsHWIntrinsic()->Op(2) = op1; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_98068/Runtime_98068.cs b/src/tests/JIT/Regression/JitBlue/Runtime_98068/Runtime_98068.cs new file mode 100644 index 00000000000000..26efaba4fd2d05 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_98068/Runtime_98068.cs @@ -0,0 +1,753 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public static class Runtime_98068 +{ + [Fact] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TestMax() + { + // Double + + Assert.Equal(Max(double.NaN, +1.0), Max_Value_One(double.NaN)); + Assert.Equal(Max(double.NaN, +0.0), Max_Value_Zero(double.NaN)); + Assert.Equal(Max(double.NaN, -0.0), Max_Value_NegZero(double.NaN)); + + Assert.Equal(Max(+1.0, double.NaN), Max_Value_NaN(+1.0)); + Assert.Equal(Max(+0.0, double.NaN), Max_Value_NaN(+0.0)); + Assert.Equal(Max(-0.0, double.NaN), Max_Value_NaN(-0.0)); + + // Single + + Assert.Equal(Max(float.NaN, +1.0f), Max_Value_One(float.NaN)); + Assert.Equal(Max(float.NaN, +0.0f), Max_Value_Zero(float.NaN)); + Assert.Equal(Max(float.NaN, -0.0f), Max_Value_NegZero(float.NaN)); + + Assert.Equal(Max(+1.0f, float.NaN), Max_Value_NaN(+1.0f)); + Assert.Equal(Max(+0.0f, float.NaN), Max_Value_NaN(+0.0f)); + Assert.Equal(Max(-0.0f, float.NaN), Max_Value_NaN(-0.0f)); + } + + [Fact] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TestMaxMagnitude() + { + // Double + + Assert.Equal(MaxMagnitude(double.NaN, +1.0), MaxMagnitude_Value_One(double.NaN)); + Assert.Equal(MaxMagnitude(double.NaN, +0.0), MaxMagnitude_Value_Zero(double.NaN)); + Assert.Equal(MaxMagnitude(double.NaN, -0.0), MaxMagnitude_Value_NegZero(double.NaN)); + + Assert.Equal(MaxMagnitude(+1.0, double.NaN), MaxMagnitude_Value_NaN(+1.0)); + Assert.Equal(MaxMagnitude(+0.0, double.NaN), MaxMagnitude_Value_NaN(+0.0)); + Assert.Equal(MaxMagnitude(-0.0, double.NaN), MaxMagnitude_Value_NaN(-0.0)); + + // Single + + Assert.Equal(MaxMagnitude(float.NaN, +1.0f), MaxMagnitude_Value_One(float.NaN)); + Assert.Equal(MaxMagnitude(float.NaN, +0.0f), MaxMagnitude_Value_Zero(float.NaN)); + Assert.Equal(MaxMagnitude(float.NaN, -0.0f), MaxMagnitude_Value_NegZero(float.NaN)); + + Assert.Equal(MaxMagnitude(+1.0f, float.NaN), MaxMagnitude_Value_NaN(+1.0f)); + Assert.Equal(MaxMagnitude(+0.0f, float.NaN), MaxMagnitude_Value_NaN(+0.0f)); + Assert.Equal(MaxMagnitude(-0.0f, float.NaN), MaxMagnitude_Value_NaN(-0.0f)); + } + + [Fact] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TestMaxMagnitudeNumber() + { + // Double + + Assert.Equal(MaxMagnitudeNumber(double.NaN, +1.0), MaxMagnitudeNumber_Value_One(double.NaN)); + Assert.Equal(MaxMagnitudeNumber(double.NaN, +0.0), MaxMagnitudeNumber_Value_Zero(double.NaN)); + Assert.Equal(MaxMagnitudeNumber(double.NaN, -0.0), MaxMagnitudeNumber_Value_NegZero(double.NaN)); + + Assert.Equal(MaxMagnitudeNumber(+1.0, double.NaN), MaxMagnitudeNumber_Value_NaN(+1.0)); + Assert.Equal(MaxMagnitudeNumber(+0.0, double.NaN), MaxMagnitudeNumber_Value_NaN(+0.0)); + Assert.Equal(MaxMagnitudeNumber(-0.0, double.NaN), MaxMagnitudeNumber_Value_NaN(-0.0)); + + // Single + + Assert.Equal(MaxMagnitudeNumber(float.NaN, +1.0f), MaxMagnitudeNumber_Value_One(float.NaN)); + Assert.Equal(MaxMagnitudeNumber(float.NaN, +0.0f), MaxMagnitudeNumber_Value_Zero(float.NaN)); + Assert.Equal(MaxMagnitudeNumber(float.NaN, -0.0f), MaxMagnitudeNumber_Value_NegZero(float.NaN)); + + Assert.Equal(MaxMagnitudeNumber(+1.0f, float.NaN), MaxMagnitudeNumber_Value_NaN(+1.0f)); + Assert.Equal(MaxMagnitudeNumber(+0.0f, float.NaN), MaxMagnitudeNumber_Value_NaN(+0.0f)); + Assert.Equal(MaxMagnitudeNumber(-0.0f, float.NaN), MaxMagnitudeNumber_Value_NaN(-0.0f)); + } + + [Fact] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TestMaxNumber() + { + // Double + + Assert.Equal(MaxNumber(double.NaN, +1.0), MaxNumber_Value_One(double.NaN)); + Assert.Equal(MaxNumber(double.NaN, +0.0), MaxNumber_Value_Zero(double.NaN)); + Assert.Equal(MaxNumber(double.NaN, -0.0), MaxNumber_Value_NegZero(double.NaN)); + + Assert.Equal(MaxNumber(+1.0, double.NaN), MaxNumber_Value_NaN(+1.0)); + Assert.Equal(MaxNumber(+0.0, double.NaN), MaxNumber_Value_NaN(+0.0)); + Assert.Equal(MaxNumber(-0.0, double.NaN), MaxNumber_Value_NaN(-0.0)); + + // Single + + Assert.Equal(MaxNumber(float.NaN, +1.0f), MaxNumber_Value_One(float.NaN)); + Assert.Equal(MaxNumber(float.NaN, +0.0f), MaxNumber_Value_Zero(float.NaN)); + Assert.Equal(MaxNumber(float.NaN, -0.0f), MaxNumber_Value_NegZero(float.NaN)); + + Assert.Equal(MaxNumber(+1.0f, float.NaN), MaxNumber_Value_NaN(+1.0f)); + Assert.Equal(MaxNumber(+0.0f, float.NaN), MaxNumber_Value_NaN(+0.0f)); + Assert.Equal(MaxNumber(-0.0f, float.NaN), MaxNumber_Value_NaN(-0.0f)); + } + + [Fact] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TestMin() + { + // Double + + Assert.Equal(Min(double.NaN, +1.0), Min_Value_One(double.NaN)); + Assert.Equal(Min(double.NaN, +0.0), Min_Value_Zero(double.NaN)); + Assert.Equal(Min(double.NaN, -0.0), Min_Value_NegZero(double.NaN)); + + Assert.Equal(Min(+1.0, double.NaN), Min_Value_NaN(+1.0)); + Assert.Equal(Min(+0.0, double.NaN), Min_Value_NaN(+0.0)); + Assert.Equal(Min(-0.0, double.NaN), Min_Value_NaN(-0.0)); + + // Single + + Assert.Equal(Min(float.NaN, +1.0f), Min_Value_One(float.NaN)); + Assert.Equal(Min(float.NaN, +0.0f), Min_Value_Zero(float.NaN)); + Assert.Equal(Min(float.NaN, -0.0f), Min_Value_NegZero(float.NaN)); + + Assert.Equal(Min(+1.0f, float.NaN), Min_Value_NaN(+1.0f)); + Assert.Equal(Min(+0.0f, float.NaN), Min_Value_NaN(+0.0f)); + Assert.Equal(Min(-0.0f, float.NaN), Min_Value_NaN(-0.0f)); + } + + [Fact] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TestMinMagnitude() + { + // Double + + Assert.Equal(MinMagnitude(double.NaN, +1.0), MinMagnitude_Value_One(double.NaN)); + Assert.Equal(MinMagnitude(double.NaN, +0.0), MinMagnitude_Value_Zero(double.NaN)); + Assert.Equal(MinMagnitude(double.NaN, -0.0), MinMagnitude_Value_NegZero(double.NaN)); + + Assert.Equal(MinMagnitude(+1.0, double.NaN), MinMagnitude_Value_NaN(+1.0)); + Assert.Equal(MinMagnitude(+0.0, double.NaN), MinMagnitude_Value_NaN(+0.0)); + Assert.Equal(MinMagnitude(-0.0, double.NaN), MinMagnitude_Value_NaN(-0.0)); + + // Single + + Assert.Equal(MinMagnitude(float.NaN, +1.0f), MinMagnitude_Value_One(float.NaN)); + Assert.Equal(MinMagnitude(float.NaN, +0.0f), MinMagnitude_Value_Zero(float.NaN)); + Assert.Equal(MinMagnitude(float.NaN, -0.0f), MinMagnitude_Value_NegZero(float.NaN)); + + Assert.Equal(MinMagnitude(+1.0f, float.NaN), MinMagnitude_Value_NaN(+1.0f)); + Assert.Equal(MinMagnitude(+0.0f, float.NaN), MinMagnitude_Value_NaN(+0.0f)); + Assert.Equal(MinMagnitude(-0.0f, float.NaN), MinMagnitude_Value_NaN(-0.0f)); + } + + [Fact] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TestMinMagnitudeNumber() + { + // Double + + Assert.Equal(MinMagnitudeNumber(double.NaN, +1.0), MinMagnitudeNumber_Value_One(double.NaN)); + Assert.Equal(MinMagnitudeNumber(double.NaN, +0.0), MinMagnitudeNumber_Value_Zero(double.NaN)); + Assert.Equal(MinMagnitudeNumber(double.NaN, -0.0), MinMagnitudeNumber_Value_NegZero(double.NaN)); + + Assert.Equal(MinMagnitudeNumber(+1.0, double.NaN), MinMagnitudeNumber_Value_NaN(+1.0)); + Assert.Equal(MinMagnitudeNumber(+0.0, double.NaN), MinMagnitudeNumber_Value_NaN(+0.0)); + Assert.Equal(MinMagnitudeNumber(-0.0, double.NaN), MinMagnitudeNumber_Value_NaN(-0.0)); + + // Single + + Assert.Equal(MinMagnitudeNumber(float.NaN, +1.0f), MinMagnitudeNumber_Value_One(float.NaN)); + Assert.Equal(MinMagnitudeNumber(float.NaN, +0.0f), MinMagnitudeNumber_Value_Zero(float.NaN)); + Assert.Equal(MinMagnitudeNumber(float.NaN, -0.0f), MinMagnitudeNumber_Value_NegZero(float.NaN)); + + Assert.Equal(MinMagnitudeNumber(+1.0f, float.NaN), MinMagnitudeNumber_Value_NaN(+1.0f)); + Assert.Equal(MinMagnitudeNumber(+0.0f, float.NaN), MinMagnitudeNumber_Value_NaN(+0.0f)); + Assert.Equal(MinMagnitudeNumber(-0.0f, float.NaN), MinMagnitudeNumber_Value_NaN(-0.0f)); + } + + [Fact] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TestMinNumber() + { + // Double + + Assert.Equal(MinNumber(double.NaN, +1.0), MinNumber_Value_One(double.NaN)); + Assert.Equal(MinNumber(double.NaN, +0.0), MinNumber_Value_Zero(double.NaN)); + Assert.Equal(MinNumber(double.NaN, -0.0), MinNumber_Value_NegZero(double.NaN)); + + Assert.Equal(MinNumber(+1.0, double.NaN), MinNumber_Value_NaN(+1.0)); + Assert.Equal(MinNumber(+0.0, double.NaN), MinNumber_Value_NaN(+0.0)); + Assert.Equal(MinNumber(-0.0, double.NaN), MinNumber_Value_NaN(-0.0)); + + // Single + + Assert.Equal(MinNumber(float.NaN, +1.0f), MinNumber_Value_One(float.NaN)); + Assert.Equal(MinNumber(float.NaN, +0.0f), MinNumber_Value_Zero(float.NaN)); + Assert.Equal(MinNumber(float.NaN, -0.0f), MinNumber_Value_NegZero(float.NaN)); + + Assert.Equal(MinNumber(+1.0f, float.NaN), MinNumber_Value_NaN(+1.0f)); + Assert.Equal(MinNumber(+0.0f, float.NaN), MinNumber_Value_NaN(+0.0f)); + Assert.Equal(MinNumber(-0.0f, float.NaN), MinNumber_Value_NaN(-0.0f)); + } + + // + // Max.Double + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double Max(double left, double right) + { + return double.Max(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static double Max_Value_One(double value) + { + return double.Max(value, +1.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double Max_Value_NaN(double value) + { + return double.Max(value, double.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double Max_Value_NegZero(double value) + { + return double.Max(value, -0.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double Max_Value_Zero(double value) + { + return double.Max(value, +0.0); + } + + // + // Max.Single + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float Max(float left, float right) + { + return float.Max(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static float Max_Value_One(float value) + { + return float.Max(value, +1.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float Max_Value_NaN(float value) + { + return float.Max(value, float.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float Max_Value_NegZero(float value) + { + return float.Max(value, -0.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float Max_Value_Zero(float value) + { + return float.Max(value, +0.0f); + } + + // + // MaxMagnitude.Double + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MaxMagnitude(double left, double right) + { + return double.MaxMagnitude(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static double MaxMagnitude_Value_One(double value) + { + return double.MaxMagnitude(value, +1.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MaxMagnitude_Value_NaN(double value) + { + return double.MaxMagnitude(value, double.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MaxMagnitude_Value_NegZero(double value) + { + return double.MaxMagnitude(value, -0.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MaxMagnitude_Value_Zero(double value) + { + return double.MaxMagnitude(value, +0.0); + } + + // + // MaxMagnitude.Single + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MaxMagnitude(float left, float right) + { + return float.MaxMagnitude(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static float MaxMagnitude_Value_One(float value) + { + return float.MaxMagnitude(value, +1.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MaxMagnitude_Value_NaN(float value) + { + return float.MaxMagnitude(value, float.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MaxMagnitude_Value_NegZero(float value) + { + return float.MaxMagnitude(value, -0.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MaxMagnitude_Value_Zero(float value) + { + return float.MaxMagnitude(value, +0.0f); + } + + // + // MaxMagnitudeNumber.Double + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MaxMagnitudeNumber(double left, double right) + { + return double.MaxMagnitudeNumber(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static double MaxMagnitudeNumber_Value_One(double value) + { + return double.MaxMagnitudeNumber(value, +1.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MaxMagnitudeNumber_Value_NaN(double value) + { + return double.MaxMagnitudeNumber(value, double.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MaxMagnitudeNumber_Value_NegZero(double value) + { + return double.MaxMagnitudeNumber(value, -0.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MaxMagnitudeNumber_Value_Zero(double value) + { + return double.MaxMagnitudeNumber(value, +0.0); + } + + // + // MaxMagnitudeNumber.Single + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MaxMagnitudeNumber(float left, float right) + { + return float.MaxMagnitudeNumber(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static float MaxMagnitudeNumber_Value_One(float value) + { + return float.MaxMagnitudeNumber(value, +1.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MaxMagnitudeNumber_Value_NaN(float value) + { + return float.MaxMagnitudeNumber(value, float.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MaxMagnitudeNumber_Value_NegZero(float value) + { + return float.MaxMagnitudeNumber(value, -0.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MaxMagnitudeNumber_Value_Zero(float value) + { + return float.MaxMagnitudeNumber(value, +0.0f); + } + + // + // MaxNumber.Double + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MaxNumber(double left, double right) + { + return double.MaxNumber(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static double MaxNumber_Value_One(double value) + { + return double.MaxNumber(value, +1.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MaxNumber_Value_NaN(double value) + { + return double.MaxNumber(value, double.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MaxNumber_Value_NegZero(double value) + { + return double.MaxNumber(value, -0.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MaxNumber_Value_Zero(double value) + { + return double.MaxNumber(value, +0.0); + } + + // + // MaxNumber.Single + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MaxNumber(float left, float right) + { + return float.MaxNumber(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static float MaxNumber_Value_One(float value) + { + return float.MaxNumber(value, +1.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MaxNumber_Value_NaN(float value) + { + return float.MaxNumber(value, float.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MaxNumber_Value_NegZero(float value) + { + return float.MaxNumber(value, -0.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MaxNumber_Value_Zero(float value) + { + return float.MaxNumber(value, +0.0f); + } + + // + // Min.Double + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double Min(double left, double right) + { + return double.Min(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static double Min_Value_One(double value) + { + return double.Min(value, +1.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double Min_Value_NaN(double value) + { + return double.Min(value, double.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double Min_Value_NegZero(double value) + { + return double.Min(value, -0.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double Min_Value_Zero(double value) + { + return double.Min(value, +0.0); + } + + // + // Min.Single + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float Min(float left, float right) + { + return float.Min(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static float Min_Value_One(float value) + { + return float.Min(value, +1.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float Min_Value_NaN(float value) + { + return float.Min(value, float.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float Min_Value_NegZero(float value) + { + return float.Min(value, -0.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float Min_Value_Zero(float value) + { + return float.Min(value, +0.0f); + } + + // + // MinMagnitude.Double + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MinMagnitude(double left, double right) + { + return double.MinMagnitude(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static double MinMagnitude_Value_One(double value) + { + return double.MinMagnitude(value, +1.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MinMagnitude_Value_NaN(double value) + { + return double.MinMagnitude(value, double.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MinMagnitude_Value_NegZero(double value) + { + return double.MinMagnitude(value, -0.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MinMagnitude_Value_Zero(double value) + { + return double.MinMagnitude(value, +0.0); + } + + // + // MinMagnitude.Single + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MinMagnitude(float left, float right) + { + return float.MinMagnitude(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static float MinMagnitude_Value_One(float value) + { + return float.MinMagnitude(value, +1.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MinMagnitude_Value_NaN(float value) + { + return float.MinMagnitude(value, float.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MinMagnitude_Value_NegZero(float value) + { + return float.MinMagnitude(value, -0.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MinMagnitude_Value_Zero(float value) + { + return float.MinMagnitude(value, +0.0f); + } + + // + // MinMagnitudeNumber.Double + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MinMagnitudeNumber(double left, double right) + { + return double.MinMagnitudeNumber(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static double MinMagnitudeNumber_Value_One(double value) + { + return double.MinMagnitudeNumber(value, +1.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MinMagnitudeNumber_Value_NaN(double value) + { + return double.MinMagnitudeNumber(value, double.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MinMagnitudeNumber_Value_NegZero(double value) + { + return double.MinMagnitudeNumber(value, -0.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MinMagnitudeNumber_Value_Zero(double value) + { + return double.MinMagnitudeNumber(value, +0.0); + } + + // + // MinMagnitudeNumber.Single + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MinMagnitudeNumber(float left, float right) + { + return float.MinMagnitudeNumber(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static float MinMagnitudeNumber_Value_One(float value) + { + return float.MinMagnitudeNumber(value, +1.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MinMagnitudeNumber_Value_NaN(float value) + { + return float.MinMagnitudeNumber(value, float.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MinMagnitudeNumber_Value_NegZero(float value) + { + return float.MinMagnitudeNumber(value, -0.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MinMagnitudeNumber_Value_Zero(float value) + { + return float.MinMagnitudeNumber(value, +0.0f); + } + + // + // MinNumber.Double + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MinNumber(double left, double right) + { + return double.MinNumber(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static double MinNumber_Value_One(double value) + { + return double.MinNumber(value, +1.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MinNumber_Value_NaN(double value) + { + return double.MinNumber(value, double.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MinNumber_Value_NegZero(double value) + { + return double.MinNumber(value, -0.0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static double MinNumber_Value_Zero(double value) + { + return double.MinNumber(value, +0.0); + } + + // + // MinNumber.Single + // + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MinNumber(float left, float right) + { + return float.MinNumber(left, right); + } + + [MethodImpl(MethodImplOptions.NoInlining| MethodImplOptions.AggressiveOptimization)] + public static float MinNumber_Value_One(float value) + { + return float.MinNumber(value, +1.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MinNumber_Value_NaN(float value) + { + return float.MinNumber(value, float.NaN); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MinNumber_Value_NegZero(float value) + { + return float.MinNumber(value, -0.0f); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static float MinNumber_Value_Zero(float value) + { + return float.MinNumber(value, +0.0f); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_98068/Runtime_98068.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_98068/Runtime_98068.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_98068/Runtime_98068.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From ff4e048ecabcac608e2cd10281efc3f043b7c6fd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 11 Feb 2024 15:46:22 -0800 Subject: [PATCH 610/783] Define installer-owned directories (#98241) Co-authored-by: Nikola Milosavljevic --- .../Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.props | 1 + 1 file changed, 1 insertion(+) diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.props index 6907e829c384f3..b9af46ba7258bf 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.props @@ -61,6 +61,7 @@ + From 2190e9be7e942f8037cd7318527086805a305150 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Mon, 12 Feb 2024 09:26:16 +0100 Subject: [PATCH 611/783] Fix Windows implementation of NegotiateAuthenticationPal.GetMIC (#98031) --- .../src/System/Net/NegotiateAuthenticationPal.Windows.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Windows.cs index 07e8dea22baa9c..6a136c4a1c59df 100644 --- a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Windows.cs @@ -566,7 +566,7 @@ public override unsafe void GetMIC(ReadOnlySpan message, IBufferWriter signatureBuffer = signature.GetSpan(sizes.cbSecurityTrailer); + Span signatureBuffer = signature.GetSpan(sizes.cbMaxSignature); fixed (byte* messagePtr = message) fixed (byte* signaturePtr = signatureBuffer) @@ -577,7 +577,7 @@ public override unsafe void GetMIC(ReadOnlySpan message, IBufferWriterBufferType = SecurityBufferType.SECBUFFER_TOKEN; tokenBuffer->pvBuffer = (IntPtr)signaturePtr; - tokenBuffer->cbBuffer = sizes.cbSecurityTrailer; + tokenBuffer->cbBuffer = sizes.cbMaxSignature; dataBuffer->BufferType = SecurityBufferType.SECBUFFER_DATA; dataBuffer->pvBuffer = (IntPtr)messagePtr; dataBuffer->cbBuffer = message.Length; @@ -597,7 +597,7 @@ public override unsafe void GetMIC(ReadOnlySpan message, IBufferWritercbBuffer); } } finally From dedae5e0a7cdeb2b86243d3fe48268b7b5e065ed Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Mon, 12 Feb 2024 17:59:08 +0100 Subject: [PATCH 612/783] [release/8.0-staging] Fix constant folding for arm64 MultiplyByScalar operations involving Vector2.One (#98150) MultiplyByScalar on ARM64 should not be handled by the same path as other multiplications since it has different behavior. --- src/coreclr/jit/valuenum.cpp | 32 +++++++++++++++++-- .../JitBlue/Runtime_93876/Runtime_93876.cs | 25 +++++++++++++++ .../Runtime_93876/Runtime_93876.csproj | 8 +++++ 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.csproj diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 259305a6aac7b1..fa60633afbc233 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -7809,10 +7809,38 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary(var_types type, } #ifdef TARGET_ARM64 - case NI_AdvSimd_Multiply: case NI_AdvSimd_MultiplyByScalar: - case NI_AdvSimd_Arm64_Multiply: case NI_AdvSimd_Arm64_MultiplyByScalar: + { + if (!varTypeIsFloating(baseType)) + { + // Handle `x * 0 == 0` and `0 * x == 0` + // Not safe for floating-point when x == -0.0, NaN, +Inf, -Inf + ValueNum zeroVN = VNZeroForType(TypeOfVN(cnsVN)); + + if (cnsVN == zeroVN) + { + return VNZeroForType(type); + } + } + + assert((TypeOfVN(arg0VN) == type) && (TypeOfVN(arg1VN) == TYP_SIMD8)); + + // Handle x * 1 => x, but only if the scalar RHS is <1, ...>. + if (IsVNConstant(arg1VN)) + { + if (EvaluateSimdGetElement(this, TYP_SIMD8, baseType, arg1VN, 0) == VNOneForType(baseType)) + { + return arg0VN; + } + } + break; + } +#endif + +#ifdef TARGET_ARM64 + case NI_AdvSimd_Multiply: + case NI_AdvSimd_Arm64_Multiply: #else case NI_SSE_Multiply: case NI_SSE2_Multiply: diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.cs b/src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.cs new file mode 100644 index 00000000000000..760cd04a594e3e --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Numerics; +using Xunit; + +public static class Runtime_93876 +{ + [Fact] + public static void Problem() + { + Vector4 v = Mul(0, 1); + Assert.Equal(Vector4.One, v); + Vector64 v64 = Mul64(0, 1); + Assert.Equal(Vector64.One, v64); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Vector4 Mul(float a, float b) => Vector4.Multiply(a + b, Vector4.One); + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Vector64 Mul64(float a, float b) => Vector64.Multiply(a + b, Vector64.One); +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From bb540a87535a1d51828eed38d0f04998e1fb8f55 Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Mon, 12 Feb 2024 07:05:42 -1000 Subject: [PATCH 613/783] [NativeAOT][8.0] Use ld_classic in ILC build and in build integration (#97856) * use ld_classic in ILC build and in build integration * PR feedback * Maybe fix the build for non-apple * Update src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets PR feedback Co-authored-by: Jan Kotas --------- Co-authored-by: Jan Kotas --- .../Microsoft.NETCore.Native.Unix.targets | 13 +++++++++++++ src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 71acdacdadd10a..c9ae3083cf5cd4 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -166,6 +166,19 @@ The .NET Foundation licenses this file to you under the MIT license. + + + + + + + <_XcodeVersion>$([System.Text.RegularExpressions.Regex]::Match($(_XcodeVersionString), '[1-9]\d*')) + + + + + + <_CommandProbe>command -v <_CommandProbe Condition="$([MSBuild]::IsOSPlatform('Windows'))">where /Q diff --git a/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj b/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj index 7122c81034ff31..7c25444f209c33 100644 --- a/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj +++ b/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj @@ -70,6 +70,19 @@ + + + + + + + <_XcodeVersion>$([System.Text.RegularExpressions.Regex]::Match($(_XcodeVersionString), '[1-9]\d*')) + + + + + + $(_CC_LDFLAGS.SubString(0, $(_CC_LDFLAGS.IndexOf(';')))) <_LDFLAGS>$(_CC_LDFLAGS.SubString($([MSBuild]::Add($(_CC_LDFLAGS.IndexOf(';')), 1)))) From ba68cf1d1091526397a2c655ff931f6678d1262f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 14:35:43 -0300 Subject: [PATCH 614/783] Fix side effect of only not sending assembly_load while invoking methods. (#98254) Co-authored-by: Thays Grazia --- src/mono/mono/component/debugger-agent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index c9199635d15d59..80918c38876824 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -4149,7 +4149,7 @@ jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo) if (assembly) { DebuggerTlsData *tls; tls = (DebuggerTlsData *)mono_native_tls_get_value (debugger_tls_id); - if (tls->invoke == NULL) { + if (!CHECK_ICORDBG (TRUE) || tls->invoke == NULL) { process_profiler_event (EVENT_KIND_ASSEMBLY_LOAD, assembly); } else { assembly_load(prof, assembly); //send later From 6dec8dd10ca45d925fb3577be9cfd44a4822b7fc Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Mon, 12 Feb 2024 09:47:17 -0800 Subject: [PATCH 615/783] Fix polluted CompareState when comparing element types in a signature (#98249) We were propagating state from each type in the method signature to the comparisons for the next type. This resulted in type equivalence checks being disabled for any parameters that came after a generic parameter. --- src/coreclr/vm/siginfo.cpp | 12 +-- .../typeequivalence/contracts/Types.cs | 6 ++ .../typeequivalence/impl/Impls.cs | 12 +++ .../typeequivalence/simple/Simple.cs | 87 ++++++++++--------- 4 files changed, 68 insertions(+), 49 deletions(-) diff --git a/src/coreclr/vm/siginfo.cpp b/src/coreclr/vm/siginfo.cpp index eb35f3a372538f..3342a27178f50c 100644 --- a/src/coreclr/vm/siginfo.cpp +++ b/src/coreclr/vm/siginfo.cpp @@ -4204,8 +4204,6 @@ MetaSig::CompareTypeDefsUnderSubstitutions( SigPointer inst1 = pSubst1->GetInst(); SigPointer inst2 = pSubst2->GetInst(); - TokenPairList visited { pVisited }; - CompareState state{ &visited }; for (DWORD i = 0; i < pTypeDef1->GetNumGenericArgs(); i++) { PCCOR_SIGNATURE startInst1 = inst1.GetPtr(); @@ -4214,6 +4212,8 @@ MetaSig::CompareTypeDefsUnderSubstitutions( PCCOR_SIGNATURE startInst2 = inst2.GetPtr(); IfFailThrow(inst2.SkipExactlyOne()); PCCOR_SIGNATURE endInst2ptr = inst2.GetPtr(); + TokenPairList visited{ pVisited }; + CompareState state{ &visited }; if (!CompareElementType( startInst1, startInst2, @@ -4382,8 +4382,6 @@ MetaSig::CompareMethodSigs( IfFailThrow(CorSigUncompressData_EndPtr(pSig1, pEndSig1, &ArgCount1)); IfFailThrow(CorSigUncompressData_EndPtr(pSig2, pEndSig2, &ArgCount2)); - TokenPairList visited{ pVisited }; - if (ArgCount1 != ArgCount2) { if ((callConv & IMAGE_CEE_CS_CALLCONV_MASK) != IMAGE_CEE_CS_CALLCONV_VARARG) @@ -4405,7 +4403,6 @@ MetaSig::CompareMethodSigs( // to correctly handle overloads, where there are a number of varargs methods // to pick from, like m1(int,...) and m2(int,int,...), etc. - CompareState state{ &visited }; // <= because we want to include a check of the return value! for (i = 0; i <= ArgCount1; i++) { @@ -4437,6 +4434,8 @@ MetaSig::CompareMethodSigs( else { // We are in bounds on both sides. Compare the element. + TokenPairList visited{ pVisited }; + CompareState state{ &visited }; if (!CompareElementType( pSig1, pSig2, @@ -4461,7 +4460,6 @@ MetaSig::CompareMethodSigs( } // do return type as well - CompareState state{ &visited }; for (i = 0; i <= ArgCount1; i++) { if (i == 0 && skipReturnTypeSig) @@ -4476,6 +4474,8 @@ MetaSig::CompareMethodSigs( } else { + TokenPairList visited{ pVisited }; + CompareState state{ &visited }; if (!CompareElementType( pSig1, pSig2, diff --git a/src/tests/baseservices/typeequivalence/contracts/Types.cs b/src/tests/baseservices/typeequivalence/contracts/Types.cs index a9fc0270a1bdd0..539e83318fc506 100644 --- a/src/tests/baseservices/typeequivalence/contracts/Types.cs +++ b/src/tests/baseservices/typeequivalence/contracts/Types.cs @@ -61,6 +61,12 @@ public interface ISparseType int MultiplyBy20(int a); } + [Guid("BD752276-52DF-4CD1-8C62-49D202F15C8D")] + public struct TestValueType + { + public int Field; + } + // // Below types are used in type punning tests and shouldn't be used anywhere else. // diff --git a/src/tests/baseservices/typeequivalence/impl/Impls.cs b/src/tests/baseservices/typeequivalence/impl/Impls.cs index dd0ce12eec9baa..55117a68236175 100644 --- a/src/tests/baseservices/typeequivalence/impl/Impls.cs +++ b/src/tests/baseservices/typeequivalence/impl/Impls.cs @@ -130,3 +130,15 @@ public static int GetField_3(OnlyLoadOnce_3 s) return s.Field; } } + +public static class MethodCall +{ + // Include a generic type in the method signature before the type using type equivalence to ensure that + // processing of the generic type does not affect subsequent type processing during signature comparison. + public static System.Collections.Generic.List InterfaceAfterGeneric(IEmptyType t) => null; + public static System.Collections.Generic.List ValueTypeAfterGeneric(TestValueType t) => null; + + // Generic type after the type using type equivalence should also not affect processing. + public static void InterfaceBeforeGeneric(IEmptyType t, System.Collections.Generic.List l) { } + public static void ValueTypeBeforeGeneric(TestValueType t, System.Collections.Generic.List l) { } +} diff --git a/src/tests/baseservices/typeequivalence/simple/Simple.cs b/src/tests/baseservices/typeequivalence/simple/Simple.cs index 7595199a120e16..24e1c9684c70d4 100644 --- a/src/tests/baseservices/typeequivalence/simple/Simple.cs +++ b/src/tests/baseservices/typeequivalence/simple/Simple.cs @@ -17,6 +17,7 @@ public struct EquivalentValueType public int A; } +[PlatformSpecific(TestPlatforms.Windows)] public class Simple { private class EmptyType2 : IEmptyType @@ -30,7 +31,8 @@ public static object Create() } } - private static void InterfaceTypesFromDifferentAssembliesAreEquivalent() + [Fact] + public static void InterfaceTypesFromDifferentAssembliesAreEquivalent() { Console.WriteLine($"{nameof(InterfaceTypesFromDifferentAssembliesAreEquivalent)}"); var inAsm = EmptyType.Create(); @@ -44,9 +46,10 @@ void AreNotSameObject(IEmptyType a, IEmptyType b) } } - private static void ValidateTypeInstanceEquality() + [Fact] + public static void TypeInstanceEquality() { - Console.WriteLine($"{nameof(ValidateTypeInstanceEquality)}"); + Console.WriteLine($"{nameof(TypeInstanceEquality)}"); var inAsm = EmptyType.Create(); var otherAsm = EmptyType2.Create(); @@ -110,7 +113,8 @@ public override string ScaleString(string s) } } - private static void InterfaceTypesMethodOperations() + [Fact] + public static void InterfaceTypesMethodOperations() { Console.WriteLine($"{nameof(InterfaceTypesMethodOperations)}"); @@ -141,7 +145,8 @@ private static void InterfaceTypesMethodOperations() } } - private static void CallSparseInterface() + [Fact] + public static void CallSparseInterface() { Console.WriteLine($"{nameof(CallSparseInterface)}"); @@ -156,9 +161,10 @@ private static void CallSparseInterface() Assert.Equal(input * 18, sparseType.MultiplyBy18(input)); } - private static void TestArrayEquivalence() + [Fact] + public static void ArrayEquivalence() { - Console.WriteLine($"{nameof(TestArrayEquivalence)}"); + Console.WriteLine($"{nameof(ArrayEquivalence)}"); var inAsm = EmptyType.Create(); var otherAsm = EmptyType2.Create(); @@ -173,9 +179,10 @@ private static void TestArrayEquivalence() Assert.False(inAsmInterfaceType.MakeArrayType(1).IsEquivalentTo(otherAsmInterfaceType.MakeArrayType(2))); } - private static void TestByRefEquivalence() + [Fact] + public static void ByRefEquivalence() { - Console.WriteLine($"{nameof(TestByRefEquivalence)}"); + Console.WriteLine($"{nameof(ByRefEquivalence)}"); var inAsm = EmptyType.Create(); var otherAsm = EmptyType2.Create(); @@ -197,9 +204,10 @@ public void Method(V input) } } - private static void TestGenericClassNonEquivalence() + [Fact] + public static void GenericClassNonEquivalence() { - Console.WriteLine($"{nameof(TestGenericClassNonEquivalence)}"); + Console.WriteLine($"{nameof(GenericClassNonEquivalence)}"); var inAsm = EmptyType.Create(); var otherAsm = EmptyType2.Create(); @@ -209,9 +217,10 @@ private static void TestGenericClassNonEquivalence() Assert.False(typeof(Generic<>).MakeGenericType(inAsmInterfaceType).IsEquivalentTo(typeof(Generic<>).MakeGenericType(otherAsmInterfaceType))); } - private static void TestGenericInterfaceEquivalence() + [Fact] + public static void GenericInterfaceEquivalence() { - Console.WriteLine($"{nameof(TestGenericInterfaceEquivalence)}"); + Console.WriteLine($"{nameof(GenericInterfaceEquivalence)}"); var inAsm = EmptyType.Create(); var otherAsm = EmptyType2.Create(); @@ -221,9 +230,10 @@ private static void TestGenericInterfaceEquivalence() Assert.True(typeof(IGeneric<>).MakeGenericType(inAsmInterfaceType).IsEquivalentTo(typeof(IGeneric<>).MakeGenericType(otherAsmInterfaceType))); } - private static unsafe void TestTypeEquivalenceWithTypePunning() + [Fact] + public static unsafe void TypeEquivalenceWithTypePunning() { - Console.WriteLine($"{nameof(TestTypeEquivalenceWithTypePunning)}"); + Console.WriteLine($"{nameof(TypeEquivalenceWithTypePunning)}"); { Console.WriteLine($"-- GetFunctionPointer()"); @@ -260,10 +270,11 @@ private static unsafe void TestTypeEquivalenceWithTypePunning() } } + [Fact] [MethodImpl (MethodImplOptions.NoInlining)] - private static void TestLoadingValueTypesWithMethod() + public static void LoadValueTypesWithMethod() { - Console.WriteLine($"{nameof(TestLoadingValueTypesWithMethod)}"); + Console.WriteLine($"{nameof(LoadValueTypesWithMethod)}"); Console.WriteLine($"-- {typeof(ValueTypeWithStaticMethod).Name}"); Assert.Throws(() => LoadInvalidType()); } @@ -274,7 +285,8 @@ private static void LoadInvalidType() Console.WriteLine($"-- {typeof(ValueTypeWithInstanceMethod).Name}"); } - private static void TestCastsOptimizations() + [Fact] + public static void CastsOptimizations() { string otherTypeName = $"{typeof(EquivalentValueType).FullName},{typeof(EmptyType).Assembly.GetName().Name}"; Type otherEquivalentValueType = Type.GetType(otherTypeName); @@ -285,32 +297,21 @@ private static void TestCastsOptimizations() EquivalentValueType inst = (EquivalentValueType)otherEquivalentValueTypeInstance; } - public static int Main() + [Fact] + public static void MethodCallSignature() { - if (!OperatingSystem.IsWindows()) - { - return 100; - } - try - { - InterfaceTypesFromDifferentAssembliesAreEquivalent(); - ValidateTypeInstanceEquality(); - InterfaceTypesMethodOperations(); - CallSparseInterface(); - TestByRefEquivalence(); - TestArrayEquivalence(); - TestGenericClassNonEquivalence(); - TestGenericInterfaceEquivalence(); - TestTypeEquivalenceWithTypePunning(); - TestLoadingValueTypesWithMethod(); - TestCastsOptimizations(); - } - catch (Exception e) - { - Console.WriteLine($"Test Failure: {e}"); - return 101; - } + Console.WriteLine($"{nameof(MethodCallSignature)}"); + + Console.WriteLine($"-- {nameof(MethodCall.InterfaceAfterGeneric)}"); + MethodCall.InterfaceAfterGeneric((IEmptyType)EmptyType2.Create()); + + Console.WriteLine($"-- {nameof(MethodCall.ValueTypeAfterGeneric)}"); + MethodCall.ValueTypeAfterGeneric(new TestValueType()); + + Console.WriteLine($"-- {nameof(MethodCall.InterfaceBeforeGeneric)}"); + MethodCall.InterfaceBeforeGeneric((IEmptyType)EmptyType2.Create(), null); - return 100; + Console.WriteLine($"-- {nameof(MethodCall.ValueTypeBeforeGeneric)}"); + MethodCall.ValueTypeBeforeGeneric(new TestValueType(), null); } } From 95988727574bd17962fa2d7e54525446835a9ebb Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 09:57:32 -0800 Subject: [PATCH 616/783] [release/8.0-staging] Update dependencies from dotnet/emsdk (#97405) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/dotnet/emsdk build 20240123.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.2-servicing.24062.1 -> To Version 8.0.2-servicing.24073.1 * Update dependencies from https://github.com/dotnet/emsdk build 20240208.3 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.2-servicing.24062.1 -> To Version 8.0.3-servicing.24108.3 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- NuGet.config | 5 +---- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/NuGet.config b/NuGet.config index 12fa8c8879cdb6..a681bc250bc9ed 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,10 +9,7 @@ - - - - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 04a7792f12c29a..4e522812e23bc7 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,13 +90,13 @@ 45dd3a73dd5b64b010c4251303b3664bb30df029 - + https://github.com/dotnet/emsdk - 2fc2ffd960930318f33fcaa690cbdbc55d72f52d + 9a29abdd764a4de0f253ed368871877a47725247 - + https://github.com/dotnet/emsdk - 2fc2ffd960930318f33fcaa690cbdbc55d72f52d + 9a29abdd764a4de0f253ed368871877a47725247 diff --git a/eng/Versions.props b/eng/Versions.props index 05d877f78822fa..8b755c5895c9db 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.2 + 8.0.3 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda From 11ae42ba5af1bec15e7ab7c11529d5e006f253a2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 13:33:17 -0500 Subject: [PATCH 617/783] [release/8.0-staging] Fix regex lazy loop handling of backtracking state at max iteration limit (#97927) * Fix regex lazy loop handling of backtracking state at max iteration limit Upon entering a lazy loop, state is pushed onto the backtracking stack if the lazy loop might be backtracked into. That state is then dutifully popped off when unwinding the loop due to failure to match. However, if the loop successfully matches its maximum number of times but still fails because of a failure after the lazy loop, the state still needs to be popped off the stack, but isn't. This fixes that. * Add a few more test variations --------- Co-authored-by: Stephen Toub --- .../gen/RegexGenerator.Emitter.cs | 12 +++++++++ .../Text/RegularExpressions/RegexCompiler.cs | 26 +++++++++++++++++-- .../FunctionalTests/Regex.Match.Tests.cs | 5 ++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs index 19488703f07f7e..efe4f0e40b4390 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs +++ b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs @@ -3770,6 +3770,17 @@ void EmitLazy(RegexNode node) using (clause) { + // We're backtracking, which could either be to something prior to the lazy loop or to something + // inside of the lazy loop. If it's to something inside of the lazy loop, then either the loop + // will eventually succeed or we'll eventually end up unwinding back through the iterations all + // the way back to the loop not matching at all, in which case the state we first pushed on at the + // beginning of the !isAtomic section will get popped off. But if here we're instead going to jump + // to something prior to the lazy loop, then we need to pop off that state here. + if (doneLabel == originalDoneLabel) + { + EmitAdd(writer, "stackpos", -entriesPerIteration); + } + if (iterationMayBeEmpty) { // If we saw empty, it must have been in the most recent iteration, as we wouldn't have @@ -3777,6 +3788,7 @@ void EmitLazy(RegexNode node) // false prior to backtracking / undoing that iteration. writer.WriteLine($"{sawEmpty} = 0; // false"); } + Goto(doneLabel); } } diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs index 20ccc3afefcca6..fb710b26788732 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs @@ -4075,6 +4075,8 @@ void EmitLazy(RegexNode node) // Determine where to branch, either back to the lazy loop body to add an additional iteration, // or to the last backtracking label. + Label jumpToDone = DefineLabel(); + if (iterationMayBeEmpty) { // if (sawEmpty != 0) @@ -4093,7 +4095,7 @@ void EmitLazy(RegexNode node) Ldc(0); Stloc(sawEmpty!); - BrFar(doneLabel); + Br(jumpToDone); MarkLabel(sawEmptyZero); } @@ -4102,12 +4104,32 @@ void EmitLazy(RegexNode node) // if (iterationCount >= maxIterations) goto doneLabel; Ldloc(iterationCount); Ldc(maxIterations); - BgeFar(doneLabel); + Bge(jumpToDone); } // goto body; BrFar(body); + MarkLabel(jumpToDone); + + // We're backtracking, which could either be to something prior to the lazy loop or to something + // inside of the lazy loop. If it's to something inside of the lazy loop, then either the loop + // will eventually succeed or we'll eventually end up unwinding back through the iterations all + // the way back to the loop not matching at all, in which case the state we first pushed on at the + // beginning of the !isAtomic section will get popped off. But if here we're instead going to jump + // to something prior to the lazy loop, then we need to pop off that state here. + if (doneLabel == originalDoneLabel) + { + // stackpos -= entriesPerIteration; + Ldloc(stackpos); + Ldc(entriesPerIteration); + Sub(); + Stloc(stackpos); + } + + // goto done; + BrFar(doneLabel); + doneLabel = backtrack; MarkLabel(skipBacktrack); } diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Tests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Tests.cs index 43bd39f8f36779..d09f45ac2064c4 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Tests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Tests.cs @@ -2374,6 +2374,11 @@ public static IEnumerable AllMatches_TestData() yield return new object[] { engine, "^(?:aaa|aa){1,5}?$", RegexOptions.None, "aaaaaaaa", new (int, int, string)[] { (0, 8, "aaaaaaaa") } }; yield return new object[] { engine, "^(?:aaa|aa){4}$", RegexOptions.None, "aaaaaaaa", new (int, int, string)[] { (0, 8, "aaaaaaaa") } }; yield return new object[] { engine, "^(?:aaa|aa){4}?$", RegexOptions.None, "aaaaaaaa", new (int, int, string)[] { (0, 8, "aaaaaaaa") } }; + yield return new object[] { engine, "^((?:(xx?,xx?)|xx?,xx?>xx?,xx?)-?(x)??){1,2}$", RegexOptions.None, "xx,xx>xx,xx", new (int, int, string)[] { (0, 11, "xx,xx>xx,xx") } }; + yield return new object[] { engine, "^((?:(xx?,xx?)|xx?,xx?>xx?,xx?)-?(x*)??){1,2}$", RegexOptions.None, "xx,xx>xx,xx", new (int, int, string)[] { (0, 11, "xx,xx>xx,xx") } }; + yield return new object[] { engine, "^((?:(xx?,xx?)|xx?,xx?>xx?,xx?)-?(x+)??){1,2}$", RegexOptions.None, "xx,xx>xx,xx", new (int, int, string)[] { (0, 11, "xx,xx>xx,xx") } }; + yield return new object[] { engine, "^((?:(x(x?),x(x?))|xx?,(x(x?)>x(x?)),(x((x))?))-?(x+?)??){1,2}$", RegexOptions.None, "xx,xx>xx,xx", new (int, int, string)[] { (0, 11, "xx,xx>xx,xx") } }; + yield return new object[] { engine, "^(?:x|(x)??){2}$", RegexOptions.None, "x>", null }; // Mostly empty matches using unusual regexes consisting mostly of anchors only yield return new object[] { engine, "^", RegexOptions.None, "", new (int, int, string)[] { (0, 0, "") } }; From b7fda9f36c2cd2a8cde7afdd4dd9670a6e9397d6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 12:16:33 -0800 Subject: [PATCH 618/783] Add ca-certificates to Mariner 2.0 deps (#98267) Co-authored-by: Nikola Milosavljevic --- .../dotnet-runtime-deps/dotnet-runtime-deps-cm.2.proj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-cm.2.proj b/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-cm.2.proj index 52b410239d3be7..76315c4255ec16 100644 --- a/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-cm.2.proj +++ b/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-cm.2.proj @@ -5,6 +5,6 @@ - + From ddb41ec46ddc558be2f43135a1daa01ebac8e841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20P=C3=ADchov=C3=A1?= Date: Mon, 12 Feb 2024 20:40:26 +0000 Subject: [PATCH 619/783] [release/8.0] Update MsQuic --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index c202a5bbb52706..e9219d391d6e4d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -219,7 +219,7 @@ 8.0.0-rtm.23523.2 - 2.2.3 + 2.2.5-ci.444313 8.0.0-alpha.1.23527.1 16.0.5-alpha.1.23566.1 From 00c95a673bdc72cc8e903df4e0acb450f7ad1a9d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 13:03:15 -0800 Subject: [PATCH 620/783] [release/8.0-staging] Ensure that Vector512 uses the same patterns as Vector64/128/256 (#98115) * Ensure that Vector512 uses the same patterns as Vector64/128/256 * Update src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs Co-authored-by: Jeff Handley --------- Co-authored-by: Tanner Gooding Co-authored-by: Jeff Handley --- .../src/System/Runtime/Intrinsics/Vector512.cs | 15 +++++---------- .../tests/Vectors/Vector128Tests.cs | 16 ++++++++++++++++ .../tests/Vectors/Vector256Tests.cs | 16 ++++++++++++++++ .../tests/Vectors/Vector512Tests.cs | 16 ++++++++++++++++ .../tests/Vectors/Vector64Tests.cs | 16 ++++++++++++++++ 5 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs index 824440a5bf2a7b..9847a9fe0da476 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs @@ -483,8 +483,7 @@ public static void CopyTo(this Vector512 vector, Span destination) ThrowHelper.ThrowArgumentException_DestinationTooShort(); } - ref byte address = ref Unsafe.As(ref MemoryMarshal.GetReference(destination)); - Unsafe.WriteUnaligned(ref address, vector); + Unsafe.WriteUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(destination)), vector); } /// Creates a new instance with all elements initialized to the specified value. @@ -615,8 +614,7 @@ public static Vector512 Create(T[] values) ThrowHelper.ThrowArgumentOutOfRange_IndexMustBeLessOrEqualException(); } - ref byte address = ref Unsafe.As(ref MemoryMarshal.GetArrayDataReference(values)); - return Unsafe.ReadUnaligned>(ref address); + return Unsafe.ReadUnaligned>(ref Unsafe.As(ref values[0])); } /// Creates a new from a given array. @@ -636,8 +634,7 @@ public static Vector512 Create(T[] values, int index) ThrowHelper.ThrowArgumentOutOfRange_IndexMustBeLessOrEqualException(); } - ref byte address = ref Unsafe.As(ref MemoryMarshal.GetArrayDataReference(values)); - return Unsafe.ReadUnaligned>(ref Unsafe.Add(ref address, index)); + return Unsafe.ReadUnaligned>(ref Unsafe.As(ref values[index])); } /// Creates a new from a given readonly span. @@ -654,8 +651,7 @@ public static Vector512 Create(ReadOnlySpan values) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.values); } - ref byte address = ref Unsafe.As(ref MemoryMarshal.GetReference(values)); - return Unsafe.ReadUnaligned>(ref address); + return Unsafe.ReadUnaligned>(ref Unsafe.As(ref MemoryMarshal.GetReference(values))); } /// Creates a new instance with each element initialized to the corresponding specified value. @@ -2739,8 +2735,7 @@ public static bool TryCopyTo(this Vector512 vector, Span destination) return false; } - ref byte address = ref Unsafe.As(ref MemoryMarshal.GetReference(destination)); - Unsafe.WriteUnaligned(ref address, vector); + Unsafe.WriteUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(destination)), vector); return true; } diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs index cf1f6cec9be38d..0288e9b6b5408e 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs @@ -4517,6 +4517,22 @@ public void Vector128SingleEqualsNonCanonicalNaNTest() } } + [Fact] + public void Vector128SingleCreateFromArrayTest() + { + float[] array = [1.0f, 2.0f, 3.0f, 4.0f, 5.0f]; + Vector128 vector = Vector128.Create(array); + Assert.Equal(Vector128.Create(1.0f, 2.0f, 3.0f, 4.0f), vector); + } + + [Fact] + public void Vector128SingleCreateFromArrayOffsetTest() + { + float[] array = [1.0f, 2.0f, 3.0f, 4.0f, 5.0f]; + Vector128 vector = Vector128.Create(array, 1); + Assert.Equal(Vector128.Create(2.0f, 3.0f, 4.0f, 5.0f), vector); + } + [Fact] public void Vector128SingleCopyToTest() { diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs index 95c05c50310fe3..109e58da096688 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs @@ -5539,6 +5539,22 @@ public void Vector256SingleEqualsNonCanonicalNaNTest() } } + [Fact] + public void Vector256SingleCreateFromArrayTest() + { + float[] array = [1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f]; + Vector256 vector = Vector256.Create(array); + Assert.Equal(Vector256.Create(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f), vector); + } + + [Fact] + public void Vector256SingleCreateFromArrayOffsetTest() + { + float[] array = [1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f]; + Vector256 vector = Vector256.Create(array, 1); + Assert.Equal(Vector256.Create(2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f), vector); + } + [Fact] public void Vector256SingleCopyToTest() { diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs index 2b97f49d914981..0bc2b15c2aadc2 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs @@ -5016,6 +5016,22 @@ public void Vector512SingleEqualsNonCanonicalNaNTest() } } + [Fact] + public void Vector512SingleCreateFromArrayTest() + { + float[] array = [1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f]; + Vector512 vector = Vector512.Create(array); + Assert.Equal(Vector512.Create(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f), vector); + } + + [Fact] + public void Vector512SingleCreateFromArrayOffsetTest() + { + float[] array = [1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f]; + Vector512 vector = Vector512.Create(array, 1); + Assert.Equal(Vector512.Create(2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f), vector); + } + [Fact] public void Vector512SingleCopyToTest() { diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs index 46aed6abbb06a8..72293b224282b8 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs @@ -3937,6 +3937,22 @@ public void Vector64SingleEqualsNonCanonicalNaNTest() } } + [Fact] + public void Vector64SingleCreateFromArrayTest() + { + float[] array = [1.0f, 2.0f, 3.0f]; + Vector64 vector = Vector64.Create(array); + Assert.Equal(Vector64.Create(1.0f, 2.0f), vector); + } + + [Fact] + public void Vector64SingleCreateFromArrayOffsetTest() + { + float[] array = [1.0f, 2.0f, 3.0f]; + Vector64 vector = Vector64.Create(array, 1); + Assert.Equal(Vector64.Create(2.0f, 3.0f), vector); + } + [Fact] public void Vector64SingleCopyToTest() { From c192fbadef5a315a796b5918b29baebd06157b74 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 14:19:42 -0800 Subject: [PATCH 621/783] [release/8.0-staging] Implement faster RSA key check Co-authored-by: Kevin Jones --- .../apibridge.c | 23 ++ .../apibridge.h | 4 + .../openssl_1_0_structs.h | 11 +- .../opensslshim.h | 35 +++ .../osslcompat_111.h | 7 + .../pal_evp_pkey.c | 249 +++++++++++++++++- 6 files changed, 317 insertions(+), 12 deletions(-) diff --git a/src/native/libs/System.Security.Cryptography.Native/apibridge.c b/src/native/libs/System.Security.Cryptography.Native/apibridge.c index bad65ee2b50211..5c8d05d17c74d4 100644 --- a/src/native/libs/System.Security.Cryptography.Native/apibridge.c +++ b/src/native/libs/System.Security.Cryptography.Native/apibridge.c @@ -442,6 +442,14 @@ void local_RSA_get0_crt_params(const RSA* rsa, const BIGNUM** dmp1, const BIGNUM } } +int local_RSA_get_multi_prime_extra_count(const RSA* rsa) +{ + (void)rsa; + // OpenSSL before 1.1 does not support multi-prime RSA, so it implicitly + // has zero extra primes. + return 0; +} + int32_t local_RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d) { if (rsa == NULL) @@ -909,4 +917,19 @@ int local_BN_is_zero(const BIGNUM* a) return a->top == 0; } +int local_BN_is_one(const BIGNUM* a) +{ + return BN_abs_is_word(a, 1) && !a->neg; +} + +int local_BN_abs_is_word(const BIGNUM *a, const BN_ULONG w) +{ + return ((a->top == 1) && (a->d[0] == w)) || ((w == 0) && (a->top == 0)); +} + +int local_BN_is_odd(const BIGNUM* a) +{ + return (a->top > 0) && (a->d[0] & 1); +} + #endif diff --git a/src/native/libs/System.Security.Cryptography.Native/apibridge.h b/src/native/libs/System.Security.Cryptography.Native/apibridge.h index 93cff0d2fd11ed..06bfa4c2fe8fb9 100644 --- a/src/native/libs/System.Security.Cryptography.Native/apibridge.h +++ b/src/native/libs/System.Security.Cryptography.Native/apibridge.h @@ -7,7 +7,10 @@ #include "pal_types.h" int local_ASN1_TIME_to_tm(const ASN1_TIME* s, struct tm* tm); +int local_BN_abs_is_word(const BIGNUM *a, const BN_ULONG w); int local_BN_is_zero(const BIGNUM* a); +int local_BN_is_odd(const BIGNUM* a); +int local_BN_is_one(const BIGNUM* a); int local_BIO_up_ref(BIO *a); const BIGNUM* local_DSA_get0_key(const DSA* dsa, const BIGNUM** pubKey, const BIGNUM** privKey); void local_DSA_get0_pqg(const DSA* dsa, const BIGNUM** p, const BIGNUM** q, const BIGNUM** g); @@ -27,6 +30,7 @@ long local_OpenSSL_version_num(void); void local_RSA_get0_crt_params(const RSA* rsa, const BIGNUM** dmp1, const BIGNUM** dmq1, const BIGNUM** iqmp); void local_RSA_get0_factors(const RSA* rsa, const BIGNUM** p, const BIGNUM** q); void local_RSA_get0_key(const RSA* rsa, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d); +int local_RSA_get_multi_prime_extra_count(const RSA* r); int32_t local_RSA_meth_get_flags(const RSA_METHOD* meth); int32_t local_RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp); int32_t local_RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q); diff --git a/src/native/libs/System.Security.Cryptography.Native/openssl_1_0_structs.h b/src/native/libs/System.Security.Cryptography.Native/openssl_1_0_structs.h index 486dbb902de3b3..f13fa7ba79d00c 100644 --- a/src/native/libs/System.Security.Cryptography.Native/openssl_1_0_structs.h +++ b/src/native/libs/System.Security.Cryptography.Native/openssl_1_0_structs.h @@ -185,10 +185,11 @@ struct bio_st int references; }; -struct bignum_st { - const void* _ignored1; +struct bignum_st +{ + BN_ULONG *d; int top; - int _ignored2; - int _ignored3; - int _ignored4; + int dmax; + int neg; + int flags; }; diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index 0748e305d5ce0c..1f1b1851f098aa 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -55,6 +55,9 @@ #if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM // Remove problematic #defines +#undef BN_abs_is_word +#undef BN_is_odd +#undef BN_is_one #undef BN_is_zero #undef SSL_get_state #undef SSL_is_init_finished @@ -200,15 +203,28 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len); FALLBACK_FUNCTION(BIO_up_ref) \ REQUIRED_FUNCTION(BIO_s_mem) \ REQUIRED_FUNCTION(BIO_write) \ + FALLBACK_FUNCTION(BN_abs_is_word) \ REQUIRED_FUNCTION(BN_bin2bn) \ REQUIRED_FUNCTION(BN_bn2bin) \ REQUIRED_FUNCTION(BN_clear_free) \ + REQUIRED_FUNCTION(BN_cmp) \ + REQUIRED_FUNCTION(BN_div) \ REQUIRED_FUNCTION(BN_dup) \ REQUIRED_FUNCTION(BN_free) \ + REQUIRED_FUNCTION(BN_gcd) \ + FALLBACK_FUNCTION(BN_is_odd) \ + FALLBACK_FUNCTION(BN_is_one) \ FALLBACK_FUNCTION(BN_is_zero) \ + REQUIRED_FUNCTION(BN_mod_inverse) \ + REQUIRED_FUNCTION(BN_mod_mul) \ + REQUIRED_FUNCTION(BN_mul) \ REQUIRED_FUNCTION(BN_new) \ REQUIRED_FUNCTION(BN_num_bits) \ REQUIRED_FUNCTION(BN_set_word) \ + REQUIRED_FUNCTION(BN_sub) \ + REQUIRED_FUNCTION(BN_value_one) \ + REQUIRED_FUNCTION(BN_CTX_new) \ + REQUIRED_FUNCTION(BN_CTX_free) \ LEGACY_FUNCTION(CRYPTO_add_lock) \ REQUIRED_FUNCTION(CRYPTO_free) \ REQUIRED_FUNCTION(CRYPTO_get_ex_new_index) \ @@ -474,6 +490,7 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len); REQUIRED_FUNCTION(RSA_free) \ REQUIRED_FUNCTION(RSA_generate_key_ex) \ REQUIRED_FUNCTION(RSA_get_method) \ + FALLBACK_FUNCTION(RSA_get_multi_prime_extra_count) \ FALLBACK_FUNCTION(RSA_get0_crt_params) \ FALLBACK_FUNCTION(RSA_get0_factors) \ FALLBACK_FUNCTION(RSA_get0_key) \ @@ -700,15 +717,28 @@ FOR_ALL_OPENSSL_FUNCTIONS #define BIO_up_ref BIO_up_ref_ptr #define BIO_s_mem BIO_s_mem_ptr #define BIO_write BIO_write_ptr +#define BN_abs_is_word BN_abs_is_word_ptr #define BN_bin2bn BN_bin2bn_ptr #define BN_bn2bin BN_bn2bin_ptr #define BN_clear_free BN_clear_free_ptr +#define BN_cmp BN_cmp_ptr +#define BN_div BN_div_ptr #define BN_dup BN_dup_ptr #define BN_free BN_free_ptr +#define BN_gcd BN_gcd_ptr +#define BN_is_odd BN_is_odd_ptr +#define BN_is_one BN_is_one_ptr #define BN_is_zero BN_is_zero_ptr +#define BN_mod_inverse BN_mod_inverse_ptr +#define BN_mod_mul BN_mod_mul_ptr +#define BN_mul BN_mul_ptr #define BN_new BN_new_ptr #define BN_num_bits BN_num_bits_ptr #define BN_set_word BN_set_word_ptr +#define BN_sub BN_sub_ptr +#define BN_value_one BN_value_one_ptr +#define BN_CTX_free BN_CTX_free_ptr +#define BN_CTX_new BN_CTX_new_ptr #define CRYPTO_add_lock CRYPTO_add_lock_ptr #define CRYPTO_free CRYPTO_free_ptr #define CRYPTO_get_ex_new_index CRYPTO_get_ex_new_index_ptr @@ -977,6 +1007,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #define RSA_get0_factors RSA_get0_factors_ptr #define RSA_get0_key RSA_get0_key_ptr #define RSA_get_method RSA_get_method_ptr +#define RSA_get_multi_prime_extra_count RSA_get_multi_prime_extra_count_ptr #define RSA_meth_get_flags RSA_meth_get_flags_ptr #define RSA_new RSA_new_ptr #define RSA_pkey_ctx_ctrl RSA_pkey_ctx_ctrl_ptr @@ -1236,6 +1267,9 @@ FOR_ALL_OPENSSL_FUNCTIONS // Alias "future" API to the local_ version. #define ASN1_TIME_to_tm local_ASN1_TIME_to_tm +#define BN_abs_is_word local_BN_abs_is_word +#define BN_is_odd local_BN_is_odd +#define BN_is_one local_BN_is_one #define BN_is_zero local_BN_is_zero #define BIO_up_ref local_BIO_up_ref #define DSA_get0_key local_DSA_get0_key @@ -1253,6 +1287,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #define HMAC_CTX_free local_HMAC_CTX_free #define HMAC_CTX_new local_HMAC_CTX_new #define OpenSSL_version_num local_OpenSSL_version_num +#define RSA_get_multi_prime_extra_count local_RSA_get_multi_prime_extra_count #define RSA_get0_crt_params local_RSA_get0_crt_params #define RSA_get0_factors local_RSA_get0_factors #define RSA_get0_key local_RSA_get0_key diff --git a/src/native/libs/System.Security.Cryptography.Native/osslcompat_111.h b/src/native/libs/System.Security.Cryptography.Native/osslcompat_111.h index 2581e7f8150682..a56becf4f85578 100644 --- a/src/native/libs/System.Security.Cryptography.Native/osslcompat_111.h +++ b/src/native/libs/System.Security.Cryptography.Native/osslcompat_111.h @@ -6,6 +6,9 @@ #pragma once #include "pal_types.h" +#undef BN_abs_is_word +#undef BN_is_odd +#undef BN_is_one #undef BN_is_zero #undef SSL_CTX_set_options #undef SSL_set_options @@ -21,6 +24,9 @@ typedef struct stack_st OPENSSL_STACK; #define OPENSSL_INIT_LOAD_SSL_STRINGS 0x00200000L int ASN1_TIME_to_tm(const ASN1_TIME* s, struct tm* tm); +int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w); +int BN_is_odd(const BIGNUM* a); +int BN_is_one(const BIGNUM* a); int BN_is_zero(const BIGNUM* a); int BIO_up_ref(BIO* a); const BIGNUM* DSA_get0_key(const DSA* dsa, const BIGNUM** pubKey, const BIGNUM** privKey); @@ -52,6 +58,7 @@ const RSA_METHOD* RSA_PKCS1_OpenSSL(void); void RSA_get0_crt_params(const RSA* rsa, const BIGNUM** dmp1, const BIGNUM** dmq1, const BIGNUM** iqmp); void RSA_get0_factors(const RSA* rsa, const BIGNUM** p, const BIGNUM** q); void RSA_get0_key(const RSA* rsa, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d); +int RSA_get_multi_prime_extra_count(const RSA* r); int32_t RSA_meth_get_flags(const RSA_METHOD* meth); int32_t RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_t p1, void* p2); int32_t RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp); diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c index 6cf59b97d057e8..80183b97a77c90 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c @@ -89,7 +89,231 @@ int32_t CryptoNative_UpRefEvpPkey(EVP_PKEY* pkey) return EVP_PKEY_up_ref(pkey); } -static bool CheckKey(EVP_PKEY* key, int32_t algId, int32_t (*check_func)(EVP_PKEY_CTX*)) +static bool Lcm(const BIGNUM* num1, const BIGNUM* num2, BN_CTX* ctx, BIGNUM* result) +{ + assert(result); + + // lcm(num1, num2) = (num1 * num2) / gcd(num1, num2) + BIGNUM* mul = NULL; + BIGNUM* gcd = NULL; + bool ret = false; + + if ((mul = BN_new()) == NULL || + (gcd = BN_new()) == NULL || + !BN_mul(mul, num1, num2, ctx) || + !BN_gcd(gcd, num1, num2, ctx) || + !BN_div(result, NULL, mul, gcd, ctx)) + { + goto done; + } + + ret = true; +done: + BN_clear_free(mul); + BN_clear_free(gcd); + return ret; +} + +static int32_t QuickRsaCheck(const RSA* rsa, bool isPublic) +{ + // This method does some lightweight key consistency checks on an RSA key to make sure all supplied values are + // sensible. This is not intended to be a strict key check that verifies a key conforms to any particular set + // of criteria or standards. + + const BIGNUM* n = NULL; + const BIGNUM* e = NULL; + const BIGNUM* d = NULL; + const BIGNUM* p = NULL; + const BIGNUM* q = NULL; + const BIGNUM* dp = NULL; + const BIGNUM* dq = NULL; + const BIGNUM* inverseQ = NULL; + BN_CTX* ctx = NULL; + + // x and y are scratch integers that receive the result of some operations. + BIGNUM* x = NULL; + BIGNUM* y = NULL; + + // pM1 and qM1 are to hold p-1 and q-1, respectively. We need these values a couple of times, so don't waste time + // recomputing them in scratch integers. + BIGNUM* pM1 = NULL; + BIGNUM* qM1 = NULL; + int ret = 0; + + RSA_get0_key(rsa, &n, &e, &d); + + // Always need public parameters. + if (!n || !e) + { + ERR_PUT_error(ERR_LIB_RSA, 0, RSA_R_VALUE_MISSING, __FILE__, __LINE__); + goto done; + } + + // Compatibility: We put this error for OpenSSL 1.0.2 and 1.1.x when the modulus is zero because OpenSSL did not + // handle this correctly. Continue to use the same error if the modulus is zero. + if (BN_is_zero(n)) + { + ERR_put_error(ERR_LIB_EVP, 0, EVP_R_DECODE_ERROR, __FILE__, __LINE__); + goto done; + } + + // OpenSSL has kept this value at 16,384 for all versions. + if (BN_num_bits(n) > OPENSSL_RSA_MAX_MODULUS_BITS) + { + ERR_PUT_error(ERR_LIB_RSA, 0, RSA_R_MODULUS_TOO_LARGE, __FILE__, __LINE__); + goto done; + } + + // Exponent cannot be 1 and must be odd + if (BN_is_one(e) || !BN_is_odd(e)) + { + ERR_PUT_error(ERR_LIB_RSA, 0, RSA_R_BAD_E_VALUE, __FILE__, __LINE__); + goto done; + } + + // At this point everything that is public has been checked. Mark as successful and clean up. + if (isPublic) + { + ret = 1; + goto done; + } + + // We do not support validating multi-prime RSA. Multi-prime RSA is not common. For these, we fall back to the + // OpenSSL key check. + if (RSA_get_multi_prime_extra_count(rsa) != 0) + { + ret = -1; + goto done; + } + + // Get the private components now that we've moved on to checking the private parameters. + RSA_get0_factors(rsa, &p, &q); + + // Need all the private parameters now. If we cannot get them, fall back to the OpenSSL key check so the provider + // or engine routine can be used. + if (!d || !p || !q) + { + ret = -1; + goto done; + } + + // Check that d is less than n. + if (BN_cmp(d, n) >= 0) + { + ERR_put_error(ERR_LIB_EVP, 0, EVP_R_DECODE_ERROR, __FILE__, __LINE__); + goto done; + } + + // Set up the scratch integers + if ((ctx = BN_CTX_new()) == NULL || + (x = BN_new()) == NULL || + (y = BN_new()) == NULL || + (pM1 = BN_new()) == NULL || + (qM1 = BN_new()) == NULL) + { + goto done; + } + + // multiply p and q and put the result in x. + if (!BN_mul(x, p, q, ctx)) + { + goto done; + } + + // p * q == n + if (BN_cmp(x, n) != 0) + { + ERR_PUT_error(ERR_LIB_RSA, 0, RSA_R_N_DOES_NOT_EQUAL_P_Q, __FILE__, __LINE__); + goto done; + } + + // Checking congruence of private parameters. + // de = 1 % lambda(n) + // lambda(n) = lcm(p-1, q-1) + // lambda(n) is known to be lambda(pq) already. + // pM1 = p-1 + // qM1 = q-1 + // x = lcm(pM1, qM1) + // Note that we are checking that these values have a valid relationship, not that the parameters + // are canonically correct. The d parameter (and subsequent derived parameters) may have more than + // one working value, but we do not check the the value is the "best" possible value. + if (!BN_sub(pM1, p, BN_value_one()) || !BN_sub(qM1, q, BN_value_one()) || !Lcm(pM1, qM1, ctx, x)) + { + goto done; + } + + // de % lambda(n) + // put the result in y + if (!BN_mod_mul(y, d, e, x, ctx)) + { + goto done; + } + + // Given de = 1 % lambda(n), de % lambda(n) should be one. + if (!BN_is_one(y)) + { + ERR_PUT_error(ERR_LIB_RSA, 0, RSA_R_D_E_NOT_CONGRUENT_TO_1, __FILE__, __LINE__); + goto done; + } + + // Move on to checking the CRT parameters. In compatibility with what OpenSSL does, + // these are optional and only check them if all are present. + RSA_get0_crt_params(rsa, &dp, &dq, &inverseQ); + + if (dp && dq && inverseQ) + { + // Check dp = d % (p-1) + // compute d % (p-1) and put in x + if (!BN_div(NULL, x, d, pM1, ctx)) + { + goto done; + } + + if (BN_cmp(x, dp) != 0) + { + ERR_PUT_error(ERR_LIB_RSA, 0, RSA_R_DMP1_NOT_CONGRUENT_TO_D, __FILE__, __LINE__); + goto done; + } + + // Check dq = d % (q-1) + // compute d % (q-1) and put in x + if (!BN_div(NULL, x, d, qM1, ctx)) + { + goto done; + } + + if (BN_cmp(x, dq) != 0) + { + ERR_PUT_error(ERR_LIB_RSA, 0, RSA_R_DMQ1_NOT_CONGRUENT_TO_D, __FILE__, __LINE__); + goto done; + } + + // Check inverseQ = q^-1 % p + // Use mod_inverse and put the result in x. + if (!BN_mod_inverse(x, q, p, ctx)) + { + goto done; + } + + if (BN_cmp(x, inverseQ) != 0) + { + ERR_PUT_error(ERR_LIB_RSA, 0, RSA_R_IQMP_NOT_INVERSE_OF_Q, __FILE__, __LINE__); + goto done; + } + } + + // If we made it to the end, everything looks good. + ret = 1; +done: + if (x) BN_clear_free(x); + if (y) BN_clear_free(y); + if (pM1) BN_clear_free(pM1); + if (qM1) BN_clear_free(qM1); + if (ctx) BN_CTX_free(ctx); + return ret; +} + +static bool CheckKey(EVP_PKEY* key, int32_t algId, bool isPublic, int32_t (*check_func)(EVP_PKEY_CTX*)) { if (algId != NID_undef && EVP_PKEY_get_base_id(key) != algId) { @@ -104,16 +328,27 @@ static bool CheckKey(EVP_PKEY* key, int32_t algId, int32_t (*check_func)(EVP_PKE { const RSA* rsa = EVP_PKEY_get0_RSA(key); + // If we can get the RSA object, use that for a faster path to validating the key that skips primality tests. if (rsa != NULL) { - const BIGNUM* modulus = NULL; - RSA_get0_key(rsa, &modulus, NULL, NULL); + // 0 = key check failed + // 1 = key check passed + // -1 = could not assess private key. + int32_t result = QuickRsaCheck(rsa, isPublic); - if (modulus != NULL && BN_is_zero(modulus)) + if (result == 0) { - ERR_put_error(ERR_LIB_EVP, 0, EVP_R_DECODE_ERROR, __FILE__, __LINE__); return false; } + if (result == 1) + { + return true; + } + + // -1 falls though. + // If the fast check was indeterminate, fall though and use the OpenSSL routine. + // Clear out any errors we may have accumulated in our check. + ERR_clear_error(); } } @@ -149,7 +384,7 @@ EVP_PKEY* CryptoNative_DecodeSubjectPublicKeyInfo(const uint8_t* buf, int32_t le EVP_PKEY* key = d2i_PUBKEY(NULL, &buf, len); - if (key != NULL && !CheckKey(key, algId, EVP_PKEY_public_check)) + if (key != NULL && !CheckKey(key, algId, true, EVP_PKEY_public_check)) { EVP_PKEY_free(key); key = NULL; @@ -175,7 +410,7 @@ EVP_PKEY* CryptoNative_DecodePkcs8PrivateKey(const uint8_t* buf, int32_t len, in EVP_PKEY* key = EVP_PKCS82PKEY(p8info); PKCS8_PRIV_KEY_INFO_free(p8info); - if (key != NULL && !CheckKey(key, algId, EVP_PKEY_check)) + if (key != NULL && !CheckKey(key, algId, false, EVP_PKEY_check)) { EVP_PKEY_free(key); key = NULL; From 11a4ff1a98fc7607d0f4c2d1d04a43661f3caf64 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 14:24:35 -0800 Subject: [PATCH 622/783] [release/8.0-staging] ServiceKey comparisons use Equals for matching (#96847) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * RemoveAllKeyed use Equals for matching This brings RemoveAllKeyed in line with service resolution (ServiceProvider.GetRequiredKeyedService) * Use equals for TryAdd and Replace * Add packaging info to csproj --------- Co-authored-by: Tommy Sørbråten Co-authored-by: Steve Harter --- ...iceCollectionDescriptorExtensions.Keyed.cs | 2 +- .../ServiceCollectionDescriptorExtensions.cs | 6 +- ...ns.DependencyInjection.Abstractions.csproj | 2 + ...iceCollectionKeyedServiceExtensionsTest.cs | 91 +++++++++++++++++++ 4 files changed, 97 insertions(+), 4 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.Keyed.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.Keyed.cs index aad0b4ff2fe414..436f108e5eb5f2 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.Keyed.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.Keyed.cs @@ -401,7 +401,7 @@ public static IServiceCollection RemoveAllKeyed(this IServiceCollection collecti for (int i = collection.Count - 1; i >= 0; i--) { ServiceDescriptor? descriptor = collection[i]; - if (descriptor.ServiceType == serviceType && descriptor.ServiceKey == serviceKey) + if (descriptor.ServiceType == serviceType && object.Equals(descriptor.ServiceKey, serviceKey)) { collection.RemoveAt(i); } diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.cs index f2435dca6cfcee..2d000f17105832 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Extensions/ServiceCollectionDescriptorExtensions.cs @@ -67,7 +67,7 @@ public static void TryAdd( for (int i = 0; i < count; i++) { if (collection[i].ServiceType == descriptor.ServiceType - && collection[i].ServiceKey == descriptor.ServiceKey) + && object.Equals(collection[i].ServiceKey, descriptor.ServiceKey)) { // Already added return; @@ -474,7 +474,7 @@ public static void TryAddEnumerable( ServiceDescriptor service = services[i]; if (service.ServiceType == descriptor.ServiceType && service.GetImplementationType() == implementationType && - service.ServiceKey == descriptor.ServiceKey) + object.Equals(service.ServiceKey, descriptor.ServiceKey)) { // Already added return; @@ -532,7 +532,7 @@ public static IServiceCollection Replace( int count = collection.Count; for (int i = 0; i < count; i++) { - if (collection[i].ServiceType == descriptor.ServiceType && collection[i].ServiceKey == descriptor.ServiceKey) + if (collection[i].ServiceType == descriptor.ServiceType && object.Equals(collection[i].ServiceKey, descriptor.ServiceKey)) { collection.RemoveAt(i); break; diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj index 422c5bef17065a..134bae2b58535f 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj @@ -4,6 +4,8 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.1;netstandard2.0;$(NetFrameworkMinimum) true true + true + 1 Abstractions for dependency injection. Commonly Used Types: diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionKeyedServiceExtensionsTest.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionKeyedServiceExtensionsTest.cs index 25b61065ef0ba3..6be7e22cce2c35 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionKeyedServiceExtensionsTest.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionKeyedServiceExtensionsTest.cs @@ -170,6 +170,7 @@ public static TheoryData TryAddImplementationTypeData { collection => collection.TryAddKeyedTransient("key-2"), serviceType, "key-2", implementationType, ServiceLifetime.Transient }, { collection => collection.TryAddKeyedTransient("key-3"), serviceType, "key-3", serviceType, ServiceLifetime.Transient }, { collection => collection.TryAddKeyedTransient(implementationType, "key-4"), implementationType, "key-4", implementationType, ServiceLifetime.Transient }, + { collection => collection.TryAddKeyedTransient(implementationType, 9), implementationType, 9, implementationType, ServiceLifetime.Transient }, { collection => collection.TryAddKeyedScoped(serviceType, "key-1", implementationType), serviceType, "key-1", implementationType, ServiceLifetime.Scoped }, { collection => collection.TryAddKeyedScoped("key-2"), serviceType, "key-2", implementationType, ServiceLifetime.Scoped }, @@ -325,6 +326,40 @@ public void TryAddEnumerable_DoesNotAddDuplicate( Assert.Equal(expectedLifetime, d.Lifetime); } + [Fact] + public void TryAddEnumerable_DoesNotAddDuplicateWhenKeyIsInt() + { + // Arrange + var collection = new ServiceCollection(); + var descriptor1 = ServiceDescriptor.KeyedTransient(1); + collection.TryAddEnumerable(descriptor1); + var descriptor2 = ServiceDescriptor.KeyedTransient(1); + + // Act + collection.TryAddEnumerable(descriptor2); + + // Assert + var d = Assert.Single(collection); + Assert.Same(descriptor1, d); + } + + [Fact] + public void TryAddEnumerable_DoesNotAddDuplicateWhenKeyIsString() + { + // Arrange + var collection = new ServiceCollection(); + var descriptor1 = ServiceDescriptor.KeyedTransient("service1"); + collection.TryAddEnumerable(descriptor1); + var descriptor2 = ServiceDescriptor.KeyedTransient("service1"); + + // Act + collection.TryAddEnumerable(descriptor2); + + // Assert + var d = Assert.Single(collection); + Assert.Same(descriptor1, d); + } + public static TheoryData TryAddEnumerableInvalidImplementationTypeData { get @@ -412,6 +447,24 @@ public void Replace_ReplacesFirstServiceWithMatchingServiceType() Assert.Equal(new[] { descriptor2, descriptor3 }, collection); } + [Fact] + public void Replace_ReplacesFirstServiceWithMatchingServiceTypeWhenKeyIsInt() + { + // Arrange + var collection = new ServiceCollection(); + var descriptor1 = new ServiceDescriptor(typeof(IFakeService), 1, typeof(FakeService), ServiceLifetime.Transient); + var descriptor2 = new ServiceDescriptor(typeof(IFakeService), 1, typeof(FakeService), ServiceLifetime.Transient); + collection.Add(descriptor1); + collection.Add(descriptor2); + var descriptor3 = new ServiceDescriptor(typeof(IFakeService), 1, typeof(FakeService), ServiceLifetime.Singleton); + + // Act + collection.Replace(descriptor3); + + // Assert + Assert.Equal(new[] { descriptor2, descriptor3 }, collection); + } + [Fact] public void RemoveAll_RemovesAllServicesWithMatchingServiceType() { @@ -431,6 +484,44 @@ public void RemoveAll_RemovesAllServicesWithMatchingServiceType() Assert.Equal(new[] { descriptor }, collection); } + private enum ServiceKeyEnum { First, Second } + + [Fact] + public void RemoveAll_RemovesAllMatchingServicesWhenKeyIsEnum() + { + var descriptor = new ServiceDescriptor(typeof(IFakeService), ServiceKeyEnum.First, typeof(FakeService), ServiceLifetime.Transient); + var collection = new ServiceCollection + { + descriptor, + new ServiceDescriptor(typeof(IFakeService), ServiceKeyEnum.Second, typeof(FakeService), ServiceLifetime.Transient), + new ServiceDescriptor(typeof(IFakeService), ServiceKeyEnum.Second, typeof(FakeService), ServiceLifetime.Transient), + }; + + // Act + collection.RemoveAllKeyed(ServiceKeyEnum.Second); + + // Assert + Assert.Equal(new[] { descriptor }, collection); + } + + [Fact] + public void RemoveAll_RemovesAllMatchingServicesWhenKeyIsInt() + { + var descriptor = new ServiceDescriptor(typeof(IFakeService), 1, typeof(FakeService), ServiceLifetime.Transient); + var collection = new ServiceCollection + { + descriptor, + new ServiceDescriptor(typeof(IFakeService), 2, typeof(FakeService), ServiceLifetime.Transient), + new ServiceDescriptor(typeof(IFakeService), 2, typeof(FakeService), ServiceLifetime.Transient), + }; + + // Act + collection.RemoveAllKeyed(2); + + // Assert + Assert.Equal(new[] { descriptor }, collection); + } + public static TheoryData NullServiceKeyData { get From 0c7efec09666babeebea1f608c91757b8faccca0 Mon Sep 17 00:00:00 2001 From: Natalia Kondratyeva Date: Wed, 14 Feb 2024 18:02:10 +0000 Subject: [PATCH 623/783] [release/8.0] Fix HTTP/2 WebSocket Abort --- .../SocketsHttpHandler/Http2Connection.cs | 8 + .../Http/SocketsHttpHandler/Http2Stream.cs | 97 +++++-- ...etsHttpHandlerTest.Http2ExtendedConnect.cs | 157 ++++++++++- .../tests/AbortTest.Loopback.cs | 246 ++++++++++++++++++ .../tests/LoopbackHelper.cs | 21 +- .../LoopbackServer/Http2LoopbackStream.cs | 100 +++++++ .../LoopbackServer/LoopbackWebSocketServer.cs | 148 +++++++++++ .../WebSocketHandshakeHelper.cs | 134 ++++++++++ .../LoopbackServer/WebSocketRequestData.cs | 20 ++ .../System.Net.WebSockets.Client.Tests.csproj | 5 + 10 files changed, 902 insertions(+), 34 deletions(-) create mode 100644 src/libraries/System.Net.WebSockets.Client/tests/AbortTest.Loopback.cs create mode 100644 src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/Http2LoopbackStream.cs create mode 100644 src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.cs create mode 100644 src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketHandshakeHelper.cs create mode 100644 src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketRequestData.cs diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs index e9cce1c24d34d5..14c9685a4f511a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs @@ -1446,6 +1446,14 @@ private int WriteHeaderCollection(HttpRequestMessage request, HttpHeaders header continue; } + // Extended connect requests will use the response content stream for bidirectional communication. + // We will ignore any content set for such requests in Http2Stream.SendRequestBodyAsync, as it has no defined semantics. + // Drop the Content-Length header as well in the unlikely case it was set. + if (knownHeader == KnownHeaders.ContentLength && request.IsExtendedConnectRequest) + { + continue; + } + // For all other known headers, send them via their pre-encoded name and the associated value. WriteBytes(knownHeader.Http2EncodedName, ref headerBuffer); string? separator = null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs index de66b7cfa103d2..d834679274b4a8 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs @@ -105,7 +105,9 @@ public Http2Stream(HttpRequestMessage request, Http2Connection connection) _headerBudgetRemaining = connection._pool.Settings.MaxResponseHeadersByteLength; - if (_request.Content == null) + // Extended connect requests will use the response content stream for bidirectional communication. + // We will ignore any content set for such requests in SendRequestBodyAsync, as it has no defined semantics. + if (_request.Content == null || _request.IsExtendedConnectRequest) { _requestCompletionState = StreamCompletionState.Completed; if (_request.IsExtendedConnectRequest) @@ -173,7 +175,9 @@ public HttpResponseMessage GetAndClearResponse() public async Task SendRequestBodyAsync(CancellationToken cancellationToken) { - if (_request.Content == null) + // Extended connect requests will use the response content stream for bidirectional communication. + // Ignore any content set for such requests, as it has no defined semantics. + if (_request.Content == null || _request.IsExtendedConnectRequest) { Debug.Assert(_requestCompletionState == StreamCompletionState.Completed); return; @@ -250,6 +254,7 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken) // and we also don't want to propagate any error to the caller, in particular for non-duplex scenarios. Debug.Assert(_responseCompletionState == StreamCompletionState.Completed); _requestCompletionState = StreamCompletionState.Completed; + Debug.Assert(!ConnectProtocolEstablished); Complete(); return; } @@ -261,6 +266,7 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken) _requestCompletionState = StreamCompletionState.Failed; SendReset(); + Debug.Assert(!ConnectProtocolEstablished); Complete(); } @@ -313,6 +319,7 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken) if (complete) { + Debug.Assert(!ConnectProtocolEstablished); Complete(); } } @@ -420,7 +427,17 @@ private void Cancel() if (sendReset) { SendReset(); - Complete(); + + // Extended CONNECT notes: + // + // To prevent from calling it *twice*, Extended CONNECT stream's Complete() is only + // called from CloseResponseBody(), as CloseResponseBody() is *always* called + // from Extended CONNECT stream's Dispose(). + + if (!ConnectProtocolEstablished) + { + Complete(); + } } } @@ -810,7 +827,20 @@ public void OnHeadersComplete(bool endStream) Debug.Assert(_responseCompletionState == StreamCompletionState.InProgress, $"Response already completed with state={_responseCompletionState}"); _responseCompletionState = StreamCompletionState.Completed; - if (_requestCompletionState == StreamCompletionState.Completed) + + // Extended CONNECT notes: + // + // To prevent from calling it *prematurely*, Extended CONNECT stream's Complete() is only + // called from CloseResponseBody(), as CloseResponseBody() is *only* called + // from Extended CONNECT stream's Dispose(). + // + // Due to bidirectional streaming nature of the Extended CONNECT request, + // the *write side* of the stream can only be completed by calling Dispose(). + // + // The streaming in both ways happens over the single "response" stream instance, which makes + // _requestCompletionState *not indicative* of the actual state of the write side of the stream. + + if (_requestCompletionState == StreamCompletionState.Completed && !ConnectProtocolEstablished) { Complete(); } @@ -871,7 +901,20 @@ public void OnResponseData(ReadOnlySpan buffer, bool endStream) Debug.Assert(_responseCompletionState == StreamCompletionState.InProgress, $"Response already completed with state={_responseCompletionState}"); _responseCompletionState = StreamCompletionState.Completed; - if (_requestCompletionState == StreamCompletionState.Completed) + + // Extended CONNECT notes: + // + // To prevent from calling it *prematurely*, Extended CONNECT stream's Complete() is only + // called from CloseResponseBody(), as CloseResponseBody() is *only* called + // from Extended CONNECT stream's Dispose(). + // + // Due to bidirectional streaming nature of the Extended CONNECT request, + // the *write side* of the stream can only be completed by calling Dispose(). + // + // The streaming in both ways happens over the single "response" stream instance, which makes + // _requestCompletionState *not indicative* of the actual state of the write side of the stream. + + if (_requestCompletionState == StreamCompletionState.Completed && !ConnectProtocolEstablished) { Complete(); } @@ -1036,17 +1079,17 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken) Debug.Assert(_response != null && _response.Content != null); // Start to process the response body. var responseContent = (HttpConnectionResponseContent)_response.Content; - if (emptyResponse) + if (ConnectProtocolEstablished) + { + responseContent.SetStream(new Http2ReadWriteStream(this, closeResponseBodyOnDispose: true)); + } + else if (emptyResponse) { // If there are any trailers, copy them over to the response. Normally this would be handled by // the response stream hitting EOF, but if there is no response body, we do it here. MoveTrailersToResponseMessage(_response); responseContent.SetStream(EmptyReadStream.Instance); } - else if (ConnectProtocolEstablished) - { - responseContent.SetStream(new Http2ReadWriteStream(this)); - } else { responseContent.SetStream(new Http2ReadStream(this)); @@ -1309,8 +1352,25 @@ private async ValueTask SendDataAsync(ReadOnlyMemory buffer, CancellationT } } + // This method should only be called from Http2ReadWriteStream.Dispose() private void CloseResponseBody() { + // Extended CONNECT notes: + // + // Due to bidirectional streaming nature of the Extended CONNECT request, + // the *write side* of the stream can only be completed by calling Dispose() + // (which, for Extended CONNECT case, will in turn call CloseResponseBody()) + // + // Similarly to QuicStream, disposal *gracefully* closes the write side of the stream + // (unless we've received RST_STREAM before) and *abortively* closes the read side + // of the stream (unless we've received EOS before). + + if (ConnectProtocolEstablished && _resetException is null) + { + // Gracefully close the write side of the Extended CONNECT stream + _connection.LogExceptions(_connection.SendEndStreamAsync(StreamId)); + } + // Check if the response body has been fully consumed. bool fullyConsumed = false; Debug.Assert(!Monitor.IsEntered(SyncObject)); @@ -1323,6 +1383,7 @@ private void CloseResponseBody() } // If the response body isn't completed, cancel it now. + // This includes aborting the read side of the Extended CONNECT stream. if (!fullyConsumed) { Cancel(); @@ -1337,6 +1398,12 @@ private void CloseResponseBody() lock (SyncObject) { + if (ConnectProtocolEstablished) + { + // This should be the only place where Extended Connect stream is completed + Complete(); + } + _responseBuffer.Dispose(); } } @@ -1430,10 +1497,7 @@ private enum StreamCompletionState : byte private sealed class Http2ReadStream : Http2ReadWriteStream { - public Http2ReadStream(Http2Stream http2Stream) : base(http2Stream) - { - base.CloseResponseBodyOnDispose = true; - } + public Http2ReadStream(Http2Stream http2Stream) : base(http2Stream, closeResponseBodyOnDispose: true) { } public override bool CanWrite => false; @@ -1482,12 +1546,13 @@ public class Http2ReadWriteStream : HttpBaseStream private Http2Stream? _http2Stream; private readonly HttpResponseMessage _responseMessage; - public Http2ReadWriteStream(Http2Stream http2Stream) + public Http2ReadWriteStream(Http2Stream http2Stream, bool closeResponseBodyOnDispose = false) { Debug.Assert(http2Stream != null); Debug.Assert(http2Stream._response != null); _http2Stream = http2Stream; _responseMessage = _http2Stream._response; + CloseResponseBodyOnDispose = closeResponseBodyOnDispose; } ~Http2ReadWriteStream() @@ -1503,7 +1568,7 @@ public Http2ReadWriteStream(Http2Stream http2Stream) } } - protected bool CloseResponseBodyOnDispose { get; set; } + protected bool CloseResponseBodyOnDispose { get; private init; } protected override void Dispose(bool disposing) { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Http2ExtendedConnect.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Http2ExtendedConnect.cs index 0ea6ae9e13f60b..cb1a15df14e774 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Http2ExtendedConnect.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Http2ExtendedConnect.cs @@ -2,8 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Net.Test.Common; +using System.Threading; using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; @@ -31,6 +33,7 @@ public static IEnumerable UseSsl_MemberData() [MemberData(nameof(UseSsl_MemberData))] public async Task Connect_ReadWriteResponseStream(bool useSsl) { + const int MessageCount = 3; byte[] clientMessage = new byte[] { 1, 2, 3 }; byte[] serverMessage = new byte[] { 4, 5, 6, 7 }; @@ -43,19 +46,39 @@ await Http2LoopbackServerFactory.Singleton.CreateClientAndServerAsync(async uri HttpRequestMessage request = CreateRequest(HttpMethod.Connect, uri, UseVersion, exactVersion: true); request.Headers.Protocol = "foo"; + bool readFromContentStream = false; + + // We won't send the content bytes, but we will send content headers. + // Since we're dropping the content, we'll also drop the Content-Length header. + request.Content = new StreamContent(new DelegateStream( + readAsyncFunc: (_, _, _, _) => + { + readFromContentStream = true; + throw new UnreachableException(); + })); + + request.Headers.Add("User-Agent", "foo"); + request.Content.Headers.Add("Content-Language", "bar"); + request.Content.Headers.ContentLength = 42; + using HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); using Stream responseStream = await response.Content.ReadAsStreamAsync(); - await responseStream.WriteAsync(clientMessage); - await responseStream.FlushAsync(); + for (int i = 0; i < MessageCount; i++) + { + await responseStream.WriteAsync(clientMessage); + await responseStream.FlushAsync(); - byte[] readBuffer = new byte[serverMessage.Length]; - await responseStream.ReadExactlyAsync(readBuffer); - Assert.Equal(serverMessage, readBuffer); + byte[] readBuffer = new byte[serverMessage.Length]; + await responseStream.ReadExactlyAsync(readBuffer); + Assert.Equal(serverMessage, readBuffer); + } // Receive server's EOS - Assert.Equal(0, await responseStream.ReadAsync(readBuffer)); + Assert.Equal(0, await responseStream.ReadAsync(new byte[1])); + + Assert.False(readFromContentStream); clientCompleted.SetResult(); }, @@ -63,14 +86,21 @@ await Http2LoopbackServerFactory.Singleton.CreateClientAndServerAsync(async uri { await using Http2LoopbackConnection connection = await ((Http2LoopbackServer)server).EstablishConnectionAsync(new SettingsEntry { SettingId = SettingId.EnableConnect, Value = 1 }); - (int streamId, _) = await connection.ReadAndParseRequestHeaderAsync(readBody: false); + (int streamId, HttpRequestData request) = await connection.ReadAndParseRequestHeaderAsync(readBody: false); + + Assert.Equal("foo", request.GetSingleHeaderValue("User-Agent")); + Assert.Equal("bar", request.GetSingleHeaderValue("Content-Language")); + Assert.Equal(0, request.GetHeaderValueCount("Content-Length")); await connection.SendResponseHeadersAsync(streamId, endStream: false).ConfigureAwait(false); - DataFrame dataFrame = await connection.ReadDataFrameAsync(); - Assert.Equal(clientMessage, dataFrame.Data.ToArray()); + for (int i = 0; i < MessageCount; i++) + { + DataFrame dataFrame = await connection.ReadDataFrameAsync(); + Assert.Equal(clientMessage, dataFrame.Data.ToArray()); - await connection.SendResponseDataAsync(streamId, serverMessage, endStream: true); + await connection.SendResponseDataAsync(streamId, serverMessage, endStream: i == MessageCount - 1); + } await clientCompleted.Task.WaitAsync(TestHelper.PassingTestTimeout); }, options: new GenericLoopbackOptions { UseSsl = useSsl }); @@ -163,5 +193,112 @@ await server.AcceptConnectionAsync(async connection => await new[] { serverTask, clientTask }.WhenAllOrAnyFailed().WaitAsync(TestHelper.PassingTestTimeout); } + + [Theory] + [MemberData(nameof(UseSsl_MemberData))] + public async Task Connect_ServerSideEOS_ReceivedByClient(bool useSsl) + { + var timeoutTcs = new CancellationTokenSource(TestHelper.PassingTestTimeout); + var serverReceivedEOS = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + await Http2LoopbackServerFactory.Singleton.CreateClientAndServerAsync( + clientFunc: async uri => + { + var client = CreateHttpClient(); + var request = CreateRequest(HttpMethod.Connect, uri, UseVersion, exactVersion: true); + request.Headers.Protocol = "foo"; + + var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, timeoutTcs.Token); + var responseStream = await response.Content.ReadAsStreamAsync(timeoutTcs.Token); + + // receive server's EOS + Assert.Equal(0, await responseStream.ReadAsync(new byte[1], timeoutTcs.Token)); + + // send client's EOS + responseStream.Dispose(); + + // wait for "ack" from server + await serverReceivedEOS.Task.WaitAsync(timeoutTcs.Token); + + // can dispose handler now + client.Dispose(); + }, + serverFunc: async server => + { + await using var connection = await ((Http2LoopbackServer)server).EstablishConnectionAsync( + new SettingsEntry { SettingId = SettingId.EnableConnect, Value = 1 }); + + (int streamId, _) = await connection.ReadAndParseRequestHeaderAsync(readBody: false); + await connection.SendResponseHeadersAsync(streamId, endStream: false); + + // send server's EOS + await connection.SendResponseDataAsync(streamId, Array.Empty(), endStream: true); + + // receive client's EOS "in response" to server's EOS + var eosFrame = Assert.IsType(await connection.ReadFrameAsync(timeoutTcs.Token)); + Assert.Equal(streamId, eosFrame.StreamId); + Assert.Equal(0, eosFrame.Data.Length); + Assert.True(eosFrame.EndStreamFlag); + + serverReceivedEOS.SetResult(); + + // on handler dispose, client should shutdown the connection without sending additional frames + await connection.WaitForClientDisconnectAsync().WaitAsync(timeoutTcs.Token); + }, + options: new GenericLoopbackOptions { UseSsl = useSsl }); + } + + [Theory] + [MemberData(nameof(UseSsl_MemberData))] + public async Task Connect_ClientSideEOS_ReceivedByServer(bool useSsl) + { + var timeoutTcs = new CancellationTokenSource(TestHelper.PassingTestTimeout); + var serverReceivedRst = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + await Http2LoopbackServerFactory.Singleton.CreateClientAndServerAsync( + clientFunc: async uri => + { + var client = CreateHttpClient(); + var request = CreateRequest(HttpMethod.Connect, uri, UseVersion, exactVersion: true); + request.Headers.Protocol = "foo"; + + var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, timeoutTcs.Token); + var responseStream = await response.Content.ReadAsStreamAsync(timeoutTcs.Token); + + // send client's EOS + // this will also send RST_STREAM as we didn't receive server's EOS before + responseStream.Dispose(); + + // wait for "ack" from server + await serverReceivedRst.Task.WaitAsync(timeoutTcs.Token); + + // can dispose handler now + client.Dispose(); + }, + serverFunc: async server => + { + await using var connection = await ((Http2LoopbackServer)server).EstablishConnectionAsync( + new SettingsEntry { SettingId = SettingId.EnableConnect, Value = 1 }); + + (int streamId, _) = await connection.ReadAndParseRequestHeaderAsync(readBody: false); + await connection.SendResponseHeadersAsync(streamId, endStream: false); + + // receive client's EOS + var eosFrame = Assert.IsType(await connection.ReadFrameAsync(timeoutTcs.Token)); + Assert.Equal(streamId, eosFrame.StreamId); + Assert.Equal(0, eosFrame.Data.Length); + Assert.True(eosFrame.EndStreamFlag); + + // receive client's RST_STREAM as we didn't send server's EOS before + var rstFrame = Assert.IsType(await connection.ReadFrameAsync(timeoutTcs.Token)); + Assert.Equal(streamId, rstFrame.StreamId); + + serverReceivedRst.SetResult(); + + // on handler dispose, client should shutdown the connection without sending additional frames + await connection.WaitForClientDisconnectAsync().WaitAsync(timeoutTcs.Token); + }, + options: new GenericLoopbackOptions { UseSsl = useSsl }); + } } } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/AbortTest.Loopback.cs b/src/libraries/System.Net.WebSockets.Client/tests/AbortTest.Loopback.cs new file mode 100644 index 00000000000000..0aa83697a9de74 --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/AbortTest.Loopback.cs @@ -0,0 +1,246 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; + +namespace System.Net.WebSockets.Client.Tests +{ + [ConditionalClass(typeof(ClientWebSocketTestBase), nameof(WebSocketsSupported))] + [SkipOnPlatform(TestPlatforms.Browser, "System.Net.Sockets are not supported on browser")] + public abstract class AbortTest_Loopback : ClientWebSocketTestBase + { + public AbortTest_Loopback(ITestOutputHelper output) : base(output) { } + + protected virtual Version HttpVersion => Net.HttpVersion.Version11; + + [Theory] + [MemberData(nameof(AbortClient_MemberData))] + public Task AbortClient_ServerGetsCorrectException(AbortType abortType, bool useSsl, bool verifySendReceive) + { + var clientMsg = new byte[] { 1, 2, 3, 4, 5, 6 }; + var serverMsg = new byte[] { 42 }; + var clientAckTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + var serverAckTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + var timeoutCts = new CancellationTokenSource(TimeOutMilliseconds); + + return LoopbackWebSocketServer.RunAsync( + async (clientWebSocket, token) => + { + if (verifySendReceive) + { + await VerifySendReceiveAsync(clientWebSocket, clientMsg, serverMsg, clientAckTcs, serverAckTcs.Task, token); + } + + switch (abortType) + { + case AbortType.Abort: + clientWebSocket.Abort(); + break; + case AbortType.Dispose: + clientWebSocket.Dispose(); + break; + } + }, + async (serverWebSocket, token) => + { + if (verifySendReceive) + { + await VerifySendReceiveAsync(serverWebSocket, serverMsg, clientMsg, serverAckTcs, clientAckTcs.Task, token); + } + + var readBuffer = new byte[1]; + var exception = await Assert.ThrowsAsync(async () => + await serverWebSocket.ReceiveAsync(readBuffer, token)); + + Assert.Equal(WebSocketError.ConnectionClosedPrematurely, exception.WebSocketErrorCode); + Assert.Equal(WebSocketState.Aborted, serverWebSocket.State); + }, + new LoopbackWebSocketServer.Options(HttpVersion, useSsl, GetInvoker()), + timeoutCts.Token); + } + + [Theory] + [MemberData(nameof(ServerPrematureEos_MemberData))] + public Task ServerPrematureEos_ClientGetsCorrectException(ServerEosType serverEosType, bool useSsl) + { + var clientMsg = new byte[] { 1, 2, 3, 4, 5, 6 }; + var serverMsg = new byte[] { 42 }; + var clientAckTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + var serverAckTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + var timeoutCts = new CancellationTokenSource(TimeOutMilliseconds); + + var globalOptions = new LoopbackWebSocketServer.Options(HttpVersion, useSsl, HttpInvoker: null) + { + DisposeServerWebSocket = false, + ManualServerHandshakeResponse = true + }; + + var serverReceivedEosTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + var clientReceivedEosTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + return LoopbackWebSocketServer.RunAsync( + async uri => + { + var token = timeoutCts.Token; + var clientOptions = globalOptions with { HttpInvoker = GetInvoker() }; + var clientWebSocket = await LoopbackWebSocketServer.GetConnectedClientAsync(uri, clientOptions, token).ConfigureAwait(false); + + if (serverEosType == ServerEosType.AfterSomeData) + { + await VerifySendReceiveAsync(clientWebSocket, clientMsg, serverMsg, clientAckTcs, serverAckTcs.Task, token).ConfigureAwait(false); + } + + // only one side of the stream was closed. the other should work + await clientWebSocket.SendAsync(clientMsg, WebSocketMessageType.Binary, endOfMessage: true, token).ConfigureAwait(false); + + var exception = await Assert.ThrowsAsync(() => clientWebSocket.ReceiveAsync(new byte[1], token)); + Assert.Equal(WebSocketError.ConnectionClosedPrematurely, exception.WebSocketErrorCode); + + clientReceivedEosTcs.SetResult(); + clientWebSocket.Dispose(); + }, + async (requestData, token) => + { + WebSocket serverWebSocket = null!; + await SendServerResponseAndEosAsync( + requestData, + serverEosType, + (wsData, ct) => + { + var wsOptions = new WebSocketCreationOptions { IsServer = true }; + serverWebSocket = WebSocket.CreateFromStream(wsData.WebSocketStream, wsOptions); + + return serverEosType == ServerEosType.AfterSomeData + ? VerifySendReceiveAsync(serverWebSocket, serverMsg, clientMsg, serverAckTcs, clientAckTcs.Task, ct) + : Task.CompletedTask; + }, + token); + + Assert.NotNull(serverWebSocket); + + // only one side of the stream was closed. the other should work + var readBuffer = new byte[clientMsg.Length]; + var result = await serverWebSocket.ReceiveAsync(readBuffer, token); + Assert.Equal(WebSocketMessageType.Binary, result.MessageType); + Assert.Equal(clientMsg.Length, result.Count); + Assert.True(result.EndOfMessage); + Assert.Equal(clientMsg, readBuffer); + + await clientReceivedEosTcs.Task.WaitAsync(token).ConfigureAwait(false); + + var exception = await Assert.ThrowsAsync(() => serverWebSocket.ReceiveAsync(readBuffer, token)); + Assert.Equal(WebSocketError.ConnectionClosedPrematurely, exception.WebSocketErrorCode); + + serverWebSocket.Dispose(); + }, + globalOptions, + timeoutCts.Token); + } + + protected virtual Task SendServerResponseAndEosAsync(WebSocketRequestData requestData, ServerEosType serverEosType, Func serverFunc, CancellationToken cancellationToken) + => WebSocketHandshakeHelper.SendHttp11ServerResponseAndEosAsync(requestData, serverFunc, cancellationToken); // override for HTTP/2 + + private static readonly bool[] Bool_Values = new[] { false, true }; + private static readonly bool[] UseSsl_Values = PlatformDetection.SupportsAlpn ? Bool_Values : new[] { false }; + + public static IEnumerable AbortClient_MemberData() + { + foreach (var abortType in Enum.GetValues()) + { + foreach (var useSsl in UseSsl_Values) + { + foreach (var verifySendReceive in Bool_Values) + { + yield return new object[] { abortType, useSsl, verifySendReceive }; + } + } + } + } + + public static IEnumerable ServerPrematureEos_MemberData() + { + foreach (var serverEosType in Enum.GetValues()) + { + foreach (var useSsl in UseSsl_Values) + { + yield return new object[] { serverEosType, useSsl }; + } + } + } + + public enum AbortType + { + Abort, + Dispose + } + + public enum ServerEosType + { + WithHeaders, + RightAfterHeaders, + AfterSomeData + } + + private static async Task VerifySendReceiveAsync(WebSocket ws, byte[] localMsg, byte[] remoteMsg, + TaskCompletionSource localAckTcs, Task remoteAck, CancellationToken cancellationToken) + { + var sendTask = ws.SendAsync(localMsg, WebSocketMessageType.Binary, endOfMessage: true, cancellationToken); + + var recvBuf = new byte[remoteMsg.Length * 2]; + var recvResult = await ws.ReceiveAsync(recvBuf, cancellationToken).ConfigureAwait(false); + + Assert.Equal(WebSocketMessageType.Binary, recvResult.MessageType); + Assert.Equal(remoteMsg.Length, recvResult.Count); + Assert.True(recvResult.EndOfMessage); + Assert.Equal(remoteMsg, recvBuf[..recvResult.Count]); + + localAckTcs.SetResult(); + + await sendTask.ConfigureAwait(false); + await remoteAck.WaitAsync(cancellationToken).ConfigureAwait(false); + } + } + + // --- HTTP/1.1 WebSocket loopback tests --- + + public class AbortTest_Invoker_Loopback : AbortTest_Loopback + { + public AbortTest_Invoker_Loopback(ITestOutputHelper output) : base(output) { } + protected override bool UseCustomInvoker => true; + } + + public class AbortTest_HttpClient_Loopback : AbortTest_Loopback + { + public AbortTest_HttpClient_Loopback(ITestOutputHelper output) : base(output) { } + protected override bool UseHttpClient => true; + } + + public class AbortTest_SharedHandler_Loopback : AbortTest_Loopback + { + public AbortTest_SharedHandler_Loopback(ITestOutputHelper output) : base(output) { } + } + + // --- HTTP/2 WebSocket loopback tests --- + + public class AbortTest_Invoker_Http2 : AbortTest_Invoker_Loopback + { + public AbortTest_Invoker_Http2(ITestOutputHelper output) : base(output) { } + protected override Version HttpVersion => Net.HttpVersion.Version20; + protected override Task SendServerResponseAndEosAsync(WebSocketRequestData rd, ServerEosType eos, Func callback, CancellationToken ct) + => WebSocketHandshakeHelper.SendHttp2ServerResponseAndEosAsync(rd, eosInHeadersFrame: eos == ServerEosType.WithHeaders, callback, ct); + } + + public class AbortTest_HttpClient_Http2 : AbortTest_HttpClient_Loopback + { + public AbortTest_HttpClient_Http2(ITestOutputHelper output) : base(output) { } + protected override Version HttpVersion => Net.HttpVersion.Version20; + protected override Task SendServerResponseAndEosAsync(WebSocketRequestData rd, ServerEosType eos, Func callback, CancellationToken ct) + => WebSocketHandshakeHelper.SendHttp2ServerResponseAndEosAsync(rd, eosInHeadersFrame: eos == ServerEosType.WithHeaders, callback, ct); + } +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackHelper.cs b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackHelper.cs index 48d167b072f781..cee509ee068467 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackHelper.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackHelper.cs @@ -28,14 +28,7 @@ public static async Task> WebSocketHandshakeAsync(Loo if (headerName == "Sec-WebSocket-Key") { string headerValue = tokens[1].Trim(); - string responseSecurityAcceptValue = ComputeWebSocketHandshakeSecurityAcceptValue(headerValue); - serverResponse = - "HTTP/1.1 101 Switching Protocols\r\n" + - "Content-Length: 0\r\n" + - "Upgrade: websocket\r\n" + - "Connection: Upgrade\r\n" + - (extensions is null ? null : $"Sec-WebSocket-Extensions: {extensions}\r\n") + - "Sec-WebSocket-Accept: " + responseSecurityAcceptValue + "\r\n\r\n"; + serverResponse = GetServerResponseString(headerValue, extensions); } } } @@ -50,6 +43,18 @@ public static async Task> WebSocketHandshakeAsync(Loo return null; } + public static string GetServerResponseString(string secWebSocketKey, string? extensions = null) + { + var responseSecurityAcceptValue = ComputeWebSocketHandshakeSecurityAcceptValue(secWebSocketKey); + return + "HTTP/1.1 101 Switching Protocols\r\n" + + "Content-Length: 0\r\n" + + "Upgrade: websocket\r\n" + + "Connection: Upgrade\r\n" + + (extensions is null ? null : $"Sec-WebSocket-Extensions: {extensions}\r\n") + + "Sec-WebSocket-Accept: " + responseSecurityAcceptValue + "\r\n\r\n"; + } + private static string ComputeWebSocketHandshakeSecurityAcceptValue(string secWebSocketKey) { // GUID specified by RFC 6455. diff --git a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/Http2LoopbackStream.cs b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/Http2LoopbackStream.cs new file mode 100644 index 00000000000000..1b3b51840ec995 --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/Http2LoopbackStream.cs @@ -0,0 +1,100 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Net.Test.Common +{ + public class Http2LoopbackStream : Stream + { + private readonly Http2LoopbackConnection _connection; + private readonly int _streamId; + private bool _readEnded; + private ReadOnlyMemory _leftoverReadData; + + public override bool CanRead => true; + public override bool CanSeek => false; + public override bool CanWrite => true; + + public Http2LoopbackConnection Connection => _connection; + public int StreamId => _streamId; + + public Http2LoopbackStream(Http2LoopbackConnection connection, int streamId) + { + _connection = connection; + _streamId = streamId; + } + + public override async ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) + { + if (!_leftoverReadData.IsEmpty) + { + int read = Math.Min(buffer.Length, _leftoverReadData.Length); + _leftoverReadData.Span.Slice(0, read).CopyTo(buffer.Span); + _leftoverReadData = _leftoverReadData.Slice(read); + return read; + } + + if (_readEnded) + { + return 0; + } + + DataFrame dataFrame = (DataFrame)await _connection.ReadFrameAsync(cancellationToken); + Assert.Equal(_streamId, dataFrame.StreamId); + _leftoverReadData = dataFrame.Data; + _readEnded = dataFrame.EndStreamFlag; + + return await ReadAsync(buffer, cancellationToken); + } + + public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + ReadAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); + + public override async ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) + { + await _connection.SendResponseDataAsync(_streamId, buffer, endStream: false); + } + + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + WriteAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); + + protected override void Dispose(bool disposing) => DisposeAsync().GetAwaiter().GetResult(); + + public override async ValueTask DisposeAsync() + { + try + { + await _connection.SendResponseDataAsync(_streamId, Memory.Empty, endStream: true).ConfigureAwait(false); + + if (!_readEnded) + { + var rstFrame = new RstStreamFrame(FrameFlags.None, (int)ProtocolErrors.NO_ERROR, _streamId); + await _connection.WriteFrameAsync(rstFrame).ConfigureAwait(false); + } + } + catch (IOException) + { + // Ignore connection errors + } + catch (SocketException) + { + // Ignore connection errors + } + } + + public override void Flush() { } + public override Task FlushAsync(CancellationToken cancellationToken) => Task.CompletedTask; + + public override int Read(byte[] buffer, int offset, int count) => throw new NotImplementedException(); + public override long Seek(long offset, SeekOrigin origin) => throw new NotImplementedException(); + public override void SetLength(long value) => throw new NotImplementedException(); + public override void Write(byte[] buffer, int offset, int count) => throw new NotImplementedException(); + public override long Length => throw new NotImplementedException(); + public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + } +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.cs b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.cs new file mode 100644 index 00000000000000..b24e2e20d40dfe --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.cs @@ -0,0 +1,148 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Net.Http; +using System.Net.Test.Common; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Net.WebSockets.Client.Tests +{ + public static class LoopbackWebSocketServer + { + public static Task RunAsync( + Func clientWebSocketFunc, + Func serverWebSocketFunc, + Options options, + CancellationToken cancellationToken) + { + Assert.False(options.ManualServerHandshakeResponse, "Not supported in this overload"); + + return RunAsyncPrivate( + uri => RunClientAsync(uri, clientWebSocketFunc, options, cancellationToken), + (requestData, token) => RunServerAsync(requestData, serverWebSocketFunc, options, token), + options, + cancellationToken); + } + + public static Task RunAsync( + Func loopbackClientFunc, + Func loopbackServerFunc, + Options options, + CancellationToken cancellationToken) + { + Assert.False(options.DisposeClientWebSocket, "Not supported in this overload"); + Assert.False(options.DisposeServerWebSocket, "Not supported in this overload"); + Assert.False(options.DisposeHttpInvoker, "Not supported in this overload"); + Assert.Null(options.HttpInvoker); // Not supported in this overload + + return RunAsyncPrivate(loopbackClientFunc, loopbackServerFunc, options, cancellationToken); + } + + private static Task RunAsyncPrivate( + Func loopbackClientFunc, + Func loopbackServerFunc, + Options options, + CancellationToken cancellationToken) + { + bool sendDefaultServerHandshakeResponse = !options.ManualServerHandshakeResponse; + if (options.HttpVersion == HttpVersion.Version11) + { + return LoopbackServer.CreateClientAndServerAsync( + loopbackClientFunc, + async server => + { + await server.AcceptConnectionAsync(async connection => + { + var requestData = await WebSocketHandshakeHelper.ProcessHttp11RequestAsync(connection, sendDefaultServerHandshakeResponse, cancellationToken).ConfigureAwait(false); + await loopbackServerFunc(requestData, cancellationToken).ConfigureAwait(false); + }); + }, + new LoopbackServer.Options { WebSocketEndpoint = true, UseSsl = options.UseSsl }); + } + else if (options.HttpVersion == HttpVersion.Version20) + { + return Http2LoopbackServer.CreateClientAndServerAsync( + loopbackClientFunc, + async server => + { + var requestData = await WebSocketHandshakeHelper.ProcessHttp2RequestAsync(server, sendDefaultServerHandshakeResponse, cancellationToken).ConfigureAwait(false); + var http2Connection = requestData.Http2Connection!; + var http2StreamId = requestData.Http2StreamId.Value; + + await loopbackServerFunc(requestData, cancellationToken).ConfigureAwait(false); + + await http2Connection.DisposeAsync().ConfigureAwait(false); + }, + new Http2Options { WebSocketEndpoint = true, UseSsl = options.UseSsl }); + } + else + { + throw new ArgumentException(nameof(options.HttpVersion)); + } + } + + private static async Task RunServerAsync( + WebSocketRequestData requestData, + Func serverWebSocketFunc, + Options options, + CancellationToken cancellationToken) + { + var wsOptions = new WebSocketCreationOptions { IsServer = true }; + var serverWebSocket = WebSocket.CreateFromStream(requestData.WebSocketStream, wsOptions); + + await serverWebSocketFunc(serverWebSocket, cancellationToken).ConfigureAwait(false); + + if (options.DisposeServerWebSocket) + { + serverWebSocket.Dispose(); + } + } + + private static async Task RunClientAsync( + Uri uri, + Func clientWebSocketFunc, + Options options, + CancellationToken cancellationToken) + { + var clientWebSocket = await GetConnectedClientAsync(uri, options, cancellationToken).ConfigureAwait(false); + + await clientWebSocketFunc(clientWebSocket, cancellationToken).ConfigureAwait(false); + + if (options.DisposeClientWebSocket) + { + clientWebSocket.Dispose(); + } + + if (options.DisposeHttpInvoker) + { + options.HttpInvoker?.Dispose(); + } + } + + public static async Task GetConnectedClientAsync(Uri uri, Options options, CancellationToken cancellationToken) + { + var clientWebSocket = new ClientWebSocket(); + clientWebSocket.Options.HttpVersion = options.HttpVersion; + clientWebSocket.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionExact; + + if (options.UseSsl && options.HttpInvoker is null) + { + clientWebSocket.Options.RemoteCertificateValidationCallback = delegate { return true; }; + } + + await clientWebSocket.ConnectAsync(uri, options.HttpInvoker, cancellationToken).ConfigureAwait(false); + + return clientWebSocket; + } + + public record class Options(Version HttpVersion, bool UseSsl, HttpMessageInvoker? HttpInvoker) + { + public bool DisposeServerWebSocket { get; set; } = true; + public bool DisposeClientWebSocket { get; set; } + public bool DisposeHttpInvoker { get; set; } + public bool ManualServerHandshakeResponse { get; set; } + } + } +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketHandshakeHelper.cs b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketHandshakeHelper.cs new file mode 100644 index 00000000000000..f4d2f42f5edbb9 --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketHandshakeHelper.cs @@ -0,0 +1,134 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Net.Sockets; +using System.Net.Test.Common; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Net.WebSockets.Client.Tests +{ + public static class WebSocketHandshakeHelper + { + public static async Task ProcessHttp11RequestAsync(LoopbackServer.Connection connection, bool sendServerResponse = true, CancellationToken cancellationToken = default) + { + List headers = await connection.ReadRequestHeaderAsync().WaitAsync(cancellationToken).ConfigureAwait(false); + + var data = new WebSocketRequestData() + { + HttpVersion = HttpVersion.Version11, + Http11Connection = connection + }; + + foreach (string header in headers.Skip(1)) + { + string[] tokens = header.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries); + if (tokens.Length is 1 or 2) + { + data.Headers.Add( + tokens[0].Trim(), + tokens.Length == 2 ? tokens[1].Trim() : null); + } + } + + var isValidOpeningHandshake = data.Headers.TryGetValue("Sec-WebSocket-Key", out var secWebSocketKey); + Assert.True(isValidOpeningHandshake); + + if (sendServerResponse) + { + await SendHttp11ServerResponseAsync(connection, secWebSocketKey, cancellationToken).ConfigureAwait(false); + } + + data.WebSocketStream = connection.Stream; + return data; + } + + private static async Task SendHttp11ServerResponseAsync(LoopbackServer.Connection connection, string secWebSocketKey, CancellationToken cancellationToken) + { + var serverResponse = LoopbackHelper.GetServerResponseString(secWebSocketKey); + await connection.WriteStringAsync(serverResponse).WaitAsync(cancellationToken).ConfigureAwait(false); + } + + public static async Task ProcessHttp2RequestAsync(Http2LoopbackServer server, bool sendServerResponse = true, CancellationToken cancellationToken = default) + { + var connection = await server.EstablishConnectionAsync(new SettingsEntry { SettingId = SettingId.EnableConnect, Value = 1 }) + .WaitAsync(cancellationToken).ConfigureAwait(false); + + (int streamId, var httpRequestData) = await connection.ReadAndParseRequestHeaderAsync(readBody: false) + .WaitAsync(cancellationToken).ConfigureAwait(false); + + var data = new WebSocketRequestData + { + HttpVersion = HttpVersion.Version20, + Http2Connection = connection, + Http2StreamId = streamId + }; + + foreach (var header in httpRequestData.Headers) + { + Assert.NotNull(header.Name); + data.Headers.Add(header.Name, header.Value); + } + + var isValidOpeningHandshake = httpRequestData.Method == HttpMethod.Connect.ToString() && data.Headers.ContainsKey(":protocol"); + Assert.True(isValidOpeningHandshake); + + if (sendServerResponse) + { + await SendHttp2ServerResponseAsync(connection, streamId, cancellationToken: cancellationToken).ConfigureAwait(false); + } + + data.WebSocketStream = new Http2LoopbackStream(connection, streamId); + return data; + } + + private static async Task SendHttp2ServerResponseAsync(Http2LoopbackConnection connection, int streamId, bool endStream = false, CancellationToken cancellationToken = default) + { + // send status 200 OK to establish websocket + // we don't need to send anything additional as Sec-WebSocket-Key is not used for HTTP/2 + // note: endStream=true is abnormal and used for testing premature EOS scenarios only + await connection.SendResponseHeadersAsync(streamId, endStream: endStream).WaitAsync(cancellationToken).ConfigureAwait(false); + } + + public static async Task SendHttp11ServerResponseAndEosAsync(WebSocketRequestData requestData, Func? requestDataCallback, CancellationToken cancellationToken) + { + Assert.Equal(HttpVersion.Version11, requestData.HttpVersion); + + // sending default handshake response + await SendHttp11ServerResponseAsync(requestData.Http11Connection!, requestData.Headers["Sec-WebSocket-Key"], cancellationToken).ConfigureAwait(false); + + if (requestDataCallback is not null) + { + await requestDataCallback(requestData, cancellationToken).ConfigureAwait(false); + } + + // send server EOS (half-closing from server side) + requestData.Http11Connection!.Socket.Shutdown(SocketShutdown.Send); + } + + public static async Task SendHttp2ServerResponseAndEosAsync(WebSocketRequestData requestData, bool eosInHeadersFrame, Func? requestDataCallback, CancellationToken cancellationToken) + { + Assert.Equal(HttpVersion.Version20, requestData.HttpVersion); + + var connection = requestData.Http2Connection!; + var streamId = requestData.Http2StreamId!.Value; + + await SendHttp2ServerResponseAsync(connection, streamId, endStream: eosInHeadersFrame, cancellationToken).ConfigureAwait(false); + + if (requestDataCallback is not null) + { + await requestDataCallback(requestData, cancellationToken).ConfigureAwait(false); + } + + if (!eosInHeadersFrame) + { + // send server EOS (half-closing from server side) + await connection.SendResponseDataAsync(streamId, Array.Empty(), endStream: true).ConfigureAwait(false); + } + } + } +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketRequestData.cs b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketRequestData.cs new file mode 100644 index 00000000000000..799157a370f073 --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketRequestData.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Net.Test.Common; + +namespace System.Net.WebSockets.Client.Tests +{ + public class WebSocketRequestData + { + public Dictionary Headers { get; set; } = new Dictionary(); + public Stream? WebSocketStream { get; set; } + + public Version HttpVersion { get; set; } + public LoopbackServer.Connection? Http11Connection { get; set; } + public Http2LoopbackConnection? Http2Connection { get; set; } + public int? Http2StreamId { get; set; } + } +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj b/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj index 8f23e7925a4514..a4f20d03002e16 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj +++ b/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj @@ -55,6 +55,7 @@ + @@ -64,6 +65,10 @@ + + + + From 457dc4941ba960757fb9170cf1b47a93ed5271c9 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Wed, 14 Feb 2024 15:13:19 -0600 Subject: [PATCH 624/783] [release/8.0] Use the Wix version from arcade (#98453) --- eng/Versions.props | 1 - src/workloads/workloads.csproj | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 4ca58c3abe68b9..bca14318f51c8b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -244,7 +244,6 @@ $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda - 1.0.0-v3.14.0.5722 16.0.5-alpha.1.23566.1 16.0.5-alpha.1.23566.1 diff --git a/src/workloads/workloads.csproj b/src/workloads/workloads.csproj index 82c5c31badd71b..3db05c0a803404 100644 --- a/src/workloads/workloads.csproj +++ b/src/workloads/workloads.csproj @@ -30,7 +30,7 @@ - + From 62304a6d7085e32672ec988835eab41d89b82e25 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 14 Feb 2024 13:14:49 -0800 Subject: [PATCH 625/783] Update dependencies from https://github.com/dotnet/arcade build 20240213.2 (#98443) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24059.4 -> To Version 8.0.0-beta.24113.2 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 5 -- eng/Version.Details.xml | 72 +++++++++---------- eng/Versions.props | 30 ++++---- eng/common/post-build/publish-using-darc.ps1 | 4 +- .../templates/job/publish-build-assets.yml | 14 ++-- .../templates/post-build/post-build.yml | 16 ++--- .../templates/variables/pool-providers.yml | 12 ++-- global.json | 6 +- 8 files changed, 77 insertions(+), 82 deletions(-) diff --git a/NuGet.config b/NuGet.config index dffd3797508204..a681bc250bc9ed 100644 --- a/NuGet.config +++ b/NuGet.config @@ -10,11 +10,6 @@ - - - - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4e522812e23bc7..b54cff26d4cff0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -111,9 +111,9 @@ - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 @@ -121,69 +121,69 @@ 73f0850939d96131c28cf6ea6ee5aacb4da0083a - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 https://github.com/dotnet/runtime-assets @@ -334,9 +334,9 @@ https://github.com/dotnet/xharness a417169d3ba558fd6daa522f04e686574bbce520 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index bca14318f51c8b..00d310742cb1bb 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -87,21 +87,21 @@ 8.0.100 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 2.5.1-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 2.5.1-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 6.0.0-preview.1.102 diff --git a/eng/common/post-build/publish-using-darc.ps1 b/eng/common/post-build/publish-using-darc.ps1 index 1e779fec4dd1ea..5a3a32ea8d75b4 100644 --- a/eng/common/post-build/publish-using-darc.ps1 +++ b/eng/common/post-build/publish-using-darc.ps1 @@ -12,7 +12,7 @@ param( try { . $PSScriptRoot\post-build-utils.ps1 - $darc = Get-Darc + $darc = Get-Darc $optionalParams = [System.Collections.ArrayList]::new() @@ -46,7 +46,7 @@ try { } Write-Host 'done.' -} +} catch { Write-Host $_ Write-PipelineTelemetryError -Category 'PromoteBuild' -Message "There was an error while trying to publish build '$BuildId' to default channels." diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml index fa5446c093dd11..8ec0151def21a8 100644 --- a/eng/common/templates/job/publish-build-assets.yml +++ b/eng/common/templates/job/publish-build-assets.yml @@ -58,7 +58,7 @@ jobs: demands: Cmd # If it's not devdiv, it's dnceng ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: $(DncEngInternalBuildPool) + name: NetCore1ESPool-Publishing-Internal demands: ImageOverride -equals windows.vs2019.amd64 steps: @@ -71,7 +71,7 @@ jobs: checkDownloadedFiles: true condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} - + - task: NuGetAuthenticate@1 - task: PowerShell@2 @@ -86,7 +86,7 @@ jobs: /p:OfficialBuildId=$(Build.BuildNumber) condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} - + - task: powershell@2 displayName: Create ReleaseConfigs Artifact inputs: @@ -95,7 +95,7 @@ jobs: Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(BARBuildId) Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value "$(DefaultChannels)" Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsStableBuild) - + - task: PublishBuildArtifacts@1 displayName: Publish ReleaseConfigs Artifact inputs: @@ -121,7 +121,7 @@ jobs: - task: PublishBuildArtifacts@1 displayName: Publish SymbolPublishingExclusionsFile Artifact - condition: eq(variables['SymbolExclusionFile'], 'true') + condition: eq(variables['SymbolExclusionFile'], 'true') inputs: PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' PublishLocation: Container @@ -137,7 +137,7 @@ jobs: displayName: Publish Using Darc inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) + arguments: -BuildId $(BARBuildId) -PublishingInfraVersion 3 -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' -MaestroToken '$(MaestroApiAccessToken)' @@ -148,4 +148,4 @@ jobs: - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: - template: /eng/common/templates/steps/publish-logs.yml parameters: - JobLabel: 'Publish_Artifacts_Logs' + JobLabel: 'Publish_Artifacts_Logs' diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index 3f74abf7ce0f8a..aba44a25a33878 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -39,7 +39,7 @@ parameters: displayName: Enable NuGet validation type: boolean default: true - + - name: publishInstallersAndChecksums displayName: Publish installers and checksums type: boolean @@ -131,8 +131,8 @@ stages: displayName: Validate inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 - arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ - -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ + arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ + -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ - job: displayName: Signing Validation @@ -221,9 +221,9 @@ stages: displayName: Validate inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1 - arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ - -ExtractPath $(Agent.BuildDirectory)/Extract/ - -GHRepoName $(Build.Repository.Name) + arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ + -ExtractPath $(Agent.BuildDirectory)/Extract/ + -GHRepoName $(Build.Repository.Name) -GHCommit $(Build.SourceVersion) -SourcelinkCliVersion $(SourceLinkCLIVersion) continueOnError: true @@ -258,7 +258,7 @@ stages: demands: Cmd # If it's not devdiv, it's dnceng ${{ else }}: - name: $(DncEngInternalBuildPool) + name: NetCore1ESPool-Publishing-Internal demands: ImageOverride -equals windows.vs2019.amd64 steps: - template: setup-maestro-vars.yml @@ -272,7 +272,7 @@ stages: displayName: Publish Using Darc inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) + arguments: -BuildId $(BARBuildId) -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' -MaestroToken '$(MaestroApiAccessToken)' diff --git a/eng/common/templates/variables/pool-providers.yml b/eng/common/templates/variables/pool-providers.yml index 9cc5c550d3b36f..d236f9fdbb153b 100644 --- a/eng/common/templates/variables/pool-providers.yml +++ b/eng/common/templates/variables/pool-providers.yml @@ -1,15 +1,15 @@ -# Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool, +# Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool, # otherwise it should go into the "normal" pools. This separates out the queueing and billing of released branches. -# Motivation: +# Motivation: # Once a given branch of a repository's output has been officially "shipped" once, it is then considered to be COGS # (Cost of goods sold) and should be moved to a servicing pool provider. This allows both separation of queueing # (allowing release builds and main PR builds to not intefere with each other) and billing (required for COGS. -# Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services -# team needs to move resources around and create new and potentially differently-named pools. Using this template +# Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services +# team needs to move resources around and create new and potentially differently-named pools. Using this template # file from an Arcade-ified repo helps guard against both having to update one's release/* branches and renaming. -# How to use: +# How to use: # This yaml assumes your shipped product branches use the naming convention "release/..." (which many do). # If we find alternate naming conventions in broad usage it can be added to the condition below. # @@ -54,4 +54,4 @@ variables: False, 'NetCore1ESPool-Internal' ) - ] \ No newline at end of file + ] diff --git a/global.json b/global.json index 13f92203054630..c987cd4bc00e7d 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.101" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24059.4", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24059.4", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.24059.4", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24113.2", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24113.2", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.24113.2", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From 91b2946fbcfcd7f6cd6c3ce65a6146efb7081173 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 14 Feb 2024 14:56:30 -0800 Subject: [PATCH 626/783] [release/8.0-staging] Manually depad RSAES-PKCS1 on Apple OSes Co-authored-by: Jeremy Barton --- .../Interop.RSA.cs | 95 +++++++++++++-- .../Cryptography/RsaPaddingProcessor.cs | 104 ++++++++++++++++ .../RSA/EncryptDecrypt.cs | 115 ++++++++++++++++++ .../entrypoints.c | 1 + .../pal_rsa.c | 7 ++ .../pal_rsa.h | 8 ++ 6 files changed, 319 insertions(+), 11 deletions(-) diff --git a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.RSA.cs b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.RSA.cs index 4a3bd4454edee9..deab51eeb2bbda 100644 --- a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.RSA.cs +++ b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.RSA.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Buffers; using System.Diagnostics; using System.Runtime.InteropServices; using System.Security.Cryptography; @@ -69,8 +70,8 @@ private static partial int RsaDecryptOaep( out SafeCFDataHandle pEncryptedOut, out SafeCFErrorHandle pErrorOut); - [LibraryImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_RsaDecryptPkcs")] - private static partial int RsaDecryptPkcs( + [LibraryImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_RsaDecryptRaw")] + private static partial int RsaDecryptRaw( SafeSecKeyRefHandle publicKey, ReadOnlySpan pbData, int cbData, @@ -166,17 +167,40 @@ internal static byte[] RsaDecrypt( byte[] data, RSAEncryptionPadding padding) { + if (padding == RSAEncryptionPadding.Pkcs1) + { + byte[] padded = ExecuteTransform( + data, + (ReadOnlySpan source, out SafeCFDataHandle decrypted, out SafeCFErrorHandle error) => + RsaDecryptRaw(privateKey, source, source.Length, out decrypted, out error)); + + byte[] depad = CryptoPool.Rent(padded.Length); + OperationStatus status = RsaPaddingProcessor.DepadPkcs1Encryption(padded, depad, out int written); + byte[]? ret = null; + + if (status == OperationStatus.Done) + { + ret = depad.AsSpan(0, written).ToArray(); + } + + // Clear the whole thing, especially on failure. + CryptoPool.Return(depad); + CryptographicOperations.ZeroMemory(padded); + + if (ret is null) + { + throw new CryptographicException(SR.Cryptography_InvalidPadding); + } + + return ret; + } + + Debug.Assert(padding.Mode == RSAEncryptionPaddingMode.Oaep); + return ExecuteTransform( data, (ReadOnlySpan source, out SafeCFDataHandle decrypted, out SafeCFErrorHandle error) => { - if (padding == RSAEncryptionPadding.Pkcs1) - { - return RsaDecryptPkcs(privateKey, source, source.Length, out decrypted, out error); - } - - Debug.Assert(padding.Mode == RSAEncryptionPaddingMode.Oaep); - return RsaDecryptOaep( privateKey, source, @@ -195,14 +219,63 @@ internal static bool TryRsaDecrypt( out int bytesWritten) { Debug.Assert(padding.Mode == RSAEncryptionPaddingMode.Pkcs1 || padding.Mode == RSAEncryptionPaddingMode.Oaep); + + if (padding.Mode == RSAEncryptionPaddingMode.Pkcs1) + { + byte[] padded = CryptoPool.Rent(source.Length); + byte[] depad = CryptoPool.Rent(source.Length); + + bool processed = TryExecuteTransform( + source, + padded, + out int paddedLength, + (ReadOnlySpan innerSource, out SafeCFDataHandle outputHandle, out SafeCFErrorHandle errorHandle) => + RsaDecryptRaw(privateKey, innerSource, innerSource.Length, out outputHandle, out errorHandle)); + + Debug.Assert( + processed, + "TryExecuteTransform should always return true for a large enough buffer."); + + OperationStatus status = OperationStatus.InvalidData; + int depaddedLength = 0; + + if (processed) + { + status = RsaPaddingProcessor.DepadPkcs1Encryption( + new ReadOnlySpan(padded, 0, paddedLength), + depad, + out depaddedLength); + } + + CryptoPool.Return(padded); + + if (status == OperationStatus.Done) + { + if (depaddedLength <= destination.Length) + { + depad.AsSpan(0, depaddedLength).CopyTo(destination); + CryptoPool.Return(depad); + bytesWritten = depaddedLength; + return true; + } + + CryptoPool.Return(depad); + bytesWritten = 0; + return false; + } + + CryptoPool.Return(depad); + Debug.Assert(status == OperationStatus.InvalidData); + throw new CryptographicException(SR.Cryptography_InvalidPadding); + } + return TryExecuteTransform( source, destination, out bytesWritten, delegate (ReadOnlySpan innerSource, out SafeCFDataHandle outputHandle, out SafeCFErrorHandle errorHandle) { - return padding.Mode == RSAEncryptionPaddingMode.Pkcs1 ? - RsaDecryptPkcs(privateKey, innerSource, innerSource.Length, out outputHandle, out errorHandle) : + return RsaDecryptOaep(privateKey, innerSource, innerSource.Length, PalAlgorithmFromAlgorithmName(padding.OaepHashAlgorithm), out outputHandle, out errorHandle); }); } diff --git a/src/libraries/Common/src/System/Security/Cryptography/RsaPaddingProcessor.cs b/src/libraries/Common/src/System/Security/Cryptography/RsaPaddingProcessor.cs index 66256440b7e708..a9f190617fbf2f 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RsaPaddingProcessor.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RsaPaddingProcessor.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Buffers; using System.Buffers.Binary; using System.Collections.Concurrent; using System.Diagnostics; @@ -142,6 +143,109 @@ internal static void PadPkcs1Encryption( source.CopyTo(mInEM); } + internal static OperationStatus DepadPkcs1Encryption( + ReadOnlySpan source, + Span destination, + out int bytesWritten) + { + int primitive = DepadPkcs1Encryption(source); + int primitiveSign = SignStretch(primitive); + + // Primitive is a positive length, or ~length to indicate + // an error, so flip ~length to length if the high bit is set. + int len = Choose(primitiveSign, ~primitive, primitive); + int spaceRemain = destination.Length - len; + int spaceRemainSign = SignStretch(spaceRemain); + + // len = clampHigh(len, destination.Length); + len = Choose(spaceRemainSign, destination.Length, len); + + // ret = spaceRemain < 0 ? DestinationTooSmall : Done + int ret = Choose( + spaceRemainSign, + (int)OperationStatus.DestinationTooSmall, + (int)OperationStatus.Done); + + // ret = primitive < 0 ? InvalidData : ret; + ret = Choose(primitiveSign, (int)OperationStatus.InvalidData, ret); + + // Write some number of bytes, regardless of the final return. + source[^len..].CopyTo(destination); + + // bytesWritten = ret == Done ? len : 0; + bytesWritten = Choose(CheckZero(ret), len, 0); + return (OperationStatus)ret; + } + + private static int DepadPkcs1Encryption(ReadOnlySpan source) + { + Debug.Assert(source.Length > 11); + ReadOnlySpan afterPadding = source.Slice(10); + ReadOnlySpan noZeros = source.Slice(2, 8); + + // Find the first zero in noZeros, or -1 for no zeros. + int zeroPos = BlindFindFirstZero(noZeros); + + // If zeroPos is negative, valid is -1, otherwise 0. + int valid = SignStretch(zeroPos); + + // If there are no zeros in afterPadding then zeroPos is negative, + // so negating the sign stretch is 0, which makes hasPos 0. + // If there -was- a zero, sign stretching is 0, so negating it makes hasPos -1. + zeroPos = BlindFindFirstZero(afterPadding); + int hasLen = ~SignStretch(zeroPos); + valid &= hasLen; + + // Check that the first two bytes are { 00 02 } + valid &= CheckZero(source[0] | (source[1] ^ 0x02)); + + int lenIfGood = afterPadding.Length - zeroPos - 1; + // If there were no zeros, use the full after-min-padding segment. + int lenIfBad = ~Choose(hasLen, lenIfGood, source.Length - 11); + + Debug.Assert(lenIfBad < 0); + return Choose(valid, lenIfGood, lenIfBad); + } + + private static int BlindFindFirstZero(ReadOnlySpan source) + { + // Any vectorization of this routine needs to use non-early termination, + // and instructions that do not vary their completion time on the input. + + int pos = -1; + + for (int i = source.Length - 1; i >= 0; i--) + { + // pos = source[i] == 0 ? i : pos; + int local = CheckZero(source[i]); + pos = Choose(local, i, pos); + } + + return pos; + } + + private static int SignStretch(int value) + { + return value >> 31; + } + + private static int Choose(int selector, int yes, int no) + { + Debug.Assert((selector | (selector - 1)) == -1); + return (selector & yes) | (~selector & no); + } + + private static int CheckZero(int value) + { + // For zero, ~value and value-1 are both all bits set (negative). + // For positive values, ~value is negative and value-1 is positive. + // For negative values except MinValue, ~value is positive and value-1 is negative. + // For MinValue, ~value is positive and value-1 is also positive. + // All together, the only thing that has negative & negative is 0, so stretch the sign bit. + int mask = ~value & (value - 1); + return SignStretch(mask); + } + internal static void PadPkcs1Signature( HashAlgorithmName hashAlgorithmName, ReadOnlySpan source, diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs index 39f3ebc82ec678..5778b66d043491 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics; +using System.Numerics; using Test.Cryptography; using Microsoft.DotNet.XUnitExtensions; using Xunit; @@ -736,6 +738,119 @@ public void Decrypt_Pkcs1_ErrorsForInvalidPadding(byte[] data) } } + [Fact] + public void Decrypt_Pkcs1_BadPadding() + { + if ((PlatformDetection.IsWindows && !PlatformDetection.IsWindows10Version2004OrGreater)) + { + return; + } + + RSAParameters keyParams = TestData.RSA2048Params; + BigInteger e = new BigInteger(keyParams.Exponent, true, true); + BigInteger n = new BigInteger(keyParams.Modulus, true, true); + byte[] buf = new byte[keyParams.Modulus.Length]; + byte[] c = new byte[buf.Length]; + + buf[1] = 2; + buf.AsSpan(2).Fill(1); + + ref byte afterMinPadding = ref buf[10]; + ref byte lastByte = ref buf[^1]; + afterMinPadding = 0; + + using (RSA rsa = RSAFactory.Create(keyParams)) + { + RawEncrypt(buf, e, n, c); + // Assert.NoThrow, check that manual padding is coherent + Decrypt(rsa, c, RSAEncryptionPadding.Pkcs1); + + // All RSA encryption schemes start with 00, so pick any other number. + // + // If buf > modulus then encrypt should fail, so this + // is the largest legal-but-invalid value to test. + buf[0] = keyParams.Modulus[0]; + RawEncrypt(buf, e, n, c); + Assert.ThrowsAny(() => Decrypt(rsa, c, RSAEncryptionPadding.Pkcs1)); + + // Check again with a zero length payload + (afterMinPadding, lastByte) = (lastByte, afterMinPadding); + RawEncrypt(buf, e, n, c); + Assert.ThrowsAny(() => Decrypt(rsa, c, RSAEncryptionPadding.Pkcs1)); + + // Back to valid padding + buf[0] = 0; + (afterMinPadding, lastByte) = (lastByte, afterMinPadding); + RawEncrypt(buf, e, n, c); + Decrypt(rsa, c, RSAEncryptionPadding.Pkcs1); + + // This is (sort of) legal for PKCS1 signatures, but not decryption. + buf[1] = 1; + RawEncrypt(buf, e, n, c); + Assert.ThrowsAny(() => Decrypt(rsa, c, RSAEncryptionPadding.Pkcs1)); + + // No RSA PKCS1 padding scheme starts with 00 FF. + buf[1] = 255; + RawEncrypt(buf, e, n, c); + Assert.ThrowsAny(() => Decrypt(rsa, c, RSAEncryptionPadding.Pkcs1)); + + // Check again with a zero length payload + (afterMinPadding, lastByte) = (lastByte, afterMinPadding); + RawEncrypt(buf, e, n, c); + Assert.ThrowsAny(() => Decrypt(rsa, c, RSAEncryptionPadding.Pkcs1)); + + // Back to valid padding + buf[1] = 2; + (afterMinPadding, lastByte) = (lastByte, afterMinPadding); + RawEncrypt(buf, e, n, c); + Decrypt(rsa, c, RSAEncryptionPadding.Pkcs1); + + // Try a zero in every possible required padding position + for (int i = 2; i < 10; i++) + { + buf[i] = 0; + + RawEncrypt(buf, e, n, c); + Assert.ThrowsAny(() => Decrypt(rsa, c, RSAEncryptionPadding.Pkcs1)); + + // It used to be 1, now it's 2, still not zero. + buf[i] = 2; + } + + // Back to valid padding + RawEncrypt(buf, e, n, c); + Decrypt(rsa, c, RSAEncryptionPadding.Pkcs1); + + // Make it such that + // "there is no octet with hexadecimal value 0x00 to separate PS from M" + // (RFC 3447 sec 7.2.2, rule 3, third clause) + buf.AsSpan(10).Fill(3); + RawEncrypt(buf, e, n, c); + Assert.ThrowsAny(() => Decrypt(rsa, c, RSAEncryptionPadding.Pkcs1)); + + // Every possible problem, for good measure. + buf[0] = 2; + buf[1] = 0; + buf[4] = 0; + RawEncrypt(buf, e, n, c); + Assert.ThrowsAny(() => Decrypt(rsa, c, RSAEncryptionPadding.Pkcs1)); + } + + static void RawEncrypt(ReadOnlySpan source, BigInteger e, BigInteger n, Span destination) + { + BigInteger m = new BigInteger(source, true, true); + BigInteger c = BigInteger.ModPow(m, e, n); + int shift = destination.Length - c.GetByteCount(true); + destination.Slice(0, shift).Clear(); + bool wrote = c.TryWriteBytes(destination.Slice(shift), out int written, true, true); + + if (!wrote || written + shift != destination.Length) + { + throw new UnreachableException(); + } + } + } + public static IEnumerable OaepPaddingModes { get diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c b/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c index 9f91b6d2488fec..099fb343947110 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c @@ -70,6 +70,7 @@ static const Entry s_cryptoAppleNative[] = DllImportEntry(AppleCryptoNative_RsaGenerateKey) DllImportEntry(AppleCryptoNative_RsaDecryptOaep) DllImportEntry(AppleCryptoNative_RsaDecryptPkcs) + DllImportEntry(AppleCryptoNative_RsaDecryptRaw) DllImportEntry(AppleCryptoNative_RsaEncryptOaep) DllImportEntry(AppleCryptoNative_RsaEncryptPkcs) DllImportEntry(AppleCryptoNative_RsaSignaturePrimitive) diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_rsa.c b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_rsa.c index a9aece35fb0f59..1746828d5b0d7d 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_rsa.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_rsa.c @@ -134,6 +134,13 @@ int32_t AppleCryptoNative_RsaDecryptOaep(SecKeyRef privateKey, privateKey, pbData, cbData, pDecryptedOut, pErrorOut, mgfAlgorithm, SecKeyCreateDecryptedData); } +int32_t AppleCryptoNative_RsaDecryptRaw( + SecKeyRef privateKey, uint8_t* pbData, int32_t cbData, CFDataRef* pDecryptedOut, CFErrorRef* pErrorOut) +{ + return RsaPrimitive( + privateKey, pbData, cbData, pDecryptedOut, pErrorOut, kSecKeyAlgorithmRSAEncryptionRaw, SecKeyCreateDecryptedData); +} + int32_t AppleCryptoNative_RsaDecryptPkcs( SecKeyRef privateKey, uint8_t* pbData, int32_t cbData, CFDataRef* pDecryptedOut, CFErrorRef* pErrorOut) { diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_rsa.h b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_rsa.h index 253fdae78e4b3e..34a350f80f9bcf 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_rsa.h +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_rsa.h @@ -31,6 +31,14 @@ PALEXPORT int32_t AppleCryptoNative_RsaDecryptOaep(SecKeyRef privateKey, CFDataRef* pDecryptedOut, CFErrorRef* pErrorOut); +/* +Decrypt the contents of pbData using the provided privateKey without validating or removing padding. + +Follows pal_seckey return conventions. +*/ +PALEXPORT int32_t AppleCryptoNative_RsaDecryptRaw( + SecKeyRef privateKey, uint8_t* pbData, int32_t cbData, CFDataRef* pDecryptedOut, CFErrorRef* pErrorOut); + /* Decrypt the contents of pbData using the provided privateKey under PKCS#1 padding. From fe2ea4ef2b70e1399de2036d443fcb26695aa549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 20 Feb 2024 10:20:44 +0100 Subject: [PATCH 627/783] Fix NativeAOT publish failure on fi_FI culture (#98552) (#98601) This culture uses `U+2212 : MINUS SIGN` instead of `-` for negative numbers which trips up msbuild when comparing the property. Instead of using an intermediate property just inline the usage and use `Contains()` for better readability. Fixes https://github.com/dotnet/runtime/issues/98550 (cherry picked from commit c768315c5698391f45a6a47d56fec4ba3df59fb8) --- .../Microsoft.DotNet.ILCompiler.SingleEntry.targets | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets index 178d8aaa93aa93..299840345a7918 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets @@ -5,8 +5,7 @@ <_hostOS>$(NETCoreSdkPortableRuntimeIdentifier.SubString(0, $(NETCoreSdkPortableRuntimeIdentifier.LastIndexOf('-')))) <_targetOS>$(RuntimeIdentifier.SubString(0, $(RuntimeIdentifier.LastIndexOf('-')))) - <_indexOfPeriod>$(_targetOS.IndexOf('.')) - <_targetOS Condition="'$(_indexOfPeriod)' > -1">$(_targetOS.SubString(0, $(_indexOfPeriod))) + <_targetOS Condition="$(_targetOS.Contains('.'))">$(_targetOS.SubString(0, $(_targetOS.IndexOf('.')))) <_targetOS Condition="$(_targetOS.StartsWith('win'))">win From 2ebbc777a1142b948a06c6d77a0400a71336124c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 19:18:25 -0600 Subject: [PATCH 628/783] [release/8.0-staging] Update dependencies from dotnet/runtime-assets (#98560) * Update dependencies from https://github.com/dotnet/runtime-assets build 20240215.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24108.4 -> To Version 8.0.0-beta.24115.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240215.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24108.4 -> To Version 8.0.0-beta.24115.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240215.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24108.4 -> To Version 8.0.0-beta.24115.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240215.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24108.4 -> To Version 8.0.0-beta.24115.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240215.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24108.4 -> To Version 8.0.0-beta.24115.2 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240215.2 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24108.4 -> To Version 8.0.0-beta.24115.2 --------- Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 6 +---- eng/Version.Details.xml | 56 ++++++++++++++++++++--------------------- eng/Versions.props | 28 ++++++++++----------- 3 files changed, 43 insertions(+), 47 deletions(-) diff --git a/NuGet.config b/NuGet.config index 2bb901348e5cec..80d8b321e9617a 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,12 +9,8 @@ - - - - - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4e522812e23bc7..06c3925d623bfd 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -185,57 +185,57 @@ https://github.com/dotnet/arcade 61ae141d2bf3534619265c8f691fd55dc3e75147 - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed https://github.com/dotnet/llvm-project @@ -358,9 +358,9 @@ https://github.com/dotnet/hotreload-utils bc857c64c5c5f1fc73048261e8f471c3310224d2 - + https://github.com/dotnet/runtime-assets - ca6c46012f68934198ce0d303196c3ae179230f5 + 0827f89642a6443c96a87990e3b910f6aa4cc4ed https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index 4ca58c3abe68b9..10419d98ecefd6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -143,20 +143,20 @@ 4.5.0 8.0.0-rc.1.23406.6 - 8.0.0-beta.24108.4 - 8.0.0-beta.24108.4 - 8.0.0-beta.24108.4 - 8.0.0-beta.24108.4 - 8.0.0-beta.24108.4 - 8.0.0-beta.24108.4 - 8.0.0-beta.24108.4 - 8.0.0-beta.24108.4 - 8.0.0-beta.24108.4 - 8.0.0-beta.24108.4 - 8.0.0-beta.24108.4 - 8.0.0-beta.24108.4 - 8.0.0-beta.24108.4 - 8.0.0-beta.24108.4 + 8.0.0-beta.24115.2 + 8.0.0-beta.24115.2 + 8.0.0-beta.24115.2 + 8.0.0-beta.24115.2 + 8.0.0-beta.24115.2 + 8.0.0-beta.24115.2 + 8.0.0-beta.24115.2 + 8.0.0-beta.24115.2 + 8.0.0-beta.24115.2 + 8.0.0-beta.24115.2 + 8.0.0-beta.24115.2 + 8.0.0-beta.24115.2 + 8.0.0-beta.24115.2 + 8.0.0-beta.24115.2 1.0.0-prerelease.23566.3 1.0.0-prerelease.23566.3 From c3a4e1383aea019a73d75cc6866bf47af116cba9 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 19:20:16 -0600 Subject: [PATCH 629/783] Update dependencies from https://github.com/dotnet/arcade build 20240213.2 (#98445) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24059.4 -> To Version 8.0.0-beta.24113.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 72 +++++++++---------- eng/Versions.props | 30 ++++---- eng/common/post-build/publish-using-darc.ps1 | 4 +- .../templates/job/publish-build-assets.yml | 14 ++-- .../templates/post-build/post-build.yml | 16 ++--- .../templates/variables/pool-providers.yml | 12 ++-- global.json | 6 +- 7 files changed, 77 insertions(+), 77 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 06c3925d623bfd..4f40ec3d7005e0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -111,9 +111,9 @@ - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 @@ -121,69 +121,69 @@ 73f0850939d96131c28cf6ea6ee5aacb4da0083a - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 https://github.com/dotnet/runtime-assets @@ -334,9 +334,9 @@ https://github.com/dotnet/xharness a417169d3ba558fd6daa522f04e686574bbce520 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + da98edc4c3ea539f109ea320672136ceb32591a7 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index 10419d98ecefd6..47287d03ea8874 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -87,21 +87,21 @@ 8.0.100 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 2.5.1-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 - 8.0.0-beta.24059.4 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 2.5.1-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 + 8.0.0-beta.24113.2 6.0.0-preview.1.102 diff --git a/eng/common/post-build/publish-using-darc.ps1 b/eng/common/post-build/publish-using-darc.ps1 index 1e779fec4dd1ea..5a3a32ea8d75b4 100644 --- a/eng/common/post-build/publish-using-darc.ps1 +++ b/eng/common/post-build/publish-using-darc.ps1 @@ -12,7 +12,7 @@ param( try { . $PSScriptRoot\post-build-utils.ps1 - $darc = Get-Darc + $darc = Get-Darc $optionalParams = [System.Collections.ArrayList]::new() @@ -46,7 +46,7 @@ try { } Write-Host 'done.' -} +} catch { Write-Host $_ Write-PipelineTelemetryError -Category 'PromoteBuild' -Message "There was an error while trying to publish build '$BuildId' to default channels." diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml index fa5446c093dd11..8ec0151def21a8 100644 --- a/eng/common/templates/job/publish-build-assets.yml +++ b/eng/common/templates/job/publish-build-assets.yml @@ -58,7 +58,7 @@ jobs: demands: Cmd # If it's not devdiv, it's dnceng ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: $(DncEngInternalBuildPool) + name: NetCore1ESPool-Publishing-Internal demands: ImageOverride -equals windows.vs2019.amd64 steps: @@ -71,7 +71,7 @@ jobs: checkDownloadedFiles: true condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} - + - task: NuGetAuthenticate@1 - task: PowerShell@2 @@ -86,7 +86,7 @@ jobs: /p:OfficialBuildId=$(Build.BuildNumber) condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} - + - task: powershell@2 displayName: Create ReleaseConfigs Artifact inputs: @@ -95,7 +95,7 @@ jobs: Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(BARBuildId) Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value "$(DefaultChannels)" Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsStableBuild) - + - task: PublishBuildArtifacts@1 displayName: Publish ReleaseConfigs Artifact inputs: @@ -121,7 +121,7 @@ jobs: - task: PublishBuildArtifacts@1 displayName: Publish SymbolPublishingExclusionsFile Artifact - condition: eq(variables['SymbolExclusionFile'], 'true') + condition: eq(variables['SymbolExclusionFile'], 'true') inputs: PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' PublishLocation: Container @@ -137,7 +137,7 @@ jobs: displayName: Publish Using Darc inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) + arguments: -BuildId $(BARBuildId) -PublishingInfraVersion 3 -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' -MaestroToken '$(MaestroApiAccessToken)' @@ -148,4 +148,4 @@ jobs: - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: - template: /eng/common/templates/steps/publish-logs.yml parameters: - JobLabel: 'Publish_Artifacts_Logs' + JobLabel: 'Publish_Artifacts_Logs' diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index 3f74abf7ce0f8a..aba44a25a33878 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -39,7 +39,7 @@ parameters: displayName: Enable NuGet validation type: boolean default: true - + - name: publishInstallersAndChecksums displayName: Publish installers and checksums type: boolean @@ -131,8 +131,8 @@ stages: displayName: Validate inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 - arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ - -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ + arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ + -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ - job: displayName: Signing Validation @@ -221,9 +221,9 @@ stages: displayName: Validate inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1 - arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ - -ExtractPath $(Agent.BuildDirectory)/Extract/ - -GHRepoName $(Build.Repository.Name) + arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ + -ExtractPath $(Agent.BuildDirectory)/Extract/ + -GHRepoName $(Build.Repository.Name) -GHCommit $(Build.SourceVersion) -SourcelinkCliVersion $(SourceLinkCLIVersion) continueOnError: true @@ -258,7 +258,7 @@ stages: demands: Cmd # If it's not devdiv, it's dnceng ${{ else }}: - name: $(DncEngInternalBuildPool) + name: NetCore1ESPool-Publishing-Internal demands: ImageOverride -equals windows.vs2019.amd64 steps: - template: setup-maestro-vars.yml @@ -272,7 +272,7 @@ stages: displayName: Publish Using Darc inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) + arguments: -BuildId $(BARBuildId) -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' -MaestroToken '$(MaestroApiAccessToken)' diff --git a/eng/common/templates/variables/pool-providers.yml b/eng/common/templates/variables/pool-providers.yml index 9cc5c550d3b36f..d236f9fdbb153b 100644 --- a/eng/common/templates/variables/pool-providers.yml +++ b/eng/common/templates/variables/pool-providers.yml @@ -1,15 +1,15 @@ -# Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool, +# Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool, # otherwise it should go into the "normal" pools. This separates out the queueing and billing of released branches. -# Motivation: +# Motivation: # Once a given branch of a repository's output has been officially "shipped" once, it is then considered to be COGS # (Cost of goods sold) and should be moved to a servicing pool provider. This allows both separation of queueing # (allowing release builds and main PR builds to not intefere with each other) and billing (required for COGS. -# Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services -# team needs to move resources around and create new and potentially differently-named pools. Using this template +# Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services +# team needs to move resources around and create new and potentially differently-named pools. Using this template # file from an Arcade-ified repo helps guard against both having to update one's release/* branches and renaming. -# How to use: +# How to use: # This yaml assumes your shipped product branches use the naming convention "release/..." (which many do). # If we find alternate naming conventions in broad usage it can be added to the condition below. # @@ -54,4 +54,4 @@ variables: False, 'NetCore1ESPool-Internal' ) - ] \ No newline at end of file + ] diff --git a/global.json b/global.json index 13f92203054630..c987cd4bc00e7d 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.101" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24059.4", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24059.4", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.24059.4", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24113.2", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24113.2", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.24113.2", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From b41d2b68fe5d4c21d8bc1a340343a8015a060175 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 19:25:29 -0600 Subject: [PATCH 630/783] Update dependencies from https://github.com/dotnet/xharness build 20240212.2 (#98444) Microsoft.DotNet.XHarness.CLI , Microsoft.DotNet.XHarness.TestRunners.Common , Microsoft.DotNet.XHarness.TestRunners.Xunit From Version 8.0.0-prerelease.24060.1 -> To Version 8.0.0-prerelease.24112.2 Co-authored-by: dotnet-maestro[bot] --- .config/dotnet-tools.json | 2 +- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 72af997c0c2543..6ff1559a00ab98 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "8.0.0-prerelease.24060.1", + "version": "8.0.0-prerelease.24112.2", "commands": [ "xharness" ] diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4f40ec3d7005e0..2427ba2b42b1e3 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -322,17 +322,17 @@ https://github.com/dotnet/runtime edbd5c769a19798b6955050baccf99e6797d3208 - + https://github.com/dotnet/xharness - a417169d3ba558fd6daa522f04e686574bbce520 + c055cc57f21796e79ace4bca2b070a8777f2446a - + https://github.com/dotnet/xharness - a417169d3ba558fd6daa522f04e686574bbce520 + c055cc57f21796e79ace4bca2b070a8777f2446a - + https://github.com/dotnet/xharness - a417169d3ba558fd6daa522f04e686574bbce520 + c055cc57f21796e79ace4bca2b070a8777f2446a https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index 47287d03ea8874..b760f86c84c233 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -183,9 +183,9 @@ 1.1.0 17.4.0-preview-20220707-01 - 8.0.0-prerelease.24060.1 - 8.0.0-prerelease.24060.1 - 8.0.0-prerelease.24060.1 + 8.0.0-prerelease.24112.2 + 8.0.0-prerelease.24112.2 + 8.0.0-prerelease.24112.2 8.0.0-alpha.0.24072.2 2.4.2 1.0.0 From a3de6b7fbb8cc20637318187ca5b293692cfa76d Mon Sep 17 00:00:00 2001 From: Juan Hoyos <19413848+hoyosjs@users.noreply.github.com> Date: Tue, 27 Feb 2024 12:03:50 -0800 Subject: [PATCH 631/783] Update diasymreader to 17.8.7-beta1.24113.1 (#98539) --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 0c986b60330b4f..fd241deaae3b37 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -165,7 +165,7 @@ 1.0.0-prerelease.23566.3 1.0.0-prerelease.23566.3 - 16.11.29-beta1.23404.4 + 17.8.7-beta1.24113.1 2.0.0-beta4.23307.1 3.0.3 2.1.0 From 276022237eb57cd632bb4a205520a90308799d4f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 17:39:19 +0100 Subject: [PATCH 632/783] [mono] Set /DEBUGTYPE:CV,FIXUP on binaries (#99356) This fixes an issue with running APIScan on mono-aot-cross.exe --- src/mono/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index 05766210ea6be5..8320e4c4cf145b 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -284,6 +284,7 @@ elseif(CLR_CMAKE_HOST_OS STREQUAL "windows") add_compile_options(/GL) # whole program optimization add_link_options(/LTCG) # link-time code generation add_link_options(/DEBUG) # enable debugging information + add_link_options(/DEBUGTYPE:CV,FIXUP) # enable fixup debug information add_link_options(/OPT:REF) # optimize: remove unreferenced functions & data add_link_options(/OPT:ICF) # optimize: enable COMDAT folding # the combination of /Zi compiler flag and /DEBUG /OPT:REF /OPT:ICF From 13d578bab9c53546a87920e55255f09e2d75274f Mon Sep 17 00:00:00 2001 From: vseanreesermsft <78103370+vseanreesermsft@users.noreply.github.com> Date: Wed, 6 Mar 2024 11:06:12 -0800 Subject: [PATCH 633/783] Update branding to 8.0.4 (#99324) --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 00d310742cb1bb..5b91c0c7996136 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,11 +1,11 @@ - 8.0.3 + 8.0.4 8 0 - 3 + 4 8.0.100 7.0.$([MSBuild]::Add($(PatchVersion),14)) 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) From e398dd64ac7c2a40eefb476f9e76cd7c0e9c5ddb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 11:29:40 -0800 Subject: [PATCH 634/783] Restore erroneously removed encoding of the argument count in a generic method instantiation (#98825) Users of the multicore jit feature would encounter silent encoding failures while recording profiles due to a defect in our encoding for generic method instances that would make them impossible to decode later. This PR fixes the encoding so that newly-recorded profiles will not be corrupt. Co-authored-by: Katelyn Gadd --- src/coreclr/vm/zapsig.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/vm/zapsig.cpp b/src/coreclr/vm/zapsig.cpp index bbbab9a51c84d4..dfd447f94eaaf6 100644 --- a/src/coreclr/vm/zapsig.cpp +++ b/src/coreclr/vm/zapsig.cpp @@ -1350,6 +1350,9 @@ BOOL ZapSig::EncodeMethod( else { Instantiation inst = pMethod->GetMethodInstantiation(); + + pSigBuilder->AppendData(inst.GetNumArgs()); + for (DWORD i = 0; i < inst.GetNumArgs(); i++) { TypeHandle t = inst[i]; From d66d7908f99087b194f6540317c43faff725b4f8 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 11:34:55 -0800 Subject: [PATCH 635/783] [release/8.0-staging] Update dependencies from dotnet/emsdk (#98458) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/dotnet/emsdk build 20240214.4 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.3-servicing.24108.3 -> To Version 8.0.3-servicing.24114.4 * Update dependencies from https://github.com/dotnet/emsdk build 20240214.6 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.3-servicing.24108.3 -> To Version 8.0.3-servicing.24114.6 * Update dependencies from https://github.com/dotnet/emsdk build 20240215.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.3-servicing.24108.3 -> To Version 8.0.3-servicing.24115.2 * Update dependencies from https://github.com/dotnet/emsdk build 20240227.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.3-servicing.24108.3 -> To Version 8.0.3-servicing.24127.1 * Update dependencies from https://github.com/dotnet/emsdk build 20240306.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.3-servicing.24108.3 -> To Version 8.0.4-servicing.24156.2 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Larry Ewing Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- NuGet.config | 3 +-- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/NuGet.config b/NuGet.config index 80d8b321e9617a..97380116615baa 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,8 +9,7 @@ - - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2427ba2b42b1e3..44ca79b371d459 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,13 +90,13 @@ 45dd3a73dd5b64b010c4251303b3664bb30df029 - + https://github.com/dotnet/emsdk - 9a29abdd764a4de0f253ed368871877a47725247 + 1639670c6547454278f51afc5c74e20f8acc7abd - + https://github.com/dotnet/emsdk - 9a29abdd764a4de0f253ed368871877a47725247 + 1639670c6547454278f51afc5c74e20f8acc7abd diff --git a/eng/Versions.props b/eng/Versions.props index fd241deaae3b37..b158b3a828dfab 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.3 + 8.0.4 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda From 4a1e5f4db0f5c338e2090144ea2cc439bcd865df Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 15:02:52 -0500 Subject: [PATCH 636/783] [release/8.0-staging] Fix FormatQuantiles formatting in MetricsEventSource (#99045) * Fix FormatQuantiles formatting in MetricsEventSource These doubles need to be formatted with the invariant culture to meet consumer expectations around parsing them. * Enable DiagnosticSource for servicing --------- Co-authored-by: Stephen Toub Co-authored-by: Eric StJohn --- ...System.Diagnostics.DiagnosticSource.csproj | 2 + .../Diagnostics/Metrics/MetricsEventSource.cs | 6 +- .../tests/MetricEventSourceTests.cs | 119 ++++++++++-------- 3 files changed, 73 insertions(+), 54 deletions(-) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj index 49b7834a9de36c..378251006567fc 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -6,6 +6,8 @@ $(NoWarn);SA1205 false true + true + 1 Provides Classes that allow you to decouple code logging rich (unserializable) diagnostics/telemetry (e.g. framework) from code that consumes it (e.g. tools) Commonly Used Types: diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs index 41979421991f48..4b5da60a441565 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs @@ -737,7 +737,11 @@ private static string FormatQuantiles(QuantileValue[] quantiles) StringBuilder sb = new StringBuilder(); for (int i = 0; i < quantiles.Length; i++) { - sb.Append(quantiles[i].Quantile).Append('=').Append(quantiles[i].Value); +#if NETCOREAPP + sb.Append(CultureInfo.InvariantCulture, $"{quantiles[i].Quantile}={quantiles[i].Value}"); +#else + sb.AppendFormat(CultureInfo.InvariantCulture, "{0}={1}", quantiles[i].Quantile, quantiles[i].Value); +#endif if (i != quantiles.Length - 1) { sb.Append(';'); diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs index 1902c2a6c4bdc3..a6d2c4a6f26640 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics.Tracing; using System.Globalization; @@ -9,7 +8,7 @@ using System.Runtime.CompilerServices; using System.Text; using System.Threading; -using System.Threading.Tasks; +using Microsoft.DotNet.RemoteExecutor; using Xunit; using Xunit.Abstractions; @@ -658,45 +657,59 @@ public void MultipleListeners_PublishingInstruments() AssertInitialEnumerationCompleteEventPresent(events2); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + public static bool IsNotBrowserAndRemoteExecuteSupported => PlatformDetection.IsNotBrowser && RemoteExecutor.IsSupported; + + [ConditionalFact(typeof(MetricEventSourceTests), nameof(IsNotBrowserAndRemoteExecuteSupported))] [OuterLoop("Slow and has lots of console spew")] public void EventSourcePublishesTimeSeriesWithEmptyMetadata() { - using Meter meter = new Meter("TestMeter1", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } }, new object()); - Counter c = meter.CreateCounter("counter1"); - int counterState = 3; - ObservableCounter oc = meter.CreateObservableCounter("observableCounter1", () => { counterState += 7; return counterState; }); - int gaugeState = 0; - ObservableGauge og = meter.CreateObservableGauge("observableGauge1", () => { gaugeState += 9; return gaugeState; }); - Histogram h = meter.CreateHistogram("histogram1"); - UpDownCounter udc = meter.CreateUpDownCounter("upDownCounter1"); - int upDownCounterState = 0; - ObservableUpDownCounter oudc = meter.CreateObservableUpDownCounter("observableUpDownCounter1", () => { upDownCounterState -= 11; return upDownCounterState; }); - - EventWrittenEventArgs[] events; - using (MetricsEventListener listener = new MetricsEventListener(_output, MetricsEventListener.TimeSeriesValues, IntervalSecs, "TestMeter1")) + RemoteExecutor.Invoke(static () => { - listener.WaitForCollectionStop(s_waitForEventTimeout, 1); - c.Add(5); - h.Record(19); - udc.Add(-33); - listener.WaitForCollectionStop(s_waitForEventTimeout, 2); - c.Add(12); - h.Record(26); - udc.Add(-40); - listener.WaitForCollectionStop(s_waitForEventTimeout, 3); - events = listener.Events.ToArray(); - } + CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("fi-FI"); - AssertBeginInstrumentReportingEventsPresent(events, c, oc, og, h, udc, oudc); - AssertInitialEnumerationCompleteEventPresent(events); - AssertCounterEventsPresent(events, meter.Name, c.Name, "", "", ("5", "5"), ("12", "17")); - AssertCounterEventsPresent(events, meter.Name, oc.Name, "", "", ("", "10"), ("7", "17")); - AssertGaugeEventsPresent(events, meter.Name, og.Name, "", "", "9", "18"); - AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", ("0.5=19;0.95=19;0.99=19", "1", "19"), ("0.5=26;0.95=26;0.99=26", "1", "26")); - AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "", "", ("-33", "-33"), ("-40", "-73")); - AssertUpDownCounterEventsPresent(events, meter.Name, oudc.Name, "", "", ("", "-11"), ("-11", "-22")); - AssertCollectStartStopEventsPresent(events, IntervalSecs, 3); + using Meter meter = new Meter("TestMeter1", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } }, new object()); + Counter c = meter.CreateCounter("counter1"); + int counterState = 3; + ObservableCounter oc = meter.CreateObservableCounter("observableCounter1", () => { counterState += 7; return counterState; }); + int gaugeState = 0; + ObservableGauge og = meter.CreateObservableGauge("observableGauge1", () => { gaugeState += 9; return gaugeState; }); + Histogram h = meter.CreateHistogram("histogram1"); + UpDownCounter udc = meter.CreateUpDownCounter("upDownCounter1"); + int upDownCounterState = 0; + ObservableUpDownCounter oudc = meter.CreateObservableUpDownCounter("observableUpDownCounter1", () => { upDownCounterState -= 11; return upDownCounterState; }); + + EventWrittenEventArgs[] events; + using (MetricsEventListener listener = new MetricsEventListener(NullTestOutputHelper.Instance, MetricsEventListener.TimeSeriesValues, IntervalSecs, "TestMeter1")) + { + listener.WaitForCollectionStop(s_waitForEventTimeout, 1); + c.Add(5); + h.Record(19); + udc.Add(-33); + listener.WaitForCollectionStop(s_waitForEventTimeout, 2); + c.Add(12); + h.Record(26); + udc.Add(-40); + listener.WaitForCollectionStop(s_waitForEventTimeout, 3); + events = listener.Events.ToArray(); + } + + AssertBeginInstrumentReportingEventsPresent(events, c, oc, og, h, udc, oudc); + AssertInitialEnumerationCompleteEventPresent(events); + AssertCounterEventsPresent(events, meter.Name, c.Name, "", "", ("5", "5"), ("12", "17")); + AssertCounterEventsPresent(events, meter.Name, oc.Name, "", "", ("", "10"), ("7", "17")); + AssertGaugeEventsPresent(events, meter.Name, og.Name, "", "", "9", "18"); + AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", ("0.5=19;0.95=19;0.99=19", "1", "19"), ("0.5=26;0.95=26;0.99=26", "1", "26")); + AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "", "", ("-33", "-33"), ("-40", "-73")); + AssertUpDownCounterEventsPresent(events, meter.Name, oudc.Name, "", "", ("", "-11"), ("-11", "-22")); + AssertCollectStartStopEventsPresent(events, IntervalSecs, 3); + }).Dispose(); + } + + private sealed class NullTestOutputHelper : ITestOutputHelper + { + public static NullTestOutputHelper Instance { get; } = new(); + public void WriteLine(string message) { } + public void WriteLine(string format, params object[] args) { } } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] @@ -1470,7 +1483,7 @@ private static string FormatTags(IEnumerable>? tag return sb.ToString(); } - private void AssertBeginInstrumentReportingEventsPresent(EventWrittenEventArgs[] events, params Instrument[] expectedInstruments) + private static void AssertBeginInstrumentReportingEventsPresent(EventWrittenEventArgs[] events, params Instrument[] expectedInstruments) { var beginReportEvents = events.Where(e => e.EventName == "BeginInstrumentReporting").Select(e => new @@ -1502,7 +1515,7 @@ private void AssertBeginInstrumentReportingEventsPresent(EventWrittenEventArgs[] Assert.Equal(expectedInstruments.Length, beginReportEvents.Length); } - private void AssertEndInstrumentReportingEventsPresent(EventWrittenEventArgs[] events, params Instrument[] expectedInstruments) + private static void AssertEndInstrumentReportingEventsPresent(EventWrittenEventArgs[] events, params Instrument[] expectedInstruments) { var beginReportEvents = events.Where(e => e.EventName == "EndInstrumentReporting").Select(e => new @@ -1534,27 +1547,27 @@ private void AssertEndInstrumentReportingEventsPresent(EventWrittenEventArgs[] e Assert.Equal(expectedInstruments.Length, beginReportEvents.Length); } - private void AssertInitialEnumerationCompleteEventPresent(EventWrittenEventArgs[] events, int eventsCount = 1) + private static void AssertInitialEnumerationCompleteEventPresent(EventWrittenEventArgs[] events, int eventsCount = 1) { Assert.Equal(eventsCount, events.Where(e => e.EventName == "InitialInstrumentEnumerationComplete").Count()); } - private void AssertTimeSeriesLimitPresent(EventWrittenEventArgs[] events) + private static void AssertTimeSeriesLimitPresent(EventWrittenEventArgs[] events) { Assert.Equal(1, events.Where(e => e.EventName == "TimeSeriesLimitReached").Count()); } - private void AssertTimeSeriesLimitNotPresent(EventWrittenEventArgs[] events) + private static void AssertTimeSeriesLimitNotPresent(EventWrittenEventArgs[] events) { Assert.Equal(0, events.Where(e => e.EventName == "TimeSeriesLimitReached").Count()); } - private void AssertHistogramLimitPresent(EventWrittenEventArgs[] events) + private static void AssertHistogramLimitPresent(EventWrittenEventArgs[] events) { Assert.Equal(1, events.Where(e => e.EventName == "HistogramLimitReached").Count()); } - private void AssertInstrumentPublishingEventsPresent(EventWrittenEventArgs[] events, params Instrument[] expectedInstruments) + private static void AssertInstrumentPublishingEventsPresent(EventWrittenEventArgs[] events, params Instrument[] expectedInstruments) { var publishEvents = events.Where(e => e.EventName == "InstrumentPublished").Select(e => new @@ -1586,19 +1599,19 @@ private void AssertInstrumentPublishingEventsPresent(EventWrittenEventArgs[] eve Assert.Equal(expectedInstruments.Length, publishEvents.Length); } - private void AssertCounterEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags, + private static void AssertCounterEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags, string expectedUnit, params (string, string)[] expected) { AssertGenericCounterEventsPresent("CounterRateValuePublished", events, meterName, instrumentName, tags, expectedUnit, expected); } - private void AssertUpDownCounterEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags, + private static void AssertUpDownCounterEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags, string expectedUnit, params (string, string)[] expected) { AssertGenericCounterEventsPresent("UpDownCounterRateValuePublished", events, meterName, instrumentName, tags, expectedUnit, expected); } - private void AssertGenericCounterEventsPresent(string eventName, EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags, + private static void AssertGenericCounterEventsPresent(string eventName, EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags, string expectedUnit, params (string, string)[] expected) { var counterEvents = events.Where(e => e.EventName == eventName).Select(e => @@ -1622,7 +1635,7 @@ private void AssertGenericCounterEventsPresent(string eventName, EventWrittenEve } } - private void AssertCounterEventsNotPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags) + private static void AssertCounterEventsNotPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags) { var counterEvents = events.Where(e => e.EventName == "CounterRateValuePublished").Select(e => new @@ -1636,7 +1649,7 @@ private void AssertCounterEventsNotPresent(EventWrittenEventArgs[] events, strin Assert.Equal(0, filteredEvents.Length); } - private void AssertGaugeEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags, + private static void AssertGaugeEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags, string expectedUnit, params string[] expectedValues) { var counterEvents = events.Where(e => e.EventName == "GaugeValuePublished").Select(e => @@ -1658,7 +1671,7 @@ private void AssertGaugeEventsPresent(EventWrittenEventArgs[] events, string met } } - private void AssertHistogramEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags, + private static void AssertHistogramEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags, string expectedUnit, params (string, string, string)[] expected) { var counterEvents = events.Where(e => e.EventName == "HistogramValuePublished").Select(e => @@ -1684,7 +1697,7 @@ private void AssertHistogramEventsPresent(EventWrittenEventArgs[] events, string } } - private void AssertHistogramEventsNotPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags) + private static void AssertHistogramEventsNotPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags) { var counterEvents = events.Where(e => e.EventName == "HistogramValuePublished").Select(e => new @@ -1697,7 +1710,7 @@ private void AssertHistogramEventsNotPresent(EventWrittenEventArgs[] events, str var filteredEvents = counterEvents.Where(e => e.MeterName == meterName && e.InstrumentName == instrumentName && e.Tags == tags).ToArray(); Assert.Equal(0, filteredEvents.Length); } - private void AssertCollectStartStopEventsPresent(EventWrittenEventArgs[] events, double expectedIntervalSecs, int expectedPairs) + private static void AssertCollectStartStopEventsPresent(EventWrittenEventArgs[] events, double expectedIntervalSecs, int expectedPairs) { int startEventsSeen = 0; int stopEventsSeen = 0; @@ -1726,7 +1739,7 @@ private void AssertCollectStartStopEventsPresent(EventWrittenEventArgs[] events, Assert.Equal(expectedPairs, stopEventsSeen); } - private void AssertObservableCallbackErrorPresent(EventWrittenEventArgs[] events) + private static void AssertObservableCallbackErrorPresent(EventWrittenEventArgs[] events) { var errorEvents = events.Where(e => e.EventName == "ObservableInstrumentCallbackError").Select(e => new @@ -1737,7 +1750,7 @@ private void AssertObservableCallbackErrorPresent(EventWrittenEventArgs[] events Assert.Contains("Example user exception", errorEvents[0].ErrorText); } - private void AssertMultipleSessionsConfiguredIncorrectlyErrorEventsPresent(EventWrittenEventArgs[] events, + private static void AssertMultipleSessionsConfiguredIncorrectlyErrorEventsPresent(EventWrittenEventArgs[] events, string expectedMaxHistograms, string actualMaxHistograms, string expectedMaxTimeSeries, string actualMaxTimeSeries, string expectedRefreshInterval, string actualRefreshInterval) { From db167d9d3fa127cb12e7a4c6a49cb4c1ce7a4279 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Mar 2024 13:35:25 +0100 Subject: [PATCH 637/783] [release/8.0-staging] Add ProducesNetCoreAssets property to Publishing.props (#98988) * add property to publishing.props * rename to ProducesDotNetReleaseShippingAssets * Update Publishing.props * Set assets manifest metadata for assets that get shipped with .NET release (#98824) * add metadata to manifest * set in ItemDefinitionGroup * remove from items * comment --------- Co-authored-by: MilenaHristova Co-authored-by: Viktor Hofer --- eng/Publishing.props | 7 ++++--- src/installer/prepare-artifacts.proj | 12 ++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/eng/Publishing.props b/eng/Publishing.props index 920e79cbbd2f7c..8b796225f8274b 100644 --- a/eng/Publishing.props +++ b/eng/Publishing.props @@ -1,6 +1,7 @@ - + - 3 + true - \ No newline at end of file + + diff --git a/src/installer/prepare-artifacts.proj b/src/installer/prepare-artifacts.proj index 5413e825c9513b..a9e0931c116010 100644 --- a/src/installer/prepare-artifacts.proj +++ b/src/installer/prepare-artifacts.proj @@ -23,6 +23,8 @@ + + @@ -56,6 +58,16 @@ + + + + DotNetReleaseShipping=true + + + 8.0.0-rtm.23523.2 - 2.2.5-ci.444313 + 2.3.5 8.0.0-alpha.1.23527.1 16.0.5-alpha.1.23566.1 From 18b5fe657919af3f94b21aaa90385f7a2d9c052f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 22:05:05 -0400 Subject: [PATCH 644/783] Fix AsyncVoidMethodBuilder race condition around SynchronizationContext (#99640) This fixes a long-standing issue we've seen sporadically over the years but for which we just got a solid repro; the symptom is a sporadic unhandled null reference exception that crashes an app when using an async void method builder and a non-default SynchronizationContext. The issue is that, because of how state management is handled in the builder, the builder itself can be cleared while its SetResult method is running, and that means two reads of the _synchronizationContext field can end up returning a non-null value followed by a null value. The fix is to just cache the field into a local before completing the builder, and then only use the local state after. Co-authored-by: Stephen Toub --- .../AsyncVoidMethodBuilder.cs | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncVoidMethodBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncVoidMethodBuilder.cs index c4719b86132779..0caebcee620366 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncVoidMethodBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncVoidMethodBuilder.cs @@ -80,13 +80,27 @@ public void SetResult() TplEventSource.Log.TraceOperationEnd(this.Task.Id, AsyncCausalityStatus.Completed); } + // Grab the context. Calling SetResult will complete the builder which can cause the state + // to be cleared out of the builder, so we can't touch anything on this builder after calling Set*. + // This clearing is done as part of the AsyncStateMachineBox.MoveNext method after it calls + // MoveNext on the state machine: it's possible to have a chain of events like this: + // Thread 1: Calls AsyncStateMachineBox.MoveNext, which calls StateMachine.MoveNext. + // Thread 1: StateMachine.MoveNext hooks up a continuation and returns + // Thread 2: That continuation runs and calls AsyncStateMachineBox.MoveNext, which calls SetResult on the builder (below) + // which will result in the state machine task being marked completed. + // Thread 1: The original AsyncStateMachineBox.MoveNext call continues and sees that the task is now completed + // Thread 1: Clears the builder + // Thread 2: Continues in this call to AsyncVoidMethodBuilder. If it touches anything on this instance, it will be cleared. + SynchronizationContext? context = _synchronizationContext; + // Mark the builder as completed. As this is a void-returning method, this mostly // doesn't matter, but it can affect things like debug events related to finalization. + // Marking the task completed will also then enable the MoveNext code to clear state. _builder.SetResult(); - if (_synchronizationContext != null) + if (context != null) { - NotifySynchronizationContextOfCompletion(); + NotifySynchronizationContextOfCompletion(context); } } @@ -106,17 +120,18 @@ public void SetException(Exception exception) TplEventSource.Log.TraceOperationEnd(this.Task.Id, AsyncCausalityStatus.Error); } - if (_synchronizationContext != null) + SynchronizationContext? context = _synchronizationContext; + if (context != null) { // If we captured a synchronization context, Post the throwing of the exception to it // and decrement its outstanding operation count. try { - Task.ThrowAsync(exception, targetContext: _synchronizationContext); + Task.ThrowAsync(exception, targetContext: context); } finally { - NotifySynchronizationContextOfCompletion(); + NotifySynchronizationContextOfCompletion(context); } } else @@ -132,12 +147,12 @@ public void SetException(Exception exception) } /// Notifies the current synchronization context that the operation completed. - private void NotifySynchronizationContextOfCompletion() + private static void NotifySynchronizationContextOfCompletion(SynchronizationContext context) { - Debug.Assert(_synchronizationContext != null, "Must only be used with a non-null context."); + Debug.Assert(context != null, "Must only be used with a non-null context."); try { - _synchronizationContext.OperationCompleted(); + context.OperationCompleted(); } catch (Exception exc) { From f09cd44a09a6d311a100404810be049f2caf7a46 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 07:52:28 -0700 Subject: [PATCH 645/783] Always keep global symbols on ApplePlatforms (#99650) Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com> --- .../BuildIntegration/Microsoft.NETCore.Native.targets | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index e379eb457bdc6c..32f6be8d9c88f7 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -358,7 +358,6 @@ The .NET Foundation licenses this file to you under the MIT license. <_IgnoreLinkerWarnings>false <_IgnoreLinkerWarnings Condition="'$(_IsApplePlatform)' == 'true'">true - <_StripFlag Condition="'$(_IsApplePlatform)' == 'true' and '$(IlcExportUnmanagedEntrypoints)' == 'true'">-x @@ -386,7 +385,7 @@ The .NET Foundation licenses this file to you under the MIT license. + strip -no_code_signature_warning -x "$(NativeBinary)"" /> Date: Wed, 13 Mar 2024 08:46:40 -0700 Subject: [PATCH 646/783] Delete Decrypt_Pkcs1_ErrorsForInvalidPadding This test has a small random chance of failure because of non-determinism. The test Decrypt_Pkcs1_BadPadding covers this scenario and is properly deterministic, so let's go ahead and delete the test that has a chance of failing. Co-authored-by: Kevin Jones --- .../RSA/EncryptDecrypt.cs | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs index 5778b66d043491..0aaffebe542ab0 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/EncryptDecrypt.cs @@ -718,26 +718,6 @@ public void NotSupportedValueMethods() } } - [ConditionalTheory] - [InlineData(new byte[] { 1, 2, 3, 4 })] - [InlineData(new byte[0])] - public void Decrypt_Pkcs1_ErrorsForInvalidPadding(byte[] data) - { - if (data.Length == 0 && !PlatformSupportsEmptyRSAEncryption) - { - throw new SkipTestException("Platform does not support RSA encryption of empty data."); - } - - using (RSA rsa = RSAFactory.Create(TestData.RSA2048Params)) - { - byte[] encrypted = Encrypt(rsa, data, RSAEncryptionPadding.Pkcs1); - encrypted[1] ^= 0xFF; - - // PKCS#1, the data, and the key are all deterministic so this should always throw an exception. - Assert.ThrowsAny(() => Decrypt(rsa, encrypted, RSAEncryptionPadding.Pkcs1)); - } - } - [Fact] public void Decrypt_Pkcs1_BadPadding() { From 86f0444770f3950bcbb2ae435958dba80ad08fca Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 15:45:55 -0700 Subject: [PATCH 647/783] Update dependencies from https://github.com/dotnet/emsdk build (#99716) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.4-servicing.24163.1 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 97380116615baa..50349586bd3ca0 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 7bad61f7c233a2..b590e3f06edcab 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - 1639670c6547454278f51afc5c74e20f8acc7abd + 08a90ca2c88b17f1b5d081318354a41db0882cff - + https://github.com/dotnet/emsdk - 1639670c6547454278f51afc5c74e20f8acc7abd + 08a90ca2c88b17f1b5d081318354a41db0882cff From c412efbe9ced452289c0b3bed2fc01ba2d2d1440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Wed, 13 Mar 2024 18:32:22 -0700 Subject: [PATCH 648/783] Rename MSBuild property MicrosoftNativeQuicMsQuicVersion -> MicrosoftNativeQuicMsQuicSchannelVersion (#99714) --- eng/Versions.props | 2 +- src/libraries/System.Net.Quic/src/System.Net.Quic.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 57ccfbd0c1fa7a..609fc2931ba508 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -219,7 +219,7 @@ 8.0.0-rtm.23523.2 - 2.2.3 + 2.2.3 8.0.0-alpha.1.23527.1 16.0.5-alpha.1.23566.1 diff --git a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj index ba05cef37b5757..d6c063e216eb58 100644 --- a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj +++ b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj @@ -148,7 +148,7 @@ GeneratePathProperty="true" /> From e3734249509ed793382f7538bd55b5bebfb0f1cc Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Thu, 14 Mar 2024 09:57:37 -0700 Subject: [PATCH 649/783] Fixing SignedXml.CheckSignature for enveloped signature with `#xpointer(/)` Reference This additionally improves support for URI-less Reference elements. Co-authored-by: Samo Prelog Co-authored-by: Kevin Jones --- .../System.Security.Cryptography.Xml.csproj | 2 + .../Security/Cryptography/Xml/Reference.cs | 25 ++++++++--- .../tests/SignedXmlTest.cs | 41 +++++++++++++++++++ 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System.Security.Cryptography.Xml.csproj b/src/libraries/System.Security.Cryptography.Xml/src/System.Security.Cryptography.Xml.csproj index 5aea1a156c97a4..dacbf6255861a6 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System.Security.Cryptography.Xml.csproj +++ b/src/libraries/System.Security.Cryptography.Xml/src/System.Security.Cryptography.Xml.csproj @@ -4,6 +4,8 @@ true $(NoWarn);CA1850 true + true + 1 Provides classes to support the creation and validation of XML digital signatures. The classes in this namespace implement the World Wide Web Consortium Recommendation, "XML-Signature Syntax and Processing", described at http://www.w3.org/TR/xmldsig-core/. Commonly Used Types: diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Reference.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Reference.cs index ba3a46bc7a7a43..4e146c45e079f7 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Reference.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Reference.cs @@ -266,18 +266,31 @@ public void LoadXml(XmlElement value) // let the transform read the children of the transformElement for data transform.LoadInnerXml(transformElement.ChildNodes); // Hack! this is done to get around the lack of here() function support in XPath - if (transform is XmlDsigEnvelopedSignatureTransform - && _uri != null && (_uri.Length == 0 || _uri[0] == '#')) + if (transform is XmlDsigEnvelopedSignatureTransform) { // Walk back to the Signature tag. Find the nearest signature ancestor // Signature-->SignedInfo-->Reference-->Transforms-->Transform XmlNode? signatureTag = transformElement.SelectSingleNode("ancestor::ds:Signature[1]", nsm); // Resolve the reference to get starting point for position calculation. - XmlNode? referenceTarget = - _uri.Length == 0 - ? transformElement.OwnerDocument - : SignedXml!.GetIdElement(transformElement.OwnerDocument, Utils.GetIdFromLocalUri(_uri, out bool _)); + // This needs to match the way CalculateSignature resolves URI references. + XmlNode? referenceTarget = null; + if (_uri == null || _uri.Length == 0) + { + referenceTarget = transformElement.OwnerDocument; + } + else if (_uri[0] == '#') + { + string idref = Utils.ExtractIdFromLocalUri(_uri); + if (idref == "xpointer(/)") + { + referenceTarget = transformElement.OwnerDocument; + } + else + { + referenceTarget = SignedXml!.GetIdElement(transformElement.OwnerDocument, idref); + } + } XmlNodeList? signatureList = referenceTarget?.SelectNodes(".//ds:Signature", nsm); if (signatureList != null) diff --git a/src/libraries/System.Security.Cryptography.Xml/tests/SignedXmlTest.cs b/src/libraries/System.Security.Cryptography.Xml/tests/SignedXmlTest.cs index 3db8c44aed8270..bd22c5b835eed8 100644 --- a/src/libraries/System.Security.Cryptography.Xml/tests/SignedXmlTest.cs +++ b/src/libraries/System.Security.Cryptography.Xml/tests/SignedXmlTest.cs @@ -9,6 +9,7 @@ // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) // Copyright (C) 2004-2005, 2008 Novell, Inc (http://www.novell.com) +using System.Collections.Generic; using System.Globalization; using System.IO; using System.Net; @@ -1993,5 +1994,45 @@ public void CheckSignatureHandlesIncorrectOrTamperedReferenceWithMultipleEnvelop Assert.False(subject.CheckSignature()); } + + public static object[][] EnvelopedSignatureWithRootXpointerReference = new object[][] + { + new object[] { true, """HiSVaCE5w9iLXTVYTKP1t/yjjmPXvWovMYpgljGgpgz2Y=dqcBmS1ZvDJNhmCEgobpAb+A2XaiuB69dfGIhisZvqoxaWqAqv/0w49jp38+usJ5t3wcq3aMC631QE8iln+lHWrarojDMDWLa00isv3oE3q9UgOIV9e6MUSoRTTvQkmlK/LSYV9T/SKx6h03vLLcIkUMXaTkC/n2kthlJTGkLbU=t6qV1iTlkCPoaIeOTvnDczQv5pytUxMoyNXws5vaMQYxfJMKos47dvmiLtfWUDLYXFX3Yf/JMC14plJw2JA5jLrlHLnZj/vCjRtXckmWW/wGYewXUqrgR1CytStUeQKj9mNsi76erukua10UhzIrWG+H6YQ/qS4AMMJZU6jBvO0=AQAB""" }, + new object[] { false, """Tempered worldSVaCE5w9iLXTVYTKP1t/yjjmPXvWovMYpgljGgpgz2Y=dqcBmS1ZvDJNhmCEgobpAb+A2XaiuB69dfGIhisZvqoxaWqAqv/0w49jp38+usJ5t3wcq3aMC631QE8iln+lHWrarojDMDWLa00isv3oE3q9UgOIV9e6MUSoRTTvQkmlK/LSYV9T/SKx6h03vLLcIkUMXaTkC/n2kthlJTGkLbU=t6qV1iTlkCPoaIeOTvnDczQv5pytUxMoyNXws5vaMQYxfJMKos47dvmiLtfWUDLYXFX3Yf/JMC14plJw2JA5jLrlHLnZj/vCjRtXckmWW/wGYewXUqrgR1CytStUeQKj9mNsi76erukua10UhzIrWG+H6YQ/qS4AMMJZU6jBvO0=AQAB""" }, + }; + + [Theory] + [MemberData(nameof(EnvelopedSignatureWithRootXpointerReference))] + public void CheckSignatureHandlesEnvelopedSignatureWithRootXpointerReference(bool isValid, string xml) + { + XmlDocument xmlDoc = new (); + xmlDoc.LoadXml(xml); + SignedXml signedXml = new (xmlDoc); + signedXml.LoadXml(xmlDoc.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl)[0] as XmlElement); + + Assert.Equal(isValid, signedXml.CheckSignature()); + } + + + public static object[][] EnvelopedSignatureWithEmptyReference = new object[][] + { + new object[] { true, """HiSVaCE5w9iLXTVYTKP1t/yjjmPXvWovMYpgljGgpgz2Y=CiB9jgIS7+Wq+lpyzCGsBZQcQ2BxqQuEU9VCvb3Li5jMtjwRV1bMO+4Wfnb4VWhEtEUq6NdiVGXhC1xvtVLnnLDX7CD/jG6NvM1Yd0/rf0UUceBhzYLFE9HLsopsBmmm3t8FO6ZtRr1QqKM0XDaQleGK9vYd2m2Jq8OR3r/w4OY=vcM1wQVmLB9DwdnAym8l8nw63/HlTVzgTDhIwNzWPhsPE/qr2wlK4TEQ3rjU+RAdNytfFNCnuuh75ZVMjAWCV9h6VDlp0DOvBhb6GenhymtTAdJJKzBXKJP6mNPga9cPOP31IZ36Ui00G3fjBBPrHa7nStludgL9Wi0dBU28DjU=AQAB""" }, + new object[] { false, """HISVaCE5w9iLXTVYTKP1t/yjjmPXvWovMYpgljGgpgz2Y=CiB9jgIS7+Wq+lpyzCGsBZQcQ2BxqQuEU9VCvb3Li5jMtjwRV1bMO+4Wfnb4VWhEtEUq6NdiVGXhC1xvtVLnnLDX7CD/jG6NvM1Yd0/rf0UUceBhzYLFE9HLsopsBmmm3t8FO6ZtRr1QqKM0XDaQleGK9vYd2m2Jq8OR3r/w4OY=vcM1wQVmLB9DwdnAym8l8nw63/HlTVzgTDhIwNzWPhsPE/qr2wlK4TEQ3rjU+RAdNytfFNCnuuh75ZVMjAWCV9h6VDlp0DOvBhb6GenhymtTAdJJKzBXKJP6mNPga9cPOP31IZ36Ui00G3fjBBPrHa7nStludgL9Wi0dBU28DjU=AQAB""" }, + }; + + [Theory] + [MemberData(nameof(EnvelopedSignatureWithEmptyReference))] + public void CheckSignatureHandlesEnvelopedSignatureWithEmptyReference(bool isValid, string xml) + { + XmlDocument xmlDoc = new (); + xmlDoc.LoadXml(xml); + SignedXml signedXml = new (xmlDoc); + signedXml.LoadXml(xmlDoc.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl)[0] as XmlElement); + + // without this, CheckSignature throws + ((Reference)signedXml.SignedInfo.References[0]).TransformChain[0].LoadInput(xmlDoc); + + Assert.Equal(isValid, signedXml.CheckSignature()); + } } } From 50c3c8697c148b8fa88ad6a7174fbdb2811c6dfe Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 14:40:06 -0700 Subject: [PATCH 650/783] [release/8.0-staging] disable optimizations for PopCount (#99832) * disable optimizations for PopCount avoid using an optimization which might fail on non-SSE4 cpus. * remove whitespace for jit-format --------- Co-authored-by: Manish Godse <61718172+mangod9@users.noreply.github.com> --- src/coreclr/jit/utils.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index 2e1c0a52a3d81b..4c9fe6479eca41 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -3192,6 +3192,11 @@ uint32_t BitOperations::Log2(uint64_t value) // Return Value: // The population count (number of bits set) of value // +#if defined(_MSC_VER) +// Disable optimizations for PopCount to avoid the compiler from generating intrinsics +// not supported on all platforms. +#pragma optimize("", off) +#endif // _MSC_VER uint32_t BitOperations::PopCount(uint32_t value) { #if defined(_MSC_VER) @@ -3244,6 +3249,9 @@ uint32_t BitOperations::PopCount(uint64_t value) return static_cast(result); #endif } +#if defined(_MSC_VER) +#pragma optimize("", on) +#endif // _MSC_VER //------------------------------------------------------------------------ // BitOperations::ReverseBits: Reverses the bits in an integer value From ff80834c258fbc9b7cd25a1703d16fe1fb315205 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 17:25:42 -0700 Subject: [PATCH 651/783] [release/8.0-staging] Handle NativeOverlapped* coming from both the Windows or Portable thread pool in NativeRuntimeEventSource (#99656) --- ...untimeEventSource.Threading.NativeSinks.cs | 27 ++++++++++++++----- .../NativeRuntimeEventSource.Threading.cs | 27 ++++++++++++++----- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs index ad7ee54ae227a4..1dab92fc3636da 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs @@ -194,7 +194,7 @@ public unsafe void ThreadPoolWorkerThreadAdjustmentStats( [Event(63, Level = EventLevel.Verbose, Message = Messages.IOEnqueue, Task = Tasks.ThreadPool, Opcode = Opcodes.IOEnqueue, Version = 0, Keywords = Keywords.ThreadingKeyword | Keywords.ThreadTransferKeyword)] private unsafe void ThreadPoolIOEnqueue( IntPtr NativeOverlapped, - IntPtr Overlapped, + IntPtr Overlapped, // 0 if the Windows thread pool is used, the relevant info could be obtained from the NativeOverlapped* if necessary bool MultiDequeues, ushort ClrInstanceID = DefaultClrInstanceId) { @@ -207,9 +207,14 @@ public unsafe void ThreadPoolIOEnqueue(NativeOverlapped* nativeOverlapped) { if (IsEnabled(EventLevel.Verbose, Keywords.ThreadingKeyword | Keywords.ThreadTransferKeyword)) { +#if TARGET_WINDOWS + IntPtr overlapped = ThreadPool.UseWindowsThreadPool ? 0 : (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(); +#else + IntPtr overlapped = (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(); +#endif ThreadPoolIOEnqueue( (IntPtr)nativeOverlapped, - (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(), + overlapped, false); } } @@ -231,7 +236,7 @@ public void ThreadPoolIOEnqueue(RegisteredWaitHandle registeredWaitHandle) [Event(64, Level = EventLevel.Verbose, Message = Messages.IO, Task = Tasks.ThreadPool, Opcode = Opcodes.IODequeue, Version = 0, Keywords = Keywords.ThreadingKeyword | Keywords.ThreadTransferKeyword)] private unsafe void ThreadPoolIODequeue( IntPtr NativeOverlapped, - IntPtr Overlapped, + IntPtr Overlapped, // 0 if the Windows thread pool is used, the relevant info could be obtained from the NativeOverlapped* if necessary ushort ClrInstanceID = DefaultClrInstanceId) { LogThreadPoolIODequeue(NativeOverlapped, Overlapped, ClrInstanceID); @@ -243,9 +248,14 @@ public unsafe void ThreadPoolIODequeue(NativeOverlapped* nativeOverlapped) { if (IsEnabled(EventLevel.Verbose, Keywords.ThreadingKeyword | Keywords.ThreadTransferKeyword)) { +#if TARGET_WINDOWS + IntPtr overlapped = ThreadPool.UseWindowsThreadPool ? 0 : (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(); +#else + IntPtr overlapped = (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(); +#endif ThreadPoolIODequeue( (IntPtr)nativeOverlapped, - (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode()); + overlapped); } } @@ -277,16 +287,21 @@ public unsafe void ThreadPoolIOPack(NativeOverlapped* nativeOverlapped) { if (IsEnabled(EventLevel.Verbose, Keywords.ThreadingKeyword)) { +#if TARGET_WINDOWS + IntPtr overlapped = ThreadPool.UseWindowsThreadPool ? 0 : (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(); +#else + IntPtr overlapped = (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(); +#endif ThreadPoolIOPack( (IntPtr)nativeOverlapped, - (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode()); + overlapped); } } [Event(65, Level = EventLevel.Verbose, Message = Messages.IO, Task = Tasks.ThreadPool, Opcode = Opcodes.IOPack, Version = 0, Keywords = Keywords.ThreadingKeyword)] private unsafe void ThreadPoolIOPack( IntPtr NativeOverlapped, - IntPtr Overlapped, + IntPtr Overlapped, // 0 if the Windows thread pool is used, the relevant info could be obtained from the NativeOverlapped* if necessary ushort ClrInstanceID = DefaultClrInstanceId) { LogThreadPoolIOPack(NativeOverlapped, Overlapped, ClrInstanceID); diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs index c7a6d96aab2ba2..b883d9a6aa7d40 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs @@ -316,7 +316,7 @@ public unsafe void ThreadPoolWorkerThreadAdjustmentStats( [Event(63, Level = EventLevel.Verbose, Message = Messages.IOEnqueue, Task = Tasks.ThreadPool, Opcode = Opcodes.IOEnqueue, Version = 0, Keywords = Keywords.ThreadingKeyword | Keywords.ThreadTransferKeyword)] private unsafe void ThreadPoolIOEnqueue( IntPtr NativeOverlapped, - IntPtr Overlapped, + IntPtr Overlapped, // 0 if the Windows thread pool is used, the relevant info could be obtained from the NativeOverlapped* if necessary bool MultiDequeues, ushort ClrInstanceID = DefaultClrInstanceId) { @@ -343,9 +343,14 @@ public unsafe void ThreadPoolIOEnqueue(NativeOverlapped* nativeOverlapped) { if (IsEnabled(EventLevel.Verbose, Keywords.ThreadingKeyword | Keywords.ThreadTransferKeyword)) { +#if TARGET_WINDOWS + IntPtr overlapped = ThreadPool.UseWindowsThreadPool ? 0 : (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(); +#else + IntPtr overlapped = (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(); +#endif ThreadPoolIOEnqueue( (IntPtr)nativeOverlapped, - (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(), + overlapped, false); } } @@ -368,7 +373,7 @@ public void ThreadPoolIOEnqueue(RegisteredWaitHandle registeredWaitHandle) [Event(64, Level = EventLevel.Verbose, Message = Messages.IO, Task = Tasks.ThreadPool, Opcode = Opcodes.IODequeue, Version = 0, Keywords = Keywords.ThreadingKeyword | Keywords.ThreadTransferKeyword)] private unsafe void ThreadPoolIODequeue( IntPtr NativeOverlapped, - IntPtr Overlapped, + IntPtr Overlapped, // 0 if the Windows thread pool is used, the relevant info could be obtained from the NativeOverlapped* if necessary ushort ClrInstanceID = DefaultClrInstanceId) { EventData* data = stackalloc EventData[3]; @@ -390,9 +395,14 @@ public unsafe void ThreadPoolIODequeue(NativeOverlapped* nativeOverlapped) { if (IsEnabled(EventLevel.Verbose, Keywords.ThreadingKeyword | Keywords.ThreadTransferKeyword)) { +#if TARGET_WINDOWS + IntPtr overlapped = ThreadPool.UseWindowsThreadPool ? 0 : (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(); +#else + IntPtr overlapped = (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(); +#endif ThreadPoolIODequeue( (IntPtr)nativeOverlapped, - (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode()); + overlapped); } } @@ -432,9 +442,14 @@ public unsafe void ThreadPoolIOPack(NativeOverlapped* nativeOverlapped) { if (IsEnabled(EventLevel.Verbose, Keywords.ThreadingKeyword)) { +#if TARGET_WINDOWS + IntPtr overlapped = ThreadPool.UseWindowsThreadPool ? 0 : (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(); +#else + IntPtr overlapped = (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(); +#endif ThreadPoolIOPack( (IntPtr)nativeOverlapped, - (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode()); + overlapped); } } @@ -442,7 +457,7 @@ public unsafe void ThreadPoolIOPack(NativeOverlapped* nativeOverlapped) [Event(65, Level = EventLevel.Verbose, Message = Messages.IO, Task = Tasks.ThreadPool, Opcode = Opcodes.IOPack, Version = 0, Keywords = Keywords.ThreadingKeyword)] private unsafe void ThreadPoolIOPack( IntPtr NativeOverlapped, - IntPtr Overlapped, + IntPtr Overlapped, // 0 if the Windows thread pool is used, the relevant info could be obtained from the NativeOverlapped* if necessary ushort ClrInstanceID = DefaultClrInstanceId) { EventData* data = stackalloc EventData[3]; From fd8f5b5af7d73f697fe9654ad8ed7953cd597287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Mon, 18 Mar 2024 12:51:07 -0700 Subject: [PATCH 652/783] [release/8.0] disable optimizations for PopCount (#99832) (#99926) * disable optimizations for PopCount avoid using an optimization which might fail on non-SSE4 cpus. * remove whitespace for jit-format --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Manish Godse <61718172+mangod9@users.noreply.github.com> --- src/coreclr/jit/utils.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index 2e1c0a52a3d81b..4c9fe6479eca41 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -3192,6 +3192,11 @@ uint32_t BitOperations::Log2(uint64_t value) // Return Value: // The population count (number of bits set) of value // +#if defined(_MSC_VER) +// Disable optimizations for PopCount to avoid the compiler from generating intrinsics +// not supported on all platforms. +#pragma optimize("", off) +#endif // _MSC_VER uint32_t BitOperations::PopCount(uint32_t value) { #if defined(_MSC_VER) @@ -3244,6 +3249,9 @@ uint32_t BitOperations::PopCount(uint64_t value) return static_cast(result); #endif } +#if defined(_MSC_VER) +#pragma optimize("", on) +#endif // _MSC_VER //------------------------------------------------------------------------ // BitOperations::ReverseBits: Reverses the bits in an integer value From cf1182c88b8dc2cd4a63c7697648d3f96031fe65 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 17:17:15 -0700 Subject: [PATCH 653/783] Fix exporting certificate keys on macOS 14.4. Apple changed the error code we get back from a failed data-key export. This caused us to not attempt to export the key using the legacy APIs and assume the key export failed. This pull request adds the additional error code returned from macOS 14.4. Co-authored-by: Kevin Jones --- .../Interop.SecKeyRef.cs | 6 +- .../tests/X509Certificates/CertTests.cs | 102 ++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs index e7c08596a2c39c..5186018760af23 100644 --- a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs +++ b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs @@ -127,6 +127,10 @@ internal static bool TrySecKeyCopyExternalRepresentation( { const int errSecPassphraseRequired = -25260; + // macOS Sonoma 14.4 started returning errSecInvalidKeyAttributeMask when a key could not be exported + // because it must be exported with a password. + const int errSecInvalidKeyAttributeMask = -67738; + int result = AppleCryptoNative_SecKeyCopyExternalRepresentation( key, out SafeCFDataHandle data, @@ -141,7 +145,7 @@ internal static bool TrySecKeyCopyExternalRepresentation( externalRepresentation = CoreFoundation.CFGetData(data); return true; case kErrorSeeError: - if (Interop.CoreFoundation.GetErrorCode(errorHandle) == errSecPassphraseRequired) + if (Interop.CoreFoundation.GetErrorCode(errorHandle) is errSecPassphraseRequired or errSecInvalidKeyAttributeMask) { externalRepresentation = Array.Empty(); return false; diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs index f0b852c25b16a7..c6eadbdcc4c170 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs @@ -27,6 +27,108 @@ public CertTests(ITestOutputHelper output) _log = output; } + [Fact] + public static void PrivateKey_FromCertificate_CanExportPrivate_ECDsa() + { + using (ECDsa ca = ECDsa.Create(ECCurve.NamedCurves.nistP256)) + { + CertificateRequest req = new("CN=potatos", ca, HashAlgorithmName.SHA256); + + using (X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddDays(3))) + using (ECDsa certKey = cert.GetECDsaPrivateKey()) + { + ECParameters certParameters = certKey.ExportParameters(true); + ECParameters originalParameters = ca.ExportParameters(true); + AssertExtensions.SequenceEqual(originalParameters.D, certParameters.D); + } + } + } + + [Fact] + public static void PrivateKey_FromCertificate_CanExportPrivate_RSA() + { + using (RSA ca = RSA.Create(2048)) + { + CertificateRequest req = new("CN=potatos", ca, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + + using (X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddDays(3))) + using (RSA certKey = cert.GetRSAPrivateKey()) + { + RSAParameters certParameters = certKey.ExportParameters(true); + RSAParameters originalParameters = ca.ExportParameters(true); + AssertExtensions.SequenceEqual(originalParameters.P, certParameters.P); + AssertExtensions.SequenceEqual(originalParameters.Q, certParameters.Q); + } + } + } + + [Fact] + [SkipOnPlatform(PlatformSupport.MobileAppleCrypto, "DSA is not available")] + public static void PrivateKey_FromCertificate_CanExportPrivate_DSA() + { + DSAParameters originalParameters = DSATestData.GetDSA1024Params(); + + using (DSA ca = DSA.Create()) + { + ca.ImportParameters(originalParameters); + DSAX509SignatureGenerator gen = new DSAX509SignatureGenerator(ca); + X500DistinguishedName dn = new X500DistinguishedName("CN=potatos"); + + CertificateRequest req = new CertificateRequest( + dn, + gen.PublicKey, + HashAlgorithmName.SHA1); + + using (X509Certificate2 cert = req.Create(dn, gen, DateTimeOffset.Now, DateTimeOffset.Now.AddDays(3), [1, 2, 3])) + using (X509Certificate2 certWithKey = cert.CopyWithPrivateKey(ca)) + using (DSA certKey = certWithKey.GetDSAPrivateKey()) + { + DSAParameters certParameters = certKey.ExportParameters(true); + AssertExtensions.SequenceEqual(originalParameters.X, certParameters.X); + } + } + } + + [Fact] + public static void PrivateKey_FromCertificate_CanExportPrivate_ECDiffieHellman() + { + using (ECDsa ca = ECDsa.Create(ECCurve.NamedCurves.nistP256)) + using (ECDiffieHellman ecdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256)) + { + CertificateRequest issuerRequest = new CertificateRequest( + new X500DistinguishedName("CN=root"), + ca, + HashAlgorithmName.SHA256); + + issuerRequest.CertificateExtensions.Add( + new X509BasicConstraintsExtension(true, false, 0, true)); + + CertificateRequest request = new CertificateRequest( + new X500DistinguishedName("CN=potato"), + new PublicKey(ecdh), + HashAlgorithmName.SHA256); + + request.CertificateExtensions.Add( + new X509BasicConstraintsExtension(false, false, 0, true)); + request.CertificateExtensions.Add( + new X509KeyUsageExtension(X509KeyUsageFlags.KeyAgreement, true)); + + DateTimeOffset notBefore = DateTimeOffset.UtcNow; + DateTimeOffset notAfter = notBefore.AddDays(30); + byte[] serial = [1, 2, 3, 4, 5, 6, 7, 8]; + + using (X509Certificate2 issuer = issuerRequest.CreateSelfSigned(notBefore, notAfter)) + using (X509Certificate2 cert = request.Create(issuer, notBefore, notAfter, serial)) + using (X509Certificate2 certWithKey = cert.CopyWithPrivateKey(ecdh)) + using (ECDiffieHellman certKey = certWithKey.GetECDiffieHellmanPrivateKey()) + { + ECParameters certParameters = certKey.ExportParameters(true); + ECParameters originalParameters = ecdh.ExportParameters(true); + AssertExtensions.SequenceEqual(originalParameters.D, certParameters.D); + } + } + } + [Fact] public static void PublicPrivateKey_IndependentLifetimes_ECDsa() { From f381395b39f7be81f7cb1bc85b80398226aa4b72 Mon Sep 17 00:00:00 2001 From: vseanreesermsft <78103370+vseanreesermsft@users.noreply.github.com> Date: Tue, 19 Mar 2024 12:02:53 -0700 Subject: [PATCH 654/783] Fix exporting certificate keys on macOS 14.4. (#99976) Apple changed the error code we get back from a failed data-key export. This caused us to not attempt to export the key using the legacy APIs and assume the key export failed. This pull request adds the additional error code returned from macOS 14.4. Co-authored-by: Kevin Jones --- .../Interop.SecKeyRef.cs | 6 +- .../tests/X509Certificates/CertTests.cs | 102 ++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs index e7c08596a2c39c..5186018760af23 100644 --- a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs +++ b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs @@ -127,6 +127,10 @@ internal static bool TrySecKeyCopyExternalRepresentation( { const int errSecPassphraseRequired = -25260; + // macOS Sonoma 14.4 started returning errSecInvalidKeyAttributeMask when a key could not be exported + // because it must be exported with a password. + const int errSecInvalidKeyAttributeMask = -67738; + int result = AppleCryptoNative_SecKeyCopyExternalRepresentation( key, out SafeCFDataHandle data, @@ -141,7 +145,7 @@ internal static bool TrySecKeyCopyExternalRepresentation( externalRepresentation = CoreFoundation.CFGetData(data); return true; case kErrorSeeError: - if (Interop.CoreFoundation.GetErrorCode(errorHandle) == errSecPassphraseRequired) + if (Interop.CoreFoundation.GetErrorCode(errorHandle) is errSecPassphraseRequired or errSecInvalidKeyAttributeMask) { externalRepresentation = Array.Empty(); return false; diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs index f0b852c25b16a7..c6eadbdcc4c170 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertTests.cs @@ -27,6 +27,108 @@ public CertTests(ITestOutputHelper output) _log = output; } + [Fact] + public static void PrivateKey_FromCertificate_CanExportPrivate_ECDsa() + { + using (ECDsa ca = ECDsa.Create(ECCurve.NamedCurves.nistP256)) + { + CertificateRequest req = new("CN=potatos", ca, HashAlgorithmName.SHA256); + + using (X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddDays(3))) + using (ECDsa certKey = cert.GetECDsaPrivateKey()) + { + ECParameters certParameters = certKey.ExportParameters(true); + ECParameters originalParameters = ca.ExportParameters(true); + AssertExtensions.SequenceEqual(originalParameters.D, certParameters.D); + } + } + } + + [Fact] + public static void PrivateKey_FromCertificate_CanExportPrivate_RSA() + { + using (RSA ca = RSA.Create(2048)) + { + CertificateRequest req = new("CN=potatos", ca, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + + using (X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddDays(3))) + using (RSA certKey = cert.GetRSAPrivateKey()) + { + RSAParameters certParameters = certKey.ExportParameters(true); + RSAParameters originalParameters = ca.ExportParameters(true); + AssertExtensions.SequenceEqual(originalParameters.P, certParameters.P); + AssertExtensions.SequenceEqual(originalParameters.Q, certParameters.Q); + } + } + } + + [Fact] + [SkipOnPlatform(PlatformSupport.MobileAppleCrypto, "DSA is not available")] + public static void PrivateKey_FromCertificate_CanExportPrivate_DSA() + { + DSAParameters originalParameters = DSATestData.GetDSA1024Params(); + + using (DSA ca = DSA.Create()) + { + ca.ImportParameters(originalParameters); + DSAX509SignatureGenerator gen = new DSAX509SignatureGenerator(ca); + X500DistinguishedName dn = new X500DistinguishedName("CN=potatos"); + + CertificateRequest req = new CertificateRequest( + dn, + gen.PublicKey, + HashAlgorithmName.SHA1); + + using (X509Certificate2 cert = req.Create(dn, gen, DateTimeOffset.Now, DateTimeOffset.Now.AddDays(3), [1, 2, 3])) + using (X509Certificate2 certWithKey = cert.CopyWithPrivateKey(ca)) + using (DSA certKey = certWithKey.GetDSAPrivateKey()) + { + DSAParameters certParameters = certKey.ExportParameters(true); + AssertExtensions.SequenceEqual(originalParameters.X, certParameters.X); + } + } + } + + [Fact] + public static void PrivateKey_FromCertificate_CanExportPrivate_ECDiffieHellman() + { + using (ECDsa ca = ECDsa.Create(ECCurve.NamedCurves.nistP256)) + using (ECDiffieHellman ecdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256)) + { + CertificateRequest issuerRequest = new CertificateRequest( + new X500DistinguishedName("CN=root"), + ca, + HashAlgorithmName.SHA256); + + issuerRequest.CertificateExtensions.Add( + new X509BasicConstraintsExtension(true, false, 0, true)); + + CertificateRequest request = new CertificateRequest( + new X500DistinguishedName("CN=potato"), + new PublicKey(ecdh), + HashAlgorithmName.SHA256); + + request.CertificateExtensions.Add( + new X509BasicConstraintsExtension(false, false, 0, true)); + request.CertificateExtensions.Add( + new X509KeyUsageExtension(X509KeyUsageFlags.KeyAgreement, true)); + + DateTimeOffset notBefore = DateTimeOffset.UtcNow; + DateTimeOffset notAfter = notBefore.AddDays(30); + byte[] serial = [1, 2, 3, 4, 5, 6, 7, 8]; + + using (X509Certificate2 issuer = issuerRequest.CreateSelfSigned(notBefore, notAfter)) + using (X509Certificate2 cert = request.Create(issuer, notBefore, notAfter, serial)) + using (X509Certificate2 certWithKey = cert.CopyWithPrivateKey(ecdh)) + using (ECDiffieHellman certKey = certWithKey.GetECDiffieHellmanPrivateKey()) + { + ECParameters certParameters = certKey.ExportParameters(true); + ECParameters originalParameters = ecdh.ExportParameters(true); + AssertExtensions.SequenceEqual(originalParameters.D, certParameters.D); + } + } + } + [Fact] public static void PublicPrivateKey_IndependentLifetimes_ECDsa() { From c27b2033c5bc66749a5d290841a0fbee5a5791d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Tue, 19 Mar 2024 17:45:15 -0700 Subject: [PATCH 655/783] [release/8.0] Upgrade zlib to 1.3.1 (#99473) * [8.0] Upgrade zlib to 1.3.1 * [PATCH] Make zlib compile clean against C4244 clang equivalent is "implicit-int-conversion" warning The change to deflate.c is legal because 'len' has an upper bound of MAX_STORED, which means it fits cleanly into a 16-bit integer. So writing out 2x 8-bit values will not result in data loss. The change to trees.c is legal because within this loop, 'count' is intended to have an upper bound of 138, with the target assignment only executing if 'count' is bounded by 4. Neither the 'count' local in isolation nor the addition that's part of the target line is expected to result in integer overflow. But even if it did, that's a matter for a different warning code and doesn't impact the correctness of the narrowing cast being considered here. Author: Levi Broderick * Update cgmanifest.json and THIRD-PARTY-NOTICES.TXT * Bring back patches comment, remove unnecessary file removal comment. --- THIRD-PARTY-NOTICES.TXT | 2 +- src/native/external/cgmanifest.json | 2 +- src/native/external/zlib-version.txt | 14 +- src/native/external/zlib/CMakeLists.txt | 45 +- src/native/external/zlib/ChangeLog | 30 +- src/native/external/zlib/FAQ | 5 +- src/native/external/zlib/Makefile.in | 22 +- src/native/external/zlib/README | 19 +- src/native/external/zlib/adler32.c | 32 +- src/native/external/zlib/compress.c | 21 +- src/native/external/zlib/configure | 31 +- src/native/external/zlib/crc32.c | 248 ++++----- src/native/external/zlib/deflate.c | 609 ++++++++++------------- src/native/external/zlib/deflate.h | 51 +- src/native/external/zlib/gzclose.c | 4 +- src/native/external/zlib/gzguts.h | 31 +- src/native/external/zlib/gzlib.c | 113 ++--- src/native/external/zlib/gzread.c | 88 +--- src/native/external/zlib/gzwrite.c | 84 +--- src/native/external/zlib/infback.c | 30 +- src/native/external/zlib/inffast.c | 5 +- src/native/external/zlib/inffast.h | 2 +- src/native/external/zlib/inflate.c | 131 ++--- src/native/external/zlib/inftrees.c | 17 +- src/native/external/zlib/inftrees.h | 10 +- src/native/external/zlib/treebuild.xml | 4 +- src/native/external/zlib/trees.c | 542 +++++++++----------- src/native/external/zlib/uncompr.c | 16 +- src/native/external/zlib/zconf.h | 18 +- src/native/external/zlib/zconf.h.cmakein | 18 +- src/native/external/zlib/zconf.h.in | 18 +- src/native/external/zlib/zlib.3 | 6 +- src/native/external/zlib/zlib.h | 391 +++++++-------- src/native/external/zlib/zlib2ansi | 152 ------ src/native/external/zlib/zutil.c | 60 +-- src/native/external/zlib/zutil.h | 47 +- 36 files changed, 1132 insertions(+), 1786 deletions(-) delete mode 100644 src/native/external/zlib/zlib2ansi diff --git a/THIRD-PARTY-NOTICES.TXT b/THIRD-PARTY-NOTICES.TXT index 4b40333f72ce4f..9b4e777ca47a98 100644 --- a/THIRD-PARTY-NOTICES.TXT +++ b/THIRD-PARTY-NOTICES.TXT @@ -73,7 +73,7 @@ https://github.com/madler/zlib https://zlib.net/zlib_license.html /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.13, October 13th, 2022 + version 1.3.1, January 22nd, 2024 Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler diff --git a/src/native/external/cgmanifest.json b/src/native/external/cgmanifest.json index 4f6264b3c7ab29..e45d9d90029623 100644 --- a/src/native/external/cgmanifest.json +++ b/src/native/external/cgmanifest.json @@ -46,7 +46,7 @@ "Type": "git", "Git": { "RepositoryUrl": "https://github.com/madler/zlib", - "CommitHash": "04f42ceca40f73e2978b50e93806c2a18c1281fc" + "CommitHash": "51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf" } }, "DevelopmentDependency": false diff --git a/src/native/external/zlib-version.txt b/src/native/external/zlib-version.txt index fcac66cc4645f4..5da9869df33f59 100644 --- a/src/native/external/zlib-version.txt +++ b/src/native/external/zlib-version.txt @@ -1,17 +1,9 @@ -v1.2.13 -(04f42ceca40f73e2978b50e93806c2a18c1281fc) +v1.3.1 +(51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf) -https://github.com/madler/zlib/releases/tag/v1.2.13 +https://github.com/madler/zlib/releases/tag/v1.3.1 We have removed zlib.3.pdf from our local copy, as it is a binary file which is not needed for our compilation. -We have also cherry-picked into our local copy: - -- https://github.com/madler/zlib/commit/e554695638228b846d49657f31eeff0ca4680e8a - - This patch only affects memLevel 9 compression. .NET doesn't currently use this - memLevel, but we'll take this patch out of an abundance of caution just in case - we enable this functionality in a future release. - We have also applied the custom patches under the patches/zlib folder. diff --git a/src/native/external/zlib/CMakeLists.txt b/src/native/external/zlib/CMakeLists.txt index b412dc7feb732a..15ceebe787e7d9 100644 --- a/src/native/external/zlib/CMakeLists.txt +++ b/src/native/external/zlib/CMakeLists.txt @@ -1,9 +1,11 @@ -cmake_minimum_required(VERSION 2.4.4) +cmake_minimum_required(VERSION 2.4.4...3.15.0) set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) project(zlib C) -set(VERSION "1.2.13") +set(VERSION "1.3.1") + +option(ZLIB_BUILD_EXAMPLES "Enable Zlib Examples" ON) set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") @@ -148,7 +150,9 @@ if(MINGW) endif(MINGW) add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +target_include_directories(zlib PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +target_include_directories(zlibstatic PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) set_target_properties(zlib PROPERTIES SOVERSION 1) @@ -166,7 +170,7 @@ endif() if(UNIX) # On unix-like platforms the library is almost always called libz set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z) - if(NOT APPLE) + if(NOT APPLE AND NOT(CMAKE_SYSTEM_NAME STREQUAL AIX)) set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"") endif() elseif(BUILD_SHARED_LIBS AND WIN32) @@ -193,21 +197,22 @@ endif() #============================================================================ # Example binaries #============================================================================ - -add_executable(example test/example.c) -target_link_libraries(example zlib) -add_test(example example) - -add_executable(minigzip test/minigzip.c) -target_link_libraries(minigzip zlib) - -if(HAVE_OFF64_T) - add_executable(example64 test/example.c) - target_link_libraries(example64 zlib) - set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") - add_test(example64 example64) - - add_executable(minigzip64 test/minigzip.c) - target_link_libraries(minigzip64 zlib) - set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") +if(ZLIB_BUILD_EXAMPLES) + add_executable(example test/example.c) + target_link_libraries(example zlib) + add_test(example example) + + add_executable(minigzip test/minigzip.c) + target_link_libraries(minigzip zlib) + + if(HAVE_OFF64_T) + add_executable(example64 test/example.c) + target_link_libraries(example64 zlib) + set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") + add_test(example64 example64) + + add_executable(minigzip64 test/minigzip.c) + target_link_libraries(minigzip64 zlib) + set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") + endif() endif() diff --git a/src/native/external/zlib/ChangeLog b/src/native/external/zlib/ChangeLog index 457526bc6a51f5..b801a1031ec0f5 100644 --- a/src/native/external/zlib/ChangeLog +++ b/src/native/external/zlib/ChangeLog @@ -1,6 +1,34 @@ ChangeLog file for zlib +Changes in 1.3.1 (22 Jan 2024) +- Reject overflows of zip header fields in minizip +- Fix bug in inflateSync() for data held in bit buffer +- Add LIT_MEM define to use more memory for a small deflate speedup +- Fix decision on the emission of Zip64 end records in minizip +- Add bounds checking to ERR_MSG() macro, used by zError() +- Neutralize zip file traversal attacks in miniunz +- Fix a bug in ZLIB_DEBUG compiles in check_match() +- Various portability and appearance improvements + +Changes in 1.3 (18 Aug 2023) +- Remove K&R function definitions and zlib2ansi +- Fix bug in deflateBound() for level 0 and memLevel 9 +- Fix bug when gzungetc() is used immediately after gzopen() +- Fix bug when using gzflush() with a very small buffer +- Fix crash when gzsetparams() attempted for transparent write +- Fix test/example.c to work with FORCE_STORED +- Rewrite of zran in examples (see zran.c version history) +- Fix minizip to allow it to open an empty zip file +- Fix reading disk number start on zip64 files in minizip +- Fix logic error in minizip argument processing +- Add minizip testing to Makefile +- Read multiple bytes instead of byte-by-byte in minizip unzip.c +- Add memory sanitizer to configure (--memory) +- Various portability improvements +- Various documentation improvements +- Various spelling and typo corrections + Changes in 1.2.13 (13 Oct 2022) - Fix configure issue that discarded provided CC definition - Correct incorrect inputs provided to the CRC functions @@ -1445,7 +1473,7 @@ Changes in 0.99 (27 Jan 96) - fix typo in Make_vms.com (f$trnlnm -> f$getsyi) - in fcalloc, normalize pointer if size > 65520 bytes - don't use special fcalloc for 32 bit Borland C++ -- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc. - use Z_BINARY instead of BINARY - document that gzclose after gzdopen will close the file - allow "a" as mode in gzopen diff --git a/src/native/external/zlib/FAQ b/src/native/external/zlib/FAQ index 99b7cf92e45497..92f5d3e29fab46 100644 --- a/src/native/external/zlib/FAQ +++ b/src/native/external/zlib/FAQ @@ -4,7 +4,7 @@ If your question is not there, please check the zlib home page http://zlib.net/ which may have more recent information. -The lastest zlib FAQ is at http://zlib.net/zlib_faq.html +The latest zlib FAQ is at http://zlib.net/zlib_faq.html 1. Is zlib Y2K-compliant? @@ -14,8 +14,7 @@ The lastest zlib FAQ is at http://zlib.net/zlib_faq.html 2. Where can I get a Windows DLL version? The zlib sources can be compiled without change to produce a DLL. See the - file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the - precompiled DLL are found in the zlib web site at http://zlib.net/ . + file win32/DLL_FAQ.txt in the zlib distribution. 3. Where can I get a Visual Basic interface to zlib? diff --git a/src/native/external/zlib/Makefile.in b/src/native/external/zlib/Makefile.in index 7d2713f4c574a9..cb8b00a9b078fb 100644 --- a/src/native/external/zlib/Makefile.in +++ b/src/native/external/zlib/Makefile.in @@ -1,5 +1,5 @@ # Makefile for zlib -# Copyright (C) 1995-2017 Jean-loup Gailly, Mark Adler +# Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler # For conditions of distribution and use, see copyright notice in zlib.h # To compile and test, type: @@ -22,13 +22,13 @@ CFLAGS=-O SFLAGS=-O LDFLAGS= -TEST_LDFLAGS=$(LDFLAGS) -L. libz.a +TEST_LIBS=-L. libz.a LDSHARED=$(CC) CPP=$(CC) -E STATICLIB=libz.a SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.13 +SHAREDLIBV=libz.so.1.3.1 SHAREDLIBM=libz.so.1 LIBS=$(STATICLIB) $(SHAREDLIBV) @@ -282,10 +282,10 @@ placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a -@rmdir objs example$(EXE): example.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ example.o $(TEST_LIBS) minigzip$(EXE): minigzip.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ minigzip.o $(TEST_LIBS) examplesh$(EXE): example.o $(SHAREDLIBV) $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) -L. $(SHAREDLIBV) @@ -294,10 +294,10 @@ minigzipsh$(EXE): minigzip.o $(SHAREDLIBV) $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) -L. $(SHAREDLIBV) example64$(EXE): example64.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ example64.o $(TEST_LIBS) minigzip64$(EXE): minigzip64.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ minigzip64.o $(TEST_LIBS) install-libs: $(LIBS) -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi @@ -359,8 +359,14 @@ zconf.h.cmakein: $(SRCDIR)zconf.h.in zconf: $(SRCDIR)zconf.h.in cp -p $(SRCDIR)zconf.h.in zconf.h +minizip-test: static + cd contrib/minizip && { CC="$(CC)" CFLAGS="$(CFLAGS)" $(MAKE) test ; cd ../.. ; } + +minizip-clean: + cd contrib/minizip && { $(MAKE) clean ; cd ../.. ; } + mostlyclean: clean -clean: +clean: minizip-clean rm -f *.o *.lo *~ \ example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ example64$(EXE) minigzip64$(EXE) \ diff --git a/src/native/external/zlib/README b/src/native/external/zlib/README index ba34d1894a9b4a..c5f917540b6fd2 100644 --- a/src/native/external/zlib/README +++ b/src/native/external/zlib/README @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.13 is a general purpose data compression library. All the code is +zlib 1.3.1 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and @@ -29,18 +29,17 @@ PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at -http://marknelson.us/1997/01/01/zlib-engine/ . +https://marknelson.us/posts/1997/01/01/zlib-engine.html . -The changes made in version 1.2.13 are documented in the file ChangeLog. +The changes made in version 1.3.1 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . -zlib is available in Java using the java.util.zip package, documented at -http://java.sun.com/developer/technicalArticles/Programming/compression/ . +zlib is available in Java using the java.util.zip package. Follow the API +Documentation link at: https://docs.oracle.com/search/?q=java.util.zip . -A Perl interface to zlib written by Paul Marquess is available -at CPAN (Comprehensive Perl Archive Network) sites, including -http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . +A Perl interface to zlib and bzip2 written by Paul Marquess +can be found at https://github.com/pmqs/IO-Compress . A Python interface to zlib written by A.M. Kuchling is available in Python 1.5 and later versions, see @@ -64,7 +63,7 @@ Notes for some targets: - zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works when compiled with cc. -- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is +- On Digital Unix 4.0D (formerly OSF/1) on AlphaServer, the cc option -std1 is necessary to get gzprintf working correctly. This is done by configure. - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with @@ -84,7 +83,7 @@ Acknowledgments: Copyright notice: - (C) 1995-2022 Jean-loup Gailly and Mark Adler + (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/native/external/zlib/adler32.c b/src/native/external/zlib/adler32.c index d0be4380a39c9c..04b81d29bad169 100644 --- a/src/native/external/zlib/adler32.c +++ b/src/native/external/zlib/adler32.c @@ -7,8 +7,6 @@ #include "zutil.h" -local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); - #define BASE 65521U /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ @@ -60,11 +58,7 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); #endif /* ========================================================================= */ -uLong ZEXPORT adler32_z(adler, buf, len) - uLong adler; - const Bytef *buf; - z_size_t len; -{ +uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) { unsigned long sum2; unsigned n; @@ -131,20 +125,12 @@ uLong ZEXPORT adler32_z(adler, buf, len) } /* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ +uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) { return adler32_z(adler, buf, len); } /* ========================================================================= */ -local uLong adler32_combine_(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ +local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) { unsigned long sum1; unsigned long sum2; unsigned rem; @@ -169,18 +155,10 @@ local uLong adler32_combine_(adler1, adler2, len2) } /* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ +uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) { return adler32_combine_(adler1, adler2, len2); } -uLong ZEXPORT adler32_combine64(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ +uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) { return adler32_combine_(adler1, adler2, len2); } diff --git a/src/native/external/zlib/compress.c b/src/native/external/zlib/compress.c index 2ad5326c14ec04..f43bacf7ab9707 100644 --- a/src/native/external/zlib/compress.c +++ b/src/native/external/zlib/compress.c @@ -19,13 +19,8 @@ memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ -int ZEXPORT compress2(dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ +int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen, int level) { z_stream stream; int err; const uInt max = (uInt)-1; @@ -65,12 +60,8 @@ int ZEXPORT compress2(dest, destLen, source, sourceLen, level) /* =========================================================================== */ -int ZEXPORT compress(dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ +int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen) { return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); } @@ -78,9 +69,7 @@ int ZEXPORT compress(dest, destLen, source, sourceLen) If the default memLevel or windowBits for deflateInit() is changed, then this function needs to be updated. */ -uLong ZEXPORT compressBound(sourceLen) - uLong sourceLen; -{ +uLong ZEXPORT compressBound(uLong sourceLen) { return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13; } diff --git a/src/native/external/zlib/configure b/src/native/external/zlib/configure index fa4d5daaba99f4..c55098afc4ae52 100644 --- a/src/native/external/zlib/configure +++ b/src/native/external/zlib/configure @@ -25,7 +25,7 @@ if test $SRCDIR = "."; then ZINCOUT="-I." SRCDIR="" else - ZINC='-include zconf.h' + ZINC='-I. -include zconf.h' ZINCOUT='-I. -I$(SRCDIR)' SRCDIR="$SRCDIR/" fi @@ -44,9 +44,8 @@ STATICLIB=libz.a # extract zlib version numbers from zlib.h VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}zlib.h` -VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < ${SRCDIR}zlib.h` -VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h` -VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h` +VER3=`echo ${VER}|sed -n -e 's/\([0-9]\{1,\}\(\\.[0-9]\{1,\}\)\{1,2\}\).*/\1/p'` +VER1=`echo ${VER}|sed -n -e 's/\([0-9]\{1,\}\)\\..*/\1/p'` # establish commands for library building if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then @@ -90,7 +89,8 @@ build64=0 gcc=0 warn=0 debug=0 -sanitize=0 +address=0 +memory=0 old_cc="$CC" old_cflags="$CFLAGS" OBJC='$(OBJZ) $(OBJG)' @@ -102,7 +102,7 @@ leave() if test "$*" != "0"; then echo "** $0 aborting." | tee -a configure.log fi - rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version + rm -rf $test.[co] $test $test$shared_ext $test.gcno $test.dSYM ./--version echo -------------------- >> configure.log echo >> configure.log echo >> configure.log @@ -141,7 +141,9 @@ case "$1" in -c* | --const) zconst=1; shift ;; -w* | --warn) warn=1; shift ;; -d* | --debug) debug=1; shift ;; - --sanitize) sanitize=1; shift ;; + --sanitize) address=1; shift ;; + --address) address=1; shift ;; + --memory) memory=1; shift ;; *) echo "unknown option: $1" | tee -a configure.log echo "$0 --help for help" | tee -a configure.log @@ -211,8 +213,11 @@ if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then CFLAGS="${CFLAGS} -Wall -Wextra" fi fi - if test $sanitize -eq 1; then - CFLAGS="${CFLAGS} -g -fsanitize=address" + if test $address -eq 1; then + CFLAGS="${CFLAGS} -g -fsanitize=address -fno-omit-frame-pointer" + fi + if test $memory -eq 1; then + CFLAGS="${CFLAGS} -g -fsanitize=memory -fno-omit-frame-pointer" fi if test $debug -eq 1; then CFLAGS="${CFLAGS} -DZLIB_DEBUG" @@ -260,7 +265,9 @@ if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then SHAREDLIBV=libz.$VER$shared_ext SHAREDLIBM=libz.$VER1$shared_ext LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"} - if libtool -V 2>&1 | grep Apple > /dev/null; then + if "${CROSS_PREFIX}libtool" -V 2>&1 | grep Apple > /dev/null; then + AR="${CROSS_PREFIX}libtool" + elif libtool -V 2>&1 | grep Apple > /dev/null; then AR="libtool" else AR="/usr/bin/libtool" @@ -435,7 +442,7 @@ EOF if test $shared -eq 1; then echo Checking for shared library support... | tee -a configure.log # we must test in two steps (cc then ld), required at least on SunOS 4.x - if try $CC -w -c $SFLAGS $test.c && + if try $CC -c $SFLAGS $test.c && try $LDSHARED $SFLAGS -o $test$shared_ext $test.o; then echo Building shared library $SHAREDLIBV with $CC. | tee -a configure.log elif test -z "$old_cc" -a -z "$old_cflags"; then @@ -860,7 +867,7 @@ echo prefix = $prefix >> configure.log echo sharedlibdir = $sharedlibdir >> configure.log echo uname = $uname >> configure.log -# udpate Makefile with the configure results +# update Makefile with the configure results sed < ${SRCDIR}Makefile.in " /^CC *=/s#=.*#=$CC# /^CFLAGS *=/s#=.*#=$CFLAGS# diff --git a/src/native/external/zlib/crc32.c b/src/native/external/zlib/crc32.c index f8357b083f7636..6c38f5c04c6a87 100644 --- a/src/native/external/zlib/crc32.c +++ b/src/native/external/zlib/crc32.c @@ -103,19 +103,6 @@ # define ARMCRC32 #endif -/* Local functions. */ -local z_crc_t multmodp OF((z_crc_t a, z_crc_t b)); -local z_crc_t x2nmodp OF((z_off64_t n, unsigned k)); - -#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) - local z_word_t byte_swap OF((z_word_t word)); -#endif - -#if defined(W) && !defined(ARMCRC32) - local z_crc_t crc_word OF((z_word_t data)); - local z_word_t crc_word_big OF((z_word_t data)); -#endif - #if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) /* Swap the bytes in a z_word_t to convert between little and big endian. Any @@ -123,9 +110,7 @@ local z_crc_t x2nmodp OF((z_off64_t n, unsigned k)); instruction, if one is available. This assumes that word_t is either 32 bits or 64 bits. */ -local z_word_t byte_swap(word) - z_word_t word; -{ +local z_word_t byte_swap(z_word_t word) { # if W == 8 return (word & 0xff00000000000000) >> 56 | @@ -146,24 +131,77 @@ local z_word_t byte_swap(word) } #endif +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Table of powers of x for combining CRC-32s, filled in by make_crc_table() + * below. + */ + local z_crc_t FAR x2n_table[32]; +#else +/* ========================================================================= + * Tables for byte-wise and braided CRC-32 calculations, and a table of powers + * of x for combining CRC-32s, all made by make_crc_table(). + */ +# include "crc32.h" +#endif + /* CRC polynomial. */ #define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ -#ifdef DYNAMIC_CRC_TABLE +/* + Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, + reflected. For speed, this requires that a not be zero. + */ +local z_crc_t multmodp(z_crc_t a, z_crc_t b) { + z_crc_t m, p; + + m = (z_crc_t)1 << 31; + p = 0; + for (;;) { + if (a & m) { + p ^= b; + if ((a & (m - 1)) == 0) + break; + } + m >>= 1; + b = b & 1 ? (b >> 1) ^ POLY : b >> 1; + } + return p; +} +/* + Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been + initialized. + */ +local z_crc_t x2nmodp(z_off64_t n, unsigned k) { + z_crc_t p; + + p = (z_crc_t)1 << 31; /* x^0 == 1 */ + while (n) { + if (n & 1) + p = multmodp(x2n_table[k & 31], p); + n >>= 1; + k++; + } + return p; +} + +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Build the tables for byte-wise and braided CRC-32 calculations, and a table + * of powers of x for combining CRC-32s. + */ local z_crc_t FAR crc_table[256]; -local z_crc_t FAR x2n_table[32]; -local void make_crc_table OF((void)); #ifdef W local z_word_t FAR crc_big_table[256]; local z_crc_t FAR crc_braid_table[W][256]; local z_word_t FAR crc_braid_big_table[W][256]; - local void braid OF((z_crc_t [][256], z_word_t [][256], int, int)); + local void braid(z_crc_t [][256], z_word_t [][256], int, int); #endif #ifdef MAKECRCH - local void write_table OF((FILE *, const z_crc_t FAR *, int)); - local void write_table32hi OF((FILE *, const z_word_t FAR *, int)); - local void write_table64 OF((FILE *, const z_word_t FAR *, int)); + local void write_table(FILE *, const z_crc_t FAR *, int); + local void write_table32hi(FILE *, const z_word_t FAR *, int); + local void write_table64(FILE *, const z_word_t FAR *, int); #endif /* MAKECRCH */ /* @@ -176,7 +214,6 @@ local void make_crc_table OF((void)); /* Definition of once functionality. */ typedef struct once_s once_t; -local void once OF((once_t *, void (*)(void))); /* Check for the availability of atomics. */ #if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ @@ -196,10 +233,7 @@ struct once_s { invoke once() at the same time. The state must be a once_t initialized with ONCE_INIT. */ -local void once(state, init) - once_t *state; - void (*init)(void); -{ +local void once(once_t *state, void (*init)(void)) { if (!atomic_load(&state->done)) { if (atomic_flag_test_and_set(&state->begun)) while (!atomic_load(&state->done)) @@ -222,10 +256,7 @@ struct once_s { /* Test and set. Alas, not atomic, but tries to minimize the period of vulnerability. */ -local int test_and_set OF((int volatile *)); -local int test_and_set(flag) - int volatile *flag; -{ +local int test_and_set(int volatile *flag) { int was; was = *flag; @@ -234,10 +265,7 @@ local int test_and_set(flag) } /* Run the provided init() function once. This is not thread-safe. */ -local void once(state, init) - once_t *state; - void (*init)(void); -{ +local void once(once_t *state, void (*init)(void)) { if (!state->done) { if (test_and_set(&state->begun)) while (!state->done) @@ -279,8 +307,7 @@ local once_t made = ONCE_INIT; combinations of CRC register values and incoming bytes. */ -local void make_crc_table() -{ +local void make_crc_table(void) { unsigned i, j, n; z_crc_t p; @@ -447,11 +474,7 @@ local void make_crc_table() Write the 32-bit values in table[0..k-1] to out, five per line in hexadecimal separated by commas. */ -local void write_table(out, table, k) - FILE *out; - const z_crc_t FAR *table; - int k; -{ +local void write_table(FILE *out, const z_crc_t FAR *table, int k) { int n; for (n = 0; n < k; n++) @@ -464,11 +487,7 @@ local void write_table(out, table, k) Write the high 32-bits of each value in table[0..k-1] to out, five per line in hexadecimal separated by commas. */ -local void write_table32hi(out, table, k) -FILE *out; -const z_word_t FAR *table; -int k; -{ +local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) { int n; for (n = 0; n < k; n++) @@ -484,11 +503,7 @@ int k; bits. If not, then the type cast and format string can be adjusted accordingly. */ -local void write_table64(out, table, k) - FILE *out; - const z_word_t FAR *table; - int k; -{ +local void write_table64(FILE *out, const z_word_t FAR *table, int k) { int n; for (n = 0; n < k; n++) @@ -498,8 +513,7 @@ local void write_table64(out, table, k) } /* Actually do the deed. */ -int main() -{ +int main(void) { make_crc_table(); return 0; } @@ -511,12 +525,7 @@ int main() Generate the little and big-endian braid tables for the given n and z_word_t size w. Each array must have room for w blocks of 256 elements. */ -local void braid(ltl, big, n, w) - z_crc_t ltl[][256]; - z_word_t big[][256]; - int n; - int w; -{ +local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) { int k; z_crc_t i, p, q; for (k = 0; k < w; k++) { @@ -531,69 +540,13 @@ local void braid(ltl, big, n, w) } #endif -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables for byte-wise and braided CRC-32 calculations, and a table of powers - * of x for combining CRC-32s, all made by make_crc_table(). - */ -#include "crc32.h" #endif /* DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Routines used for CRC calculation. Some are also required for the table - * generation above. - */ - -/* - Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, - reflected. For speed, this requires that a not be zero. - */ -local z_crc_t multmodp(a, b) - z_crc_t a; - z_crc_t b; -{ - z_crc_t m, p; - - m = (z_crc_t)1 << 31; - p = 0; - for (;;) { - if (a & m) { - p ^= b; - if ((a & (m - 1)) == 0) - break; - } - m >>= 1; - b = b & 1 ? (b >> 1) ^ POLY : b >> 1; - } - return p; -} - -/* - Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been - initialized. - */ -local z_crc_t x2nmodp(n, k) - z_off64_t n; - unsigned k; -{ - z_crc_t p; - - p = (z_crc_t)1 << 31; /* x^0 == 1 */ - while (n) { - if (n & 1) - p = multmodp(x2n_table[k & 31], p); - n >>= 1; - k++; - } - return p; -} - /* ========================================================================= * This function can be used by asm versions of crc32(), and to force the * generation of the CRC tables in a threaded application. */ -const z_crc_t FAR * ZEXPORT get_crc_table() -{ +const z_crc_t FAR * ZEXPORT get_crc_table(void) { #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ @@ -619,11 +572,8 @@ const z_crc_t FAR * ZEXPORT get_crc_table() #define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ #define Z_BATCH_MIN 800 /* fewest words in a final batch */ -unsigned long ZEXPORT crc32_z(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { z_crc_t val; z_word_t crc1, crc2; const z_word_t *word; @@ -723,18 +673,14 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) least-significant byte of the word as the first byte of data, without any pre or post conditioning. This is used to combine the CRCs of each braid. */ -local z_crc_t crc_word(data) - z_word_t data; -{ +local z_crc_t crc_word(z_word_t data) { int k; for (k = 0; k < W; k++) data = (data >> 8) ^ crc_table[data & 0xff]; return (z_crc_t)data; } -local z_word_t crc_word_big(data) - z_word_t data; -{ +local z_word_t crc_word_big(z_word_t data) { int k; for (k = 0; k < W; k++) data = (data << 8) ^ @@ -745,11 +691,8 @@ local z_word_t crc_word_big(data) #endif /* ========================================================================= */ -unsigned long ZEXPORT crc32_z(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { /* Return initial CRC, if requested. */ if (buf == Z_NULL) return 0; @@ -781,8 +724,8 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) words = (z_word_t const *)buf; /* Do endian check at execution time instead of compile time, since ARM - processors can change the endianess at execution time. If the - compiler knows what the endianess will be, it can optimize out the + processors can change the endianness at execution time. If the + compiler knows what the endianness will be, it can optimize out the check and the unused branch. */ endian = 1; if (*(unsigned char *)&endian) { @@ -1069,20 +1012,13 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) #endif /* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - uInt len; -{ +unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, + uInt len) { return crc32_z(crc, buf, len); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ +uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ @@ -1090,18 +1026,12 @@ uLong ZEXPORT crc32_combine64(crc1, crc2, len2) } /* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ +uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { return crc32_combine64(crc1, crc2, (z_off64_t)len2); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen64(len2) - z_off64_t len2; -{ +uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ @@ -1109,17 +1039,11 @@ uLong ZEXPORT crc32_combine_gen64(len2) } /* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen(len2) - z_off_t len2; -{ +uLong ZEXPORT crc32_combine_gen(z_off_t len2) { return crc32_combine_gen64((z_off64_t)len2); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine_op(crc1, crc2, op) - uLong crc1; - uLong crc2; - uLong op; -{ +uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { return multmodp(op, crc1) ^ (crc2 & 0xffffffff); } diff --git a/src/native/external/zlib/deflate.c b/src/native/external/zlib/deflate.c index b763663975458c..ca2fc59a1b54a8 100644 --- a/src/native/external/zlib/deflate.c +++ b/src/native/external/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.13 Copyright 1995-2022 Jean-loup Gailly and Mark Adler "; + " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -60,9 +60,6 @@ const char deflate_copyright[] = copyright string in the executable of your product. */ -/* =========================================================================== - * Function prototypes. - */ typedef enum { need_more, /* block not completed, need more input or more output */ block_done, /* block flush performed */ @@ -70,29 +67,16 @@ typedef enum { finish_done /* finish done, accept no more input or output */ } block_state; -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +typedef block_state (*compress_func)(deflate_state *s, int flush); /* Compression function. Returns the block state after the call. */ -local int deflateStateCheck OF((z_streamp strm)); -local void slide_hash OF((deflate_state *s)); -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); +local block_state deflate_stored(deflate_state *s, int flush); +local block_state deflate_fast(deflate_state *s, int flush); #ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local block_state deflate_rle OF((deflate_state *s, int flush)); -local block_state deflate_huff OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -local uInt longest_match OF((deflate_state *s, IPos cur_match)); - -#ifdef ZLIB_DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); +local block_state deflate_slow(deflate_state *s, int flush); #endif +local block_state deflate_rle(deflate_state *s, int flush); +local block_state deflate_huff(deflate_state *s, int flush); /* =========================================================================== * Local data @@ -195,9 +179,12 @@ local const config configuration_table[10] = { * bit values at the expense of memory usage). We slide even when level == 0 to * keep the hash table consistent if we switch back to level > 0 later. */ -local void slide_hash(s) - deflate_state *s; -{ +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) + __attribute__((no_sanitize("memory"))) +# endif +#endif +local void slide_hash(deflate_state *s) { unsigned n, m; Posf *p; uInt wsize = s->w_size; @@ -221,30 +208,177 @@ local void slide_hash(s) #endif } +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) { + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + strm->next_in += len; + strm->total_in += len; + + return len; +} + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(deflate_state *s) { + unsigned n; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize + MAX_DIST(s)) { + + zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + if (s->insert > s->strstart) + s->insert = s->strstart; + slide_hash(s); + more += wsize; + } + if (s->strm->avail_in == 0) break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + /* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ +int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, + int stream_size) { return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size); /* To do: ignore strm->next_in if we use it as window */ } /* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ +int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, int strategy, + const char *version, int stream_size) { deflate_state *s; int wrap = 1; static const char my_version[] = ZLIB_VERSION; @@ -359,7 +493,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, * symbols from which it is being constructed. */ - s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4); + s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS); s->pending_buf_size = (ulg)s->lit_bufsize * 4; if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || @@ -369,8 +503,14 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, deflateEnd (strm); return Z_MEM_ERROR; } +#ifdef LIT_MEM + s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); + s->l_buf = s->pending_buf + (s->lit_bufsize << 2); + s->sym_end = s->lit_bufsize - 1; +#else s->sym_buf = s->pending_buf + s->lit_bufsize; s->sym_end = (s->lit_bufsize - 1) * 3; +#endif /* We avoid equality with lit_bufsize*3 because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. @@ -386,9 +526,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, /* ========================================================================= * Check for a valid deflate stream state. Return 0 if ok, 1 if not. */ -local int deflateStateCheck(strm) - z_streamp strm; -{ +local int deflateStateCheck(z_streamp strm) { deflate_state *s; if (strm == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) @@ -409,11 +547,8 @@ local int deflateStateCheck(strm) } /* ========================================================================= */ -int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ +int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary, + uInt dictLength) { deflate_state *s; uInt str, n; int wrap; @@ -478,11 +613,8 @@ int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength) } /* ========================================================================= */ -int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength) - z_streamp strm; - Bytef *dictionary; - uInt *dictLength; -{ +int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary, + uInt *dictLength) { deflate_state *s; uInt len; @@ -500,9 +632,7 @@ int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength) } /* ========================================================================= */ -int ZEXPORT deflateResetKeep(strm) - z_streamp strm; -{ +int ZEXPORT deflateResetKeep(z_streamp strm) { deflate_state *s; if (deflateStateCheck(strm)) { @@ -537,10 +667,32 @@ int ZEXPORT deflateResetKeep(strm) return Z_OK; } +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init(deflate_state *s) { + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +} + /* ========================================================================= */ -int ZEXPORT deflateReset(strm) - z_streamp strm; -{ +int ZEXPORT deflateReset(z_streamp strm) { int ret; ret = deflateResetKeep(strm); @@ -550,10 +702,7 @@ int ZEXPORT deflateReset(strm) } /* ========================================================================= */ -int ZEXPORT deflateSetHeader(strm, head) - z_streamp strm; - gz_headerp head; -{ +int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) { if (deflateStateCheck(strm) || strm->state->wrap != 2) return Z_STREAM_ERROR; strm->state->gzhead = head; @@ -561,11 +710,7 @@ int ZEXPORT deflateSetHeader(strm, head) } /* ========================================================================= */ -int ZEXPORT deflatePending(strm, pending, bits) - unsigned *pending; - int *bits; - z_streamp strm; -{ +int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) { if (deflateStateCheck(strm)) return Z_STREAM_ERROR; if (pending != Z_NULL) *pending = strm->state->pending; @@ -575,19 +720,21 @@ int ZEXPORT deflatePending(strm, pending, bits) } /* ========================================================================= */ -int ZEXPORT deflatePrime(strm, bits, value) - z_streamp strm; - int bits; - int value; -{ +int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { deflate_state *s; int put; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; +#ifdef LIT_MEM + if (bits < 0 || bits > 16 || + (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#else if (bits < 0 || bits > 16 || s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) return Z_BUF_ERROR; +#endif do { put = Buf_size - s->bi_valid; if (put > bits) @@ -602,11 +749,7 @@ int ZEXPORT deflatePrime(strm, bits, value) } /* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ +int ZEXPORT deflateParams(z_streamp strm, int level, int strategy) { deflate_state *s; compress_func func; @@ -651,13 +794,8 @@ int ZEXPORT deflateParams(strm, level, strategy) } /* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ +int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, + int nice_length, int max_chain) { deflate_state *s; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -693,10 +831,7 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) * * Shifts are used to approximate divisions, for speed. */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ +uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { deflate_state *s; uLong fixedlen, storelen, wraplen; @@ -766,10 +901,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen) * IN assertion: the stream state is correct and there is enough room in * pending_buf. */ -local void putShortMSB(s, b) - deflate_state *s; - uInt b; -{ +local void putShortMSB(deflate_state *s, uInt b) { put_byte(s, (Byte)(b >> 8)); put_byte(s, (Byte)(b & 0xff)); } @@ -780,9 +912,7 @@ local void putShortMSB(s, b) * applications may wish to modify it to avoid allocating a large * strm->next_out buffer and copying into it. (See also read_buf()). */ -local void flush_pending(strm) - z_streamp strm; -{ +local void flush_pending(z_streamp strm) { unsigned len; deflate_state *s = strm->state; @@ -813,10 +943,7 @@ local void flush_pending(strm) } while (0) /* ========================================================================= */ -int ZEXPORT deflate(strm, flush) - z_streamp strm; - int flush; -{ +int ZEXPORT deflate(z_streamp strm, int flush) { int old_flush; /* value of flush param for previous deflate call */ deflate_state *s; @@ -1128,9 +1255,7 @@ int ZEXPORT deflate(strm, flush) } /* ========================================================================= */ -int ZEXPORT deflateEnd(strm) - z_streamp strm; -{ +int ZEXPORT deflateEnd(z_streamp strm) { int status; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1154,11 +1279,10 @@ int ZEXPORT deflateEnd(strm) * To simplify the source, this is not supported for 16-bit MSDOS (which * doesn't have enough memory anyway to duplicate compression states). */ -int ZEXPORT deflateCopy(dest, source) - z_streamp dest; - z_streamp source; -{ +int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { #ifdef MAXSEG_64K + (void)dest; + (void)source; return Z_STREAM_ERROR; #else deflate_state *ds; @@ -1182,7 +1306,7 @@ int ZEXPORT deflateCopy(dest, source) ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4); + ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { @@ -1193,10 +1317,15 @@ int ZEXPORT deflateCopy(dest, source) zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); +#ifdef LIT_MEM + ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); + ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); +#else ds->sym_buf = ds->pending_buf + ds->lit_bufsize; +#endif ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; @@ -1206,66 +1335,6 @@ int ZEXPORT deflateCopy(dest, source) #endif /* MAXSEG_64K */ } -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local unsigned read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, buf, len); - } -#endif - strm->next_in += len; - strm->total_in += len; - - return len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init(s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -} - #ifndef FASTEST /* =========================================================================== * Set match_start to the longest match starting at the given string and @@ -1276,10 +1345,7 @@ local void lm_init(s) * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 * OUT assertion: the match length is not greater than s->lookahead. */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ +local uInt longest_match(deflate_state *s, IPos cur_match) { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ @@ -1427,10 +1493,7 @@ local uInt longest_match(s, cur_match) /* --------------------------------------------------------------------------- * Optimized version for FASTEST only */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ +local uInt longest_match(deflate_state *s, IPos cur_match) { register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ @@ -1491,19 +1554,23 @@ local uInt longest_match(s, cur_match) /* =========================================================================== * Check that the match at match_start is indeed a match. */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ +local void check_match(deflate_state *s, IPos start, IPos match, int length) { /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); + Bytef *back = s->window + (int)match, *here = s->window + start; + IPos len = length; + if (match == (IPos)-1) { + /* match starts one byte before the current window -- just compare the + subsequent length-1 bytes */ + back++; + here++; + len--; + } + if (zmemcmp(back, here, len) != EQUAL) { + fprintf(stderr, " start %u, match %d, length %d\n", + start, (int)match, length); do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); + fprintf(stderr, "(%02x %02x)", *back++, *here++); + } while (--len != 0); z_error("invalid match"); } if (z_verbose > 1) { @@ -1515,137 +1582,6 @@ local void check_match(s, start, match, length) # define check_match(s, start, match, length) #endif /* ZLIB_DEBUG */ -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - unsigned n; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize + MAX_DIST(s)) { - - zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - if (s->insert > s->strstart) - s->insert = s->strstart; - slide_hash(s); - more += wsize; - } - if (s->strm->avail_in == 0) break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - uInt str = s->strstart - s->insert; - s->ins_h = s->window[str]; - UPDATE_HASH(s, s->ins_h, s->window[str + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); -} - /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. @@ -1688,10 +1624,7 @@ local void fill_window(s) * copied. It is most efficient with large input and output buffers, which * maximizes the opportunities to have a single copy from next_in to next_out. */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_stored(deflate_state *s, int flush) { /* Smallest worthy block size when not flushing or finishing. By default * this is 32K. This can be as small as 507 bytes for memLevel == 1. For * large input and output buffers, the stored block size will be larger. @@ -1875,10 +1808,7 @@ local block_state deflate_stored(s, flush) * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_fast(deflate_state *s, int flush) { IPos hash_head; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ @@ -1977,10 +1907,7 @@ local block_state deflate_fast(s, flush) * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_slow(deflate_state *s, int flush) { IPos hash_head; /* head of hash chain */ int bflush; /* set if current block must be flushed */ @@ -2108,10 +2035,7 @@ local block_state deflate_slow(s, flush) * one. Do not maintain a hash table. (It will be regenerated if this run of * deflate switches away from Z_RLE.) */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_rle(deflate_state *s, int flush) { int bflush; /* set if current block must be flushed */ uInt prev; /* byte at distance one to match */ Bytef *scan, *strend; /* scan goes up to strend for length of run */ @@ -2182,10 +2106,7 @@ local block_state deflate_rle(s, flush) * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. * (It will be regenerated if this run of deflate switches away from Huffman.) */ -local block_state deflate_huff(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_huff(deflate_state *s, int flush) { int bflush; /* set if current block must be flushed */ for (;;) { diff --git a/src/native/external/zlib/deflate.h b/src/native/external/zlib/deflate.h index 1a06cd5f25d107..300c6ada62b82e 100644 --- a/src/native/external/zlib/deflate.h +++ b/src/native/external/zlib/deflate.h @@ -1,5 +1,5 @@ /* deflate.h -- internal compression state - * Copyright (C) 1995-2018 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -23,6 +23,10 @@ # define GZIP #endif +/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at + the cost of a larger memory footprint */ +/* #define LIT_MEM */ + /* =========================================================================== * Internal compression state. */ @@ -217,7 +221,14 @@ typedef struct internal_state { /* Depth of each subtree used as tie breaker for trees of equal frequency */ +#ifdef LIT_MEM +# define LIT_BUFS 5 + ushf *d_buf; /* buffer for distances */ + uchf *l_buf; /* buffer for literals/lengths */ +#else +# define LIT_BUFS 4 uchf *sym_buf; /* buffer for distances and literals/lengths */ +#endif uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for @@ -239,7 +250,7 @@ typedef struct internal_state { * - I can't count above 4 */ - uInt sym_next; /* running index in sym_buf */ + uInt sym_next; /* running index in symbol buffer */ uInt sym_end; /* symbol table full when sym_next reaches this */ ulg opt_len; /* bit length of current block with optimal trees */ @@ -291,14 +302,14 @@ typedef struct internal_state { memory checker errors from longest match routines */ /* in trees.c */ -void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); -int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); -void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_init(deflate_state *s); +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc); +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, + ulg stored_len, int last); +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s); +void ZLIB_INTERNAL _tr_align(deflate_state *s); +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, + ulg stored_len, int last); #define d_code(dist) \ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) @@ -318,6 +329,25 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, extern const uch ZLIB_INTERNAL _dist_code[]; #endif +#ifdef LIT_MEM +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->sym_next] = 0; \ + s->l_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->d_buf[s->sym_next] = dist; \ + s->l_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#else # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->sym_buf[s->sym_next++] = 0; \ @@ -337,6 +367,7 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->sym_next == s->sym_end); \ } +#endif #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ diff --git a/src/native/external/zlib/gzclose.c b/src/native/external/zlib/gzclose.c index caeb99a3177f47..48d6a86f04b6ea 100644 --- a/src/native/external/zlib/gzclose.c +++ b/src/native/external/zlib/gzclose.c @@ -8,9 +8,7 @@ /* gzclose() is in a separate file so that it is linked in only if it is used. That way the other gzclose functions can be used instead to avoid linking in unneeded compression or decompression routines. */ -int ZEXPORT gzclose(file) - gzFile file; -{ +int ZEXPORT gzclose(gzFile file) { #ifndef NO_GZCOMPRESS gz_statep state; diff --git a/src/native/external/zlib/gzguts.h b/src/native/external/zlib/gzguts.h index 57faf37165a354..eba72085bb756b 100644 --- a/src/native/external/zlib/gzguts.h +++ b/src/native/external/zlib/gzguts.h @@ -1,5 +1,5 @@ /* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -7,9 +7,8 @@ # ifndef _LARGEFILE_SOURCE # define _LARGEFILE_SOURCE 1 # endif -# ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -# endif +# undef _FILE_OFFSET_BITS +# undef _TIME_BITS #endif #ifdef HAVE_HIDDEN @@ -119,8 +118,8 @@ /* gz* functions always use library allocation functions */ #ifndef STDC - extern voidp malloc OF((uInt size)); - extern void free OF((voidpf ptr)); + extern voidp malloc(uInt size); + extern void free(voidpf ptr); #endif /* get errno and strerror definition */ @@ -138,10 +137,10 @@ /* provide prototypes for these when building zlib without LFS */ #if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); #endif /* default memLevel */ @@ -203,17 +202,13 @@ typedef struct { typedef gz_state FAR *gz_statep; /* shared functions */ -void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +void ZLIB_INTERNAL gz_error(gz_statep, int, const char *); #if defined UNDER_CE -char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +char ZLIB_INTERNAL *gz_strwinerror(DWORD error); #endif /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t value -- needed when comparing unsigned to z_off64_t, which is signed (possible z_off64_t types off_t, off64_t, and long are all signed) */ -#ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) -#else -unsigned ZLIB_INTERNAL gz_intmax OF((void)); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif +unsigned ZLIB_INTERNAL gz_intmax(void); +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) diff --git a/src/native/external/zlib/gzlib.c b/src/native/external/zlib/gzlib.c index 55da46a453fd18..983153cc8e4965 100644 --- a/src/native/external/zlib/gzlib.c +++ b/src/native/external/zlib/gzlib.c @@ -1,5 +1,5 @@ /* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -15,10 +15,6 @@ #endif #endif -/* Local functions */ -local void gz_reset OF((gz_statep)); -local gzFile gz_open OF((const void *, int, const char *)); - #if defined UNDER_CE /* Map the Windows error number in ERROR to a locale-dependent error message @@ -30,9 +26,7 @@ local gzFile gz_open OF((const void *, int, const char *)); The gz_strwinerror function does not change the current setting of GetLastError. */ -char ZLIB_INTERNAL *gz_strwinerror(error) - DWORD error; -{ +char ZLIB_INTERNAL *gz_strwinerror(DWORD error) { static char buf[1024]; wchar_t *msgbuf; @@ -72,9 +66,7 @@ char ZLIB_INTERNAL *gz_strwinerror(error) #endif /* UNDER_CE */ /* Reset gzip file state */ -local void gz_reset(state) - gz_statep state; -{ +local void gz_reset(gz_statep state) { state->x.have = 0; /* no output data available */ if (state->mode == GZ_READ) { /* for reading ... */ state->eof = 0; /* not at end of file */ @@ -90,11 +82,7 @@ local void gz_reset(state) } /* Open a gzip file either by name or file descriptor. */ -local gzFile gz_open(path, fd, mode) - const void *path; - int fd; - const char *mode; -{ +local gzFile gz_open(const void *path, int fd, const char *mode) { gz_statep state; z_size_t len; int oflag; @@ -269,26 +257,17 @@ local gzFile gz_open(path, fd, mode) } /* -- see zlib.h -- */ -gzFile ZEXPORT gzopen(path, mode) - const char *path; - const char *mode; -{ +gzFile ZEXPORT gzopen(const char *path, const char *mode) { return gz_open(path, -1, mode); } /* -- see zlib.h -- */ -gzFile ZEXPORT gzopen64(path, mode) - const char *path; - const char *mode; -{ +gzFile ZEXPORT gzopen64(const char *path, const char *mode) { return gz_open(path, -1, mode); } /* -- see zlib.h -- */ -gzFile ZEXPORT gzdopen(fd, mode) - int fd; - const char *mode; -{ +gzFile ZEXPORT gzdopen(int fd, const char *mode) { char *path; /* identifier for error messages */ gzFile gz; @@ -306,19 +285,13 @@ gzFile ZEXPORT gzdopen(fd, mode) /* -- see zlib.h -- */ #ifdef WIDECHAR -gzFile ZEXPORT gzopen_w(path, mode) - const wchar_t *path; - const char *mode; -{ +gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) { return gz_open(path, -2, mode); } #endif /* -- see zlib.h -- */ -int ZEXPORT gzbuffer(file, size) - gzFile file; - unsigned size; -{ +int ZEXPORT gzbuffer(gzFile file, unsigned size) { gz_statep state; /* get internal structure and check integrity */ @@ -335,16 +308,14 @@ int ZEXPORT gzbuffer(file, size) /* check and set requested size */ if ((size << 1) < size) return -1; /* need to be able to double it */ - if (size < 2) - size = 2; /* need two bytes to check magic header */ + if (size < 8) + size = 8; /* needed to behave well with flushing */ state->want = size; return 0; } /* -- see zlib.h -- */ -int ZEXPORT gzrewind(file) - gzFile file; -{ +int ZEXPORT gzrewind(gzFile file) { gz_statep state; /* get internal structure */ @@ -365,11 +336,7 @@ int ZEXPORT gzrewind(file) } /* -- see zlib.h -- */ -z_off64_t ZEXPORT gzseek64(file, offset, whence) - gzFile file; - z_off64_t offset; - int whence; -{ +z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { unsigned n; z_off64_t ret; gz_statep state; @@ -442,11 +409,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) } /* -- see zlib.h -- */ -z_off_t ZEXPORT gzseek(file, offset, whence) - gzFile file; - z_off_t offset; - int whence; -{ +z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) { z_off64_t ret; ret = gzseek64(file, (z_off64_t)offset, whence); @@ -454,9 +417,7 @@ z_off_t ZEXPORT gzseek(file, offset, whence) } /* -- see zlib.h -- */ -z_off64_t ZEXPORT gztell64(file) - gzFile file; -{ +z_off64_t ZEXPORT gztell64(gzFile file) { gz_statep state; /* get internal structure and check integrity */ @@ -471,9 +432,7 @@ z_off64_t ZEXPORT gztell64(file) } /* -- see zlib.h -- */ -z_off_t ZEXPORT gztell(file) - gzFile file; -{ +z_off_t ZEXPORT gztell(gzFile file) { z_off64_t ret; ret = gztell64(file); @@ -481,9 +440,7 @@ z_off_t ZEXPORT gztell(file) } /* -- see zlib.h -- */ -z_off64_t ZEXPORT gzoffset64(file) - gzFile file; -{ +z_off64_t ZEXPORT gzoffset64(gzFile file) { z_off64_t offset; gz_statep state; @@ -504,9 +461,7 @@ z_off64_t ZEXPORT gzoffset64(file) } /* -- see zlib.h -- */ -z_off_t ZEXPORT gzoffset(file) - gzFile file; -{ +z_off_t ZEXPORT gzoffset(gzFile file) { z_off64_t ret; ret = gzoffset64(file); @@ -514,9 +469,7 @@ z_off_t ZEXPORT gzoffset(file) } /* -- see zlib.h -- */ -int ZEXPORT gzeof(file) - gzFile file; -{ +int ZEXPORT gzeof(gzFile file) { gz_statep state; /* get internal structure and check integrity */ @@ -531,10 +484,7 @@ int ZEXPORT gzeof(file) } /* -- see zlib.h -- */ -const char * ZEXPORT gzerror(file, errnum) - gzFile file; - int *errnum; -{ +const char * ZEXPORT gzerror(gzFile file, int *errnum) { gz_statep state; /* get internal structure and check integrity */ @@ -552,9 +502,7 @@ const char * ZEXPORT gzerror(file, errnum) } /* -- see zlib.h -- */ -void ZEXPORT gzclearerr(file) - gzFile file; -{ +void ZEXPORT gzclearerr(gzFile file) { gz_statep state; /* get internal structure and check integrity */ @@ -578,11 +526,7 @@ void ZEXPORT gzclearerr(file) memory). Simply save the error message as a static string. If there is an allocation failure constructing the error message, then convert the error to out of memory. */ -void ZLIB_INTERNAL gz_error(state, err, msg) - gz_statep state; - int err; - const char *msg; -{ +void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { /* free previously allocated message and clear */ if (state->msg != NULL) { if (state->err != Z_MEM_ERROR) @@ -619,21 +563,20 @@ void ZLIB_INTERNAL gz_error(state, err, msg) #endif } -#ifndef INT_MAX /* portably return maximum value for an int (when limits.h presumed not available) -- we need to do this to cover cases where 2's complement not used, since C standard permits 1's complement and sign-bit representations, otherwise we could just use ((unsigned)-1) >> 1 */ -unsigned ZLIB_INTERNAL gz_intmax() -{ - unsigned p, q; - - p = 1; +unsigned ZLIB_INTERNAL gz_intmax(void) { +#ifdef INT_MAX + return INT_MAX; +#else + unsigned p = 1, q; do { q = p; p <<= 1; p++; } while (p > q); return q >> 1; -} #endif +} diff --git a/src/native/external/zlib/gzread.c b/src/native/external/zlib/gzread.c index dd77381596cbc0..4168cbc88752e1 100644 --- a/src/native/external/zlib/gzread.c +++ b/src/native/external/zlib/gzread.c @@ -5,25 +5,12 @@ #include "gzguts.h" -/* Local functions */ -local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); -local int gz_avail OF((gz_statep)); -local int gz_look OF((gz_statep)); -local int gz_decomp OF((gz_statep)); -local int gz_fetch OF((gz_statep)); -local int gz_skip OF((gz_statep, z_off64_t)); -local z_size_t gz_read OF((gz_statep, voidp, z_size_t)); - /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from state->fd, and update state->eof, state->err, and state->msg as appropriate. This function needs to loop on read(), since read() is not guaranteed to read the number of bytes requested, depending on the type of descriptor. */ -local int gz_load(state, buf, len, have) - gz_statep state; - unsigned char *buf; - unsigned len; - unsigned *have; -{ +local int gz_load(gz_statep state, unsigned char *buf, unsigned len, + unsigned *have) { int ret; unsigned get, max = ((unsigned)-1 >> 2) + 1; @@ -53,9 +40,7 @@ local int gz_load(state, buf, len, have) If strm->avail_in != 0, then the current data is moved to the beginning of the input buffer, and then the remainder of the buffer is loaded with the available data from the input file. */ -local int gz_avail(state) - gz_statep state; -{ +local int gz_avail(gz_statep state) { unsigned got; z_streamp strm = &(state->strm); @@ -88,9 +73,7 @@ local int gz_avail(state) case, all further file reads will be directly to either the output buffer or a user buffer. If decompressing, the inflate state will be initialized. gz_look() will return 0 on success or -1 on failure. */ -local int gz_look(state) - gz_statep state; -{ +local int gz_look(gz_statep state) { z_streamp strm = &(state->strm); /* allocate read buffers and inflate memory */ @@ -170,9 +153,7 @@ local int gz_look(state) data. If the gzip stream completes, state->how is reset to LOOK to look for the next gzip stream or raw data, once state->x.have is depleted. Returns 0 on success, -1 on failure. */ -local int gz_decomp(state) - gz_statep state; -{ +local int gz_decomp(gz_statep state) { int ret = Z_OK; unsigned had; z_streamp strm = &(state->strm); @@ -224,9 +205,7 @@ local int gz_decomp(state) looked for to determine whether to copy or decompress. Returns -1 on error, otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the end of the input file has been reached and all data has been processed. */ -local int gz_fetch(state) - gz_statep state; -{ +local int gz_fetch(gz_statep state) { z_streamp strm = &(state->strm); do { @@ -254,10 +233,7 @@ local int gz_fetch(state) } /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ -local int gz_skip(state, len) - gz_statep state; - z_off64_t len; -{ +local int gz_skip(gz_statep state, z_off64_t len) { unsigned n; /* skip over len bytes or reach end-of-file, whichever comes first */ @@ -289,11 +265,7 @@ local int gz_skip(state, len) input. Return the number of bytes read. If zero is returned, either the end of file was reached, or there was an error. state->err must be consulted in that case to determine which. */ -local z_size_t gz_read(state, buf, len) - gz_statep state; - voidp buf; - z_size_t len; -{ +local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { z_size_t got; unsigned n; @@ -370,11 +342,7 @@ local z_size_t gz_read(state, buf, len) } /* -- see zlib.h -- */ -int ZEXPORT gzread(file, buf, len) - gzFile file; - voidp buf; - unsigned len; -{ +int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { gz_statep state; /* get internal structure */ @@ -406,12 +374,7 @@ int ZEXPORT gzread(file, buf, len) } /* -- see zlib.h -- */ -z_size_t ZEXPORT gzfread(buf, size, nitems, file) - voidp buf; - z_size_t size; - z_size_t nitems; - gzFile file; -{ +z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) { z_size_t len; gz_statep state; @@ -442,9 +405,7 @@ z_size_t ZEXPORT gzfread(buf, size, nitems, file) #else # undef gzgetc #endif -int ZEXPORT gzgetc(file) - gzFile file; -{ +int ZEXPORT gzgetc(gzFile file) { unsigned char buf[1]; gz_statep state; @@ -469,17 +430,12 @@ int ZEXPORT gzgetc(file) return gz_read(state, buf, 1) < 1 ? -1 : buf[0]; } -int ZEXPORT gzgetc_(file) -gzFile file; -{ +int ZEXPORT gzgetc_(gzFile file) { return gzgetc(file); } /* -- see zlib.h -- */ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; -{ +int ZEXPORT gzungetc(int c, gzFile file) { gz_statep state; /* get internal structure */ @@ -487,6 +443,10 @@ int ZEXPORT gzungetc(c, file) return -1; state = (gz_statep)file; + /* in case this was just opened, set up the input buffer */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + /* check that we're reading and that there's no (serious) error */ if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) @@ -536,11 +496,7 @@ int ZEXPORT gzungetc(c, file) } /* -- see zlib.h -- */ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ +char * ZEXPORT gzgets(gzFile file, char *buf, int len) { unsigned left, n; char *str; unsigned char *eol; @@ -600,9 +556,7 @@ char * ZEXPORT gzgets(file, buf, len) } /* -- see zlib.h -- */ -int ZEXPORT gzdirect(file) - gzFile file; -{ +int ZEXPORT gzdirect(gzFile file) { gz_statep state; /* get internal structure */ @@ -620,9 +574,7 @@ int ZEXPORT gzdirect(file) } /* -- see zlib.h -- */ -int ZEXPORT gzclose_r(file) - gzFile file; -{ +int ZEXPORT gzclose_r(gzFile file) { int ret, err; gz_statep state; diff --git a/src/native/external/zlib/gzwrite.c b/src/native/external/zlib/gzwrite.c index eb8a0e5893ff6a..435b4621b5349f 100644 --- a/src/native/external/zlib/gzwrite.c +++ b/src/native/external/zlib/gzwrite.c @@ -5,18 +5,10 @@ #include "gzguts.h" -/* Local functions */ -local int gz_init OF((gz_statep)); -local int gz_comp OF((gz_statep, int)); -local int gz_zero OF((gz_statep, z_off64_t)); -local z_size_t gz_write OF((gz_statep, voidpc, z_size_t)); - /* Initialize state for writing a gzip file. Mark initialization by setting state->size to non-zero. Return -1 on a memory allocation failure, or 0 on success. */ -local int gz_init(state) - gz_statep state; -{ +local int gz_init(gz_statep state) { int ret; z_streamp strm = &(state->strm); @@ -70,10 +62,7 @@ local int gz_init(state) deflate() flush value. If flush is Z_FINISH, then the deflate() state is reset to start a new gzip stream. If gz->direct is true, then simply write to the output file without compressing, and ignore flush. */ -local int gz_comp(state, flush) - gz_statep state; - int flush; -{ +local int gz_comp(gz_statep state, int flush) { int ret, writ; unsigned have, put, max = ((unsigned)-1 >> 2) + 1; z_streamp strm = &(state->strm); @@ -151,10 +140,7 @@ local int gz_comp(state, flush) /* Compress len zeros to output. Return -1 on a write error or memory allocation failure by gz_comp(), or 0 on success. */ -local int gz_zero(state, len) - gz_statep state; - z_off64_t len; -{ +local int gz_zero(gz_statep state, z_off64_t len) { int first; unsigned n; z_streamp strm = &(state->strm); @@ -184,11 +170,7 @@ local int gz_zero(state, len) /* Write len bytes from buf to file. Return the number of bytes written. If the returned value is less than len, then there was an error. */ -local z_size_t gz_write(state, buf, len) - gz_statep state; - voidpc buf; - z_size_t len; -{ +local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { z_size_t put = len; /* if len is zero, avoid unnecessary operations */ @@ -252,11 +234,7 @@ local z_size_t gz_write(state, buf, len) } /* -- see zlib.h -- */ -int ZEXPORT gzwrite(file, buf, len) - gzFile file; - voidpc buf; - unsigned len; -{ +int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) { gz_statep state; /* get internal structure */ @@ -280,12 +258,8 @@ int ZEXPORT gzwrite(file, buf, len) } /* -- see zlib.h -- */ -z_size_t ZEXPORT gzfwrite(buf, size, nitems, file) - voidpc buf; - z_size_t size; - z_size_t nitems; - gzFile file; -{ +z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems, + gzFile file) { z_size_t len; gz_statep state; @@ -310,10 +284,7 @@ z_size_t ZEXPORT gzfwrite(buf, size, nitems, file) } /* -- see zlib.h -- */ -int ZEXPORT gzputc(file, c) - gzFile file; - int c; -{ +int ZEXPORT gzputc(gzFile file, int c) { unsigned have; unsigned char buf[1]; gz_statep state; @@ -358,10 +329,7 @@ int ZEXPORT gzputc(file, c) } /* -- see zlib.h -- */ -int ZEXPORT gzputs(file, s) - gzFile file; - const char *s; -{ +int ZEXPORT gzputs(gzFile file, const char *s) { z_size_t len, put; gz_statep state; @@ -388,8 +356,7 @@ int ZEXPORT gzputs(file, s) #include /* -- see zlib.h -- */ -int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) -{ +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { int len; unsigned left; char *next; @@ -460,8 +427,7 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) return len; } -int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) -{ +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { va_list va; int ret; @@ -474,13 +440,10 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) #else /* !STDC && !Z_HAVE_STDARG_H */ /* -- see zlib.h -- */ -int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; -{ +int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, + int a4, int a5, int a6, int a7, int a8, int a9, int a10, + int a11, int a12, int a13, int a14, int a15, int a16, + int a17, int a18, int a19, int a20) { unsigned len, left; char *next; gz_statep state; @@ -562,10 +525,7 @@ int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, #endif /* -- see zlib.h -- */ -int ZEXPORT gzflush(file, flush) - gzFile file; - int flush; -{ +int ZEXPORT gzflush(gzFile file, int flush) { gz_statep state; /* get internal structure */ @@ -594,11 +554,7 @@ int ZEXPORT gzflush(file, flush) } /* -- see zlib.h -- */ -int ZEXPORT gzsetparams(file, level, strategy) - gzFile file; - int level; - int strategy; -{ +int ZEXPORT gzsetparams(gzFile file, int level, int strategy) { gz_statep state; z_streamp strm; @@ -609,7 +565,7 @@ int ZEXPORT gzsetparams(file, level, strategy) strm = &(state->strm); /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) return Z_STREAM_ERROR; /* if no change is requested, then do nothing */ @@ -636,9 +592,7 @@ int ZEXPORT gzsetparams(file, level, strategy) } /* -- see zlib.h -- */ -int ZEXPORT gzclose_w(file) - gzFile file; -{ +int ZEXPORT gzclose_w(gzFile file) { int ret = Z_OK; gz_statep state; diff --git a/src/native/external/zlib/infback.c b/src/native/external/zlib/infback.c index babeaf1806f98f..e7b25b307a3072 100644 --- a/src/native/external/zlib/infback.c +++ b/src/native/external/zlib/infback.c @@ -15,9 +15,6 @@ #include "inflate.h" #include "inffast.h" -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - /* strm provides memory allocation functions in zalloc and zfree, or Z_NULL to use the library memory allocation functions. @@ -25,13 +22,9 @@ local void fixedtables OF((struct inflate_state FAR *state)); windowBits is in the range 8..15, and window is a user-supplied window and output buffer that is 2**windowBits bytes. */ -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_streamp strm; -int windowBits; -unsigned char FAR *window; -const char *version; -int stream_size; -{ +int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, const char *version, + int stream_size) { struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || @@ -80,9 +73,7 @@ int stream_size; used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ +local void fixedtables(struct inflate_state FAR *state) { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; @@ -248,13 +239,8 @@ struct inflate_state FAR *state; inflateBack() can also return Z_STREAM_ERROR if the input parameters are not correct, i.e. strm is Z_NULL or the state was not initialized. */ -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_streamp strm; -in_func in; -void FAR *in_desc; -out_func out; -void FAR *out_desc; -{ +int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc) { struct inflate_state FAR *state; z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ @@ -632,9 +618,7 @@ void FAR *out_desc; return ret; } -int ZEXPORT inflateBackEnd(strm) -z_streamp strm; -{ +int ZEXPORT inflateBackEnd(z_streamp strm) { if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; ZFREE(strm, strm->state); diff --git a/src/native/external/zlib/inffast.c b/src/native/external/zlib/inffast.c index 1fec7f363fa665..9354676e786ee7 100644 --- a/src/native/external/zlib/inffast.c +++ b/src/native/external/zlib/inffast.c @@ -47,10 +47,7 @@ requires strm->avail_out >= 258 for each loop to avoid checking for output space. */ -void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { struct inflate_state FAR *state; z_const unsigned char FAR *in; /* local strm->next_in */ z_const unsigned char FAR *last; /* have enough input while in < last */ diff --git a/src/native/external/zlib/inffast.h b/src/native/external/zlib/inffast.h index e5c1aa4ca8cd52..49c6d156c5c652 100644 --- a/src/native/external/zlib/inffast.h +++ b/src/native/external/zlib/inffast.h @@ -8,4 +8,4 @@ subject to change. Applications should only use zlib.h. */ -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start); diff --git a/src/native/external/zlib/inflate.c b/src/native/external/zlib/inflate.c index 8acbef44e993ba..94ecff015a9be7 100644 --- a/src/native/external/zlib/inflate.c +++ b/src/native/external/zlib/inflate.c @@ -91,20 +91,7 @@ # endif #endif -/* function prototypes */ -local int inflateStateCheck OF((z_streamp strm)); -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, - unsigned copy)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, - unsigned len)); - -local int inflateStateCheck(strm) -z_streamp strm; -{ +local int inflateStateCheck(z_streamp strm) { struct inflate_state FAR *state; if (strm == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) @@ -116,9 +103,7 @@ z_streamp strm; return 0; } -int ZEXPORT inflateResetKeep(strm) -z_streamp strm; -{ +int ZEXPORT inflateResetKeep(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -142,9 +127,7 @@ z_streamp strm; return Z_OK; } -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ +int ZEXPORT inflateReset(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -155,10 +138,7 @@ z_streamp strm; return inflateResetKeep(strm); } -int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; -int windowBits; -{ +int ZEXPORT inflateReset2(z_streamp strm, int windowBits) { int wrap; struct inflate_state FAR *state; @@ -195,12 +175,8 @@ int windowBits; return inflateReset(strm); } -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ +int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size) { int ret; struct inflate_state FAR *state; @@ -239,22 +215,17 @@ int stream_size; return ret; } -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ +int ZEXPORT inflateInit_(z_streamp strm, const char *version, + int stream_size) { return inflateInit2_(strm, DEF_WBITS, version, stream_size); } -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ +int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (bits == 0) + return Z_OK; state = (struct inflate_state FAR *)strm->state; if (bits < 0) { state->hold = 0; @@ -278,9 +249,7 @@ int value; used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ +local void fixedtables(struct inflate_state FAR *state) { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; @@ -342,7 +311,7 @@ struct inflate_state FAR *state; a.out > inffixed.h */ -void makefixed() +void makefixed(void) { unsigned low, size; struct inflate_state state; @@ -396,11 +365,7 @@ void makefixed() output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ -local int updatewindow(strm, end, copy) -z_streamp strm; -const Bytef *end; -unsigned copy; -{ +local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) { struct inflate_state FAR *state; unsigned dist; @@ -622,10 +587,7 @@ unsigned copy; will return Z_BUF_ERROR if it has not reached the end of the stream. */ -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ +int ZEXPORT inflate(z_streamp strm, int flush) { struct inflate_state FAR *state; z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ @@ -1301,9 +1263,7 @@ int flush; return ret; } -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ +int ZEXPORT inflateEnd(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1315,11 +1275,8 @@ z_streamp strm; return Z_OK; } -int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) -z_streamp strm; -Bytef *dictionary; -uInt *dictLength; -{ +int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, + uInt *dictLength) { struct inflate_state FAR *state; /* check state */ @@ -1338,11 +1295,8 @@ uInt *dictLength; return Z_OK; } -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ +int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, + uInt dictLength) { struct inflate_state FAR *state; unsigned long dictid; int ret; @@ -1373,10 +1327,7 @@ uInt dictLength; return Z_OK; } -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ +int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) { struct inflate_state FAR *state; /* check state */ @@ -1401,11 +1352,8 @@ gz_headerp head; called again with more data and the *have state. *have is initialized to zero for the first call. */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -const unsigned char FAR *buf; -unsigned len; -{ +local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, + unsigned len) { unsigned got; unsigned next; @@ -1424,9 +1372,7 @@ unsigned len; return next; } -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ +int ZEXPORT inflateSync(z_streamp strm) { unsigned len; /* number of bytes to look at or looked at */ int flags; /* temporary to save header status */ unsigned long in, out; /* temporary to save total_in and total_out */ @@ -1441,7 +1387,7 @@ z_streamp strm; /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; - state->hold <<= state->bits & 7; + state->hold >>= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { @@ -1482,9 +1428,7 @@ z_streamp strm; block. When decompressing, PPP checks that at the end of input packet, inflate is waiting for these length bytes. */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ +int ZEXPORT inflateSyncPoint(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1492,10 +1436,7 @@ z_streamp strm; return state->mode == STORED && state->bits == 0; } -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ +int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { struct inflate_state FAR *state; struct inflate_state FAR *copy; unsigned char FAR *window; @@ -1539,10 +1480,7 @@ z_streamp source; return Z_OK; } -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ +int ZEXPORT inflateUndermine(z_streamp strm, int subvert) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1557,10 +1495,7 @@ int subvert; #endif } -int ZEXPORT inflateValidate(strm, check) -z_streamp strm; -int check; -{ +int ZEXPORT inflateValidate(z_streamp strm, int check) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1572,9 +1507,7 @@ int check; return Z_OK; } -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ +long ZEXPORT inflateMark(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) @@ -1585,9 +1518,7 @@ z_streamp strm; (state->mode == MATCH ? state->was - state->length : 0)); } -unsigned long ZEXPORT inflateCodesUsed(strm) -z_streamp strm; -{ +unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return (unsigned long)-1; state = (struct inflate_state FAR *)strm->state; diff --git a/src/native/external/zlib/inftrees.c b/src/native/external/zlib/inftrees.c index 57d2793bec931f..98cfe164458c40 100644 --- a/src/native/external/zlib/inftrees.c +++ b/src/native/external/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2022 Mark Adler + * Copyright (C) 1995-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.13 Copyright 1995-2022 Mark Adler "; + " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -29,14 +29,9 @@ const char inflate_copyright[] = table index bits. It will differ if the request is greater than the longest code or if it is less than the shortest code. */ -int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work) { unsigned len; /* a code's length in bits */ unsigned sym; /* index of code symbols */ unsigned min, max; /* minimum and maximum code lengths */ @@ -62,7 +57,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 194, 65}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/src/native/external/zlib/inftrees.h b/src/native/external/zlib/inftrees.h index f53665311c1624..396f74b5da798a 100644 --- a/src/native/external/zlib/inftrees.h +++ b/src/native/external/zlib/inftrees.h @@ -41,8 +41,8 @@ typedef struct { examples/enough.c found in the zlib distribution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the + returns 852, and "enough 30 6 15" for distance codes returns 592. The + initial root table size (9 or 6) is found in the fifth argument of the inflate_table() calls in inflate.c and infback.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ @@ -57,6 +57,6 @@ typedef enum { DISTS } codetype; -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work); diff --git a/src/native/external/zlib/treebuild.xml b/src/native/external/zlib/treebuild.xml index 0017a45d3c5cbf..930b00be4a853a 100644 --- a/src/native/external/zlib/treebuild.xml +++ b/src/native/external/zlib/treebuild.xml @@ -1,6 +1,6 @@ - - + + zip compression library diff --git a/src/native/external/zlib/trees.c b/src/native/external/zlib/trees.c index 8a3eec559e55bc..979ae4100a02e0 100644 --- a/src/native/external/zlib/trees.c +++ b/src/native/external/zlib/trees.c @@ -1,5 +1,5 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2021 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -122,39 +122,116 @@ struct static_tree_desc_s { int max_length; /* max bit length for the codes */ }; -local const static_tree_desc static_l_desc = +#ifdef NO_INIT_GLOBAL_POINTERS +# define TCONST +#else +# define TCONST const +#endif + +local TCONST static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; -local const static_tree_desc static_d_desc = +local TCONST static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; -local const static_tree_desc static_bl_desc = +local TCONST static_tree_desc static_bl_desc = {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== - * Local (static) routines in this file. + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 */ +local unsigned bi_reverse(unsigned code, int len) { + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, const ct_data *ltree, - const ct_data *dtree)); -local int detect_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned code, int len)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(deflate_state *s) { + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(deflate_state *s) { + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->bits_sent = (s->bits_sent + 7) & ~7; +#endif +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) { + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + unsigned code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits - 1]) << 1; + next_code[bits] = (ush)code; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, + "inconsistent bit counts"); + Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) continue; + /* Now reverse the bits */ + tree[n].Code = (ush)bi_reverse(next_code[len]++, len); + + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); + } +} #ifdef GEN_TREES_H -local void gen_trees_header OF((void)); +local void gen_trees_header(void); #endif #ifndef ZLIB_DEBUG @@ -167,27 +244,12 @@ local void gen_trees_header OF((void)); send_bits(s, tree[c].Code, tree[c].Len); } #endif -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ #ifdef ZLIB_DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ +local void send_bits(deflate_state *s, int value, int length) { Tracevv((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); s->bits_sent += (ulg)length; @@ -229,8 +291,7 @@ local void send_bits(s, value, length) /* =========================================================================== * Initialize the various 'constant' tables. */ -local void tr_static_init() -{ +local void tr_static_init(void) { #if defined(GEN_TREES_H) || !defined(STDC) static int static_init_done = 0; int n; /* iterates over tree elements */ @@ -323,8 +384,7 @@ local void tr_static_init() ((i) == (last)? "\n};\n\n" : \ ((i) % (width) == (width) - 1 ? ",\n" : ", ")) -void gen_trees_header() -{ +void gen_trees_header(void) { FILE *header = fopen("trees.h", "w"); int i; @@ -373,12 +433,26 @@ void gen_trees_header() } #endif /* GEN_TREES_H */ +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(deflate_state *s) { + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->sym_next = s->matches = 0; +} + /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ -void ZLIB_INTERNAL _tr_init(s) - deflate_state *s; -{ +void ZLIB_INTERNAL _tr_init(deflate_state *s) { tr_static_init(); s->l_desc.dyn_tree = s->dyn_ltree; @@ -401,24 +475,6 @@ void ZLIB_INTERNAL _tr_init(s) init_block(s); } -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->sym_next = s->matches = 0; -} - #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ @@ -448,11 +504,7 @@ local void init_block(s) * when the heap property is re-established (each father smaller than its * two sons). */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ +local void pqdownheap(deflate_state *s, ct_data *tree, int k) { int v = s->heap[k]; int j = k << 1; /* left son of k */ while (j <= s->heap_len) { @@ -483,10 +535,7 @@ local void pqdownheap(s, tree, k) * The length opt_len is updated; static_len is also updated if stree is * not null. */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ +local void gen_bitlen(deflate_state *s, tree_desc *desc) { ct_data *tree = desc->dyn_tree; int max_code = desc->max_code; const ct_data *stree = desc->stat_desc->static_tree; @@ -561,48 +610,9 @@ local void gen_bitlen(s, desc) } } -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes(tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - unsigned code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = (ush)code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, - "inconsistent bit counts"); - Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].Len; - if (len == 0) continue; - /* Now reverse the bits */ - tree[n].Code = (ush)bi_reverse(next_code[len]++, len); - - Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); - } -} +#ifdef DUMP_BL_TREE +# include +#endif /* =========================================================================== * Construct one Huffman tree and assigns the code bit strings and lengths. @@ -612,10 +622,7 @@ local void gen_codes(tree, max_code, bl_count) * and corresponding code. The length opt_len is updated; static_len is * also updated if stree is not null. The field max_code is set. */ -local void build_tree(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ +local void build_tree(deflate_state *s, tree_desc *desc) { ct_data *tree = desc->dyn_tree; const ct_data *stree = desc->stat_desc->static_tree; int elems = desc->stat_desc->elems; @@ -700,11 +707,7 @@ local void build_tree(s, desc) * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */ -local void scan_tree(s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ +local void scan_tree(deflate_state *s, ct_data *tree, int max_code) { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ @@ -745,11 +748,7 @@ local void scan_tree(s, tree, max_code) * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ -local void send_tree(s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ +local void send_tree(deflate_state *s, ct_data *tree, int max_code) { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ @@ -796,9 +795,7 @@ local void send_tree(s, tree, max_code) * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */ -local int build_bl_tree(s) - deflate_state *s; -{ +local int build_bl_tree(deflate_state *s) { int max_blindex; /* index of last bit length code of non zero freq */ /* Determine the bit length frequencies for literal and distance trees */ @@ -831,10 +828,8 @@ local int build_bl_tree(s) * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ +local void send_all_trees(deflate_state *s, int lcodes, int dcodes, + int blcodes) { int rank; /* index in bl_order */ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); @@ -860,12 +855,8 @@ local void send_all_trees(s, lcodes, dcodes, blcodes) /* =========================================================================== * Send a stored block */ -void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, + ulg stored_len, int last) { send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */ bi_windup(s); /* align on byte boundary */ put_short(s, (ush)stored_len); @@ -884,9 +875,7 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) /* =========================================================================== * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) */ -void ZLIB_INTERNAL _tr_flush_bits(s) - deflate_state *s; -{ +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) { bi_flush(s); } @@ -894,9 +883,7 @@ void ZLIB_INTERNAL _tr_flush_bits(s) * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. */ -void ZLIB_INTERNAL _tr_align(s) - deflate_state *s; -{ +void ZLIB_INTERNAL _tr_align(deflate_state *s) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); #ifdef ZLIB_DEBUG @@ -905,16 +892,108 @@ void ZLIB_INTERNAL _tr_align(s) bi_flush(s); } +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(deflate_state *s, const ct_data *ltree, + const ct_data *dtree) { + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned sx = 0; /* running index in symbol buffers */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->sym_next != 0) do { +#ifdef LIT_MEM + dist = s->d_buf[sx]; + lc = s->l_buf[sx++]; +#else + dist = s->sym_buf[sx++] & 0xff; + dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; + lc = s->sym_buf[sx++]; +#endif + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code + LITERALS + 1, ltree); /* send length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= (unsigned)base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check for no overlay of pending_buf on needed symbols */ +#ifdef LIT_MEM + Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow"); +#else + Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); +#endif + + } while (sx < s->sym_next); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "block list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(deflate_state *s) { + /* block_mask is the bit mask of block-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long block_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("block-listed") bytes. */ + for (n = 0; n <= 31; n++, block_mask >>= 1) + if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("allow-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "block-listed" or "allow-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and write out the encoded block. */ -void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, + ulg stored_len, int last) { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex = 0; /* index of last bit length code of non zero freq */ @@ -1011,14 +1090,15 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ -int ZLIB_INTERNAL _tr_tally(s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length - MIN_MATCH or unmatched char (dist==0) */ -{ +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { +#ifdef LIT_MEM + s->d_buf[s->sym_next] = (ush)dist; + s->l_buf[s->sym_next++] = (uch)lc; +#else s->sym_buf[s->sym_next++] = (uch)dist; s->sym_buf[s->sym_next++] = (uch)(dist >> 8); s->sym_buf[s->sym_next++] = (uch)lc; +#endif if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; @@ -1035,147 +1115,3 @@ int ZLIB_INTERNAL _tr_tally(s, dist, lc) } return (s->sym_next == s->sym_end); } - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - const ct_data *ltree; /* literal tree */ - const ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in sym_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->sym_next != 0) do { - dist = s->sym_buf[sx++] & 0xff; - dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; - lc = s->sym_buf[sx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code + LITERALS + 1, ltree); /* send length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= (unsigned)base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and sym_buf is ok: */ - Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); - - } while (sx < s->sym_next); - - send_code(s, END_BLOCK, ltree); -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "block list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(s) - deflate_state *s; -{ - /* block_mask is the bit mask of block-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long block_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("block-listed") bytes. */ - for (n = 0; n <= 31; n++, block_mask >>= 1) - if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("allow-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "block-listed" or "allow-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->bits_sent = (s->bits_sent + 7) & ~7; -#endif -} diff --git a/src/native/external/zlib/uncompr.c b/src/native/external/zlib/uncompr.c index f9532f46c1a69f..5e256663b4511c 100644 --- a/src/native/external/zlib/uncompr.c +++ b/src/native/external/zlib/uncompr.c @@ -24,12 +24,8 @@ Z_DATA_ERROR if the input data was corrupted, including if the input data is an incomplete zlib stream. */ -int ZEXPORT uncompress2(dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong *sourceLen; -{ +int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong *sourceLen) { z_stream stream; int err; const uInt max = (uInt)-1; @@ -83,11 +79,7 @@ int ZEXPORT uncompress2(dest, destLen, source, sourceLen) err; } -int ZEXPORT uncompress(dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ +int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen) { return uncompress2(dest, destLen, source, &sourceLen); } diff --git a/src/native/external/zlib/zconf.h b/src/native/external/zlib/zconf.h index bf977d3e70adef..62adc8d8431f2f 100644 --- a/src/native/external/zlib/zconf.h +++ b/src/native/external/zlib/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -241,7 +241,11 @@ #endif #ifdef Z_SOLO - typedef unsigned long z_size_t; +# ifdef _WIN64 + typedef unsigned long long z_size_t; +# else + typedef unsigned long z_size_t; +# endif #else # define z_longlong long long # if defined(NO_SIZE_T) @@ -296,14 +300,6 @@ # endif #endif -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have @@ -520,7 +516,7 @@ typedef uLong FAR uLongf; #if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t #else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# if defined(_WIN32) && !defined(__GNUC__) # define z_off64_t __int64 # else # define z_off64_t z_off_t diff --git a/src/native/external/zlib/zconf.h.cmakein b/src/native/external/zlib/zconf.h.cmakein index 247ba2461dd09e..0abe3bc9d8fa4e 100644 --- a/src/native/external/zlib/zconf.h.cmakein +++ b/src/native/external/zlib/zconf.h.cmakein @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -243,7 +243,11 @@ #endif #ifdef Z_SOLO - typedef unsigned long z_size_t; +# ifdef _WIN64 + typedef unsigned long long z_size_t; +# else + typedef unsigned long z_size_t; +# endif #else # define z_longlong long long # if defined(NO_SIZE_T) @@ -298,14 +302,6 @@ # endif #endif -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have @@ -522,7 +518,7 @@ typedef uLong FAR uLongf; #if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t #else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# if defined(_WIN32) && !defined(__GNUC__) # define z_off64_t __int64 # else # define z_off64_t z_off_t diff --git a/src/native/external/zlib/zconf.h.in b/src/native/external/zlib/zconf.h.in index bf977d3e70adef..62adc8d8431f2f 100644 --- a/src/native/external/zlib/zconf.h.in +++ b/src/native/external/zlib/zconf.h.in @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -241,7 +241,11 @@ #endif #ifdef Z_SOLO - typedef unsigned long z_size_t; +# ifdef _WIN64 + typedef unsigned long long z_size_t; +# else + typedef unsigned long z_size_t; +# endif #else # define z_longlong long long # if defined(NO_SIZE_T) @@ -296,14 +300,6 @@ # endif #endif -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have @@ -520,7 +516,7 @@ typedef uLong FAR uLongf; #if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t #else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# if defined(_WIN32) && !defined(__GNUC__) # define z_off64_t __int64 # else # define z_off64_t z_off_t diff --git a/src/native/external/zlib/zlib.3 b/src/native/external/zlib/zlib.3 index 6f6e91404dff19..c716020ea9c420 100644 --- a/src/native/external/zlib/zlib.3 +++ b/src/native/external/zlib/zlib.3 @@ -1,4 +1,4 @@ -.TH ZLIB 3 "13 Oct 2022" +.TH ZLIB 3 "22 Jan 2024" .SH NAME zlib \- compression/decompression library .SH SYNOPSIS @@ -105,9 +105,9 @@ before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). .SH AUTHORS AND LICENSE -Version 1.2.13 +Version 1.3.1 .LP -Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler +Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler .LP This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/native/external/zlib/zlib.h b/src/native/external/zlib/zlib.h index 953cb5012dc203..8d4b932eaf6a0f 100644 --- a/src/native/external/zlib/zlib.h +++ b/src/native/external/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.13, October 13th, 2022 + version 1.3.1, January 22nd, 2024 - Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.13" -#define ZLIB_VERNUM 0x12d0 +#define ZLIB_VERSION "1.3.1" +#define ZLIB_VERNUM 0x1310 #define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 13 +#define ZLIB_VER_MINOR 3 +#define ZLIB_VER_REVISION 1 #define ZLIB_VER_SUBREVISION 0 /* @@ -78,8 +78,8 @@ extern "C" { even in the case of corrupted input. */ -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); +typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size); +typedef void (*free_func)(voidpf opaque, voidpf address); struct internal_state; @@ -217,7 +217,7 @@ typedef gz_header FAR *gz_headerp; /* basic functions */ -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +ZEXTERN const char * ZEXPORT zlibVersion(void); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check @@ -225,12 +225,12 @@ ZEXTERN const char * ZEXPORT zlibVersion OF((void)); */ /* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); +ZEXTERN int ZEXPORT deflateInit(z_streamp strm, int level); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. + allocation functions. total_in, total_out, adler, and msg are initialized. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all @@ -247,7 +247,7 @@ ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); */ -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +ZEXTERN int ZEXPORT deflate(z_streamp strm, int flush); /* deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce @@ -320,8 +320,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. + avail_out is greater than six when the flush marker begins, in order to avoid + repeated flush markers upon calling deflate() again when avail_out == 0. If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was @@ -360,7 +360,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); */ -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT deflateEnd(z_streamp strm); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending @@ -375,7 +375,7 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateInit(z_streamp strm); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by @@ -383,7 +383,8 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); read or consumed. The allocation of a sliding window will be deferred to the first call of inflate (if the decompression does not complete on the first call). If zalloc and zfree are set to Z_NULL, inflateInit updates - them to use default allocation functions. + them to use default allocation functions. total_in, total_out, adler, and + msg are initialized. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the @@ -397,7 +398,7 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); */ -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +ZEXTERN int ZEXPORT inflate(z_streamp strm, int flush); /* inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce @@ -517,7 +518,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); */ -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateEnd(z_streamp strm); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending @@ -535,12 +536,12 @@ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); */ /* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); +ZEXTERN int ZEXPORT deflateInit2(z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy); This is another version of deflateInit with more compression options. The fields zalloc, zfree and opaque must be initialized before by the caller. @@ -607,9 +608,9 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, compression: this will be done by deflate(). */ -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); +ZEXTERN int ZEXPORT deflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. When using the zlib format, this @@ -651,9 +652,9 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, not perform any compression: this will be done by deflate(). */ -ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); +ZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); /* Returns the sliding dictionary being maintained by deflate. dictLength is set to the number of bytes in the dictionary, and that many bytes are copied @@ -673,8 +674,8 @@ ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, stream state is inconsistent. */ -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); +ZEXTERN int ZEXPORT deflateCopy(z_streamp dest, + z_streamp source); /* Sets the destination stream as a complete copy of the source stream. @@ -691,20 +692,20 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, destination. */ -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +ZEXTERN int ZEXPORT deflateReset(z_streamp strm); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate the internal compression state. The stream will leave the compression level and any other attributes that may have been - set unchanged. + set unchanged. total_in, total_out, adler, and msg are initialized. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). */ -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); +ZEXTERN int ZEXPORT deflateParams(z_streamp strm, + int level, + int strategy); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2(). This can be @@ -729,7 +730,7 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, Then no more input data should be provided before the deflateParams() call. If this is done, the old level and strategy will be applied to the data compressed before deflateParams(), and the new level and strategy will be - applied to the the data compressed after deflateParams(). + applied to the data compressed after deflateParams(). deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if @@ -740,11 +741,11 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, retried with more output space. */ -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); +ZEXTERN int ZEXPORT deflateTune(z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain); /* Fine tune deflate's internal compression parameters. This should only be used by someone who understands the algorithm used by zlib's deflate for @@ -757,8 +758,8 @@ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. */ -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); +ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, + uLong sourceLen); /* deflateBound() returns an upper bound on the compressed size after deflation of sourceLen bytes. It must be called after deflateInit() or @@ -772,9 +773,9 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, than Z_FINISH or Z_NO_FLUSH are used. */ -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); +ZEXTERN int ZEXPORT deflatePending(z_streamp strm, + unsigned *pending, + int *bits); /* deflatePending() returns the number of bytes and bits of output that have been generated, but not yet provided in the available output. The bytes not @@ -787,9 +788,9 @@ ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, stream state was inconsistent. */ -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); +ZEXTERN int ZEXPORT deflatePrime(z_streamp strm, + int bits, + int value); /* deflatePrime() inserts bits in the deflate output stream. The intent is that this function is used to start off the deflate output with the bits @@ -804,8 +805,8 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, source stream state was inconsistent. */ -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); +ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm, + gz_headerp head); /* deflateSetHeader() provides gzip header information for when a gzip stream is requested by deflateInit2(). deflateSetHeader() may be called @@ -821,16 +822,17 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, gzip file" and give up. If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). + the time set to zero, and os set to the current operating system, with no + extra, name, or comment fields. The gzip header is returned to the default + state by deflateReset(). deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); +ZEXTERN int ZEXPORT inflateInit2(z_streamp strm, + int windowBits); This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized @@ -883,9 +885,9 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, deferred until inflate() is called. */ -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); +ZEXTERN int ZEXPORT inflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate, @@ -906,9 +908,9 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, inflate(). */ -ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); +ZEXTERN int ZEXPORT inflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); /* Returns the sliding dictionary being maintained by inflate. dictLength is set to the number of bytes in the dictionary, and that many bytes are copied @@ -921,7 +923,7 @@ ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, stream state is inconsistent. */ -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateSync(z_streamp strm); /* Skips invalid compressed data until a possible full flush point (see above for the description of deflate with Z_FULL_FLUSH) can be found, or until all @@ -934,14 +936,14 @@ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); inflateSync returns Z_OK if a possible full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. + In the success case, the application may save the current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. */ -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); +ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, + z_streamp source); /* Sets the destination stream as a complete copy of the source stream. @@ -956,18 +958,19 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, destination. */ -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateReset(z_streamp strm); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. + total_in, total_out, adler, and msg are initialized. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). */ -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); +ZEXTERN int ZEXPORT inflateReset2(z_streamp strm, + int windowBits); /* This function is the same as inflateReset, but it also permits changing the wrap and window size requests. The windowBits parameter is interpreted @@ -980,9 +983,9 @@ ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, the windowBits parameter is invalid. */ -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); +ZEXTERN int ZEXPORT inflatePrime(z_streamp strm, + int bits, + int value); /* This function inserts bits in the inflate input stream. The intent is that this function is used to start inflating at a bit position in the @@ -1001,7 +1004,7 @@ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, stream state was inconsistent. */ -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +ZEXTERN long ZEXPORT inflateMark(z_streamp strm); /* This function returns two values, one in the lower 16 bits of the return value, and the other in the remaining upper bits, obtained by shifting the @@ -1029,8 +1032,8 @@ ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); source stream state was inconsistent. */ -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); +ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm, + gz_headerp head); /* inflateGetHeader() requests that gzip header information be stored in the provided gz_header structure. inflateGetHeader() may be called after @@ -1070,8 +1073,8 @@ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, */ /* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); +ZEXTERN int ZEXPORT inflateBackInit(z_streamp strm, int windowBits, + unsigned char FAR *window); Initialize the internal stream state for decompression using inflateBack() calls. The fields zalloc, zfree and opaque in strm must be initialized @@ -1091,13 +1094,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, the version of the header file. */ -typedef unsigned (*in_func) OF((void FAR *, - z_const unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); +typedef unsigned (*in_func)(void FAR *, + z_const unsigned char FAR * FAR *); +typedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned); -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); +ZEXTERN int ZEXPORT inflateBack(z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc); /* inflateBack() does a raw inflate with a single call using a call-back interface for input and output. This is potentially more efficient than @@ -1165,7 +1168,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, cannot return Z_OK. */ -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm); /* All memory allocated by inflateBackInit() is freed. @@ -1173,7 +1176,7 @@ ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); state was inconsistent. */ -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +ZEXTERN uLong ZEXPORT zlibCompileFlags(void); /* Return flags indicating compile-time options. Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: @@ -1226,8 +1229,8 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); you need special options. */ -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); +ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size @@ -1241,9 +1244,9 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, buffer. */ -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); +ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte @@ -1257,15 +1260,15 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, Z_STREAM_ERROR if the level parameter is invalid. */ -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen); /* compressBound() returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before a compress() or compress2() call to allocate the destination buffer. */ -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); +ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size @@ -1282,8 +1285,8 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, buffer with the uncompressed data up to that point. */ -ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong *sourceLen)); +ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong *sourceLen); /* Same as uncompress, except that sourceLen is a pointer, where the length of the source is *sourceLen. On return, *sourceLen is the number of @@ -1302,7 +1305,7 @@ ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ /* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); Open the gzip (.gz) file at path for reading and decompressing, or compressing and writing. The mode parameter is as in fopen ("rb" or "wb") @@ -1339,7 +1342,7 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); file could not be opened. */ -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); /* Associate a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or fileno (if the file has @@ -1362,7 +1365,7 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); will not detect if fd is invalid (unless fd is -1). */ -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size); /* Set the internal buffer size used by this library's functions for file to size. The default buffer size is 8192 bytes. This function must be called @@ -1378,7 +1381,7 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); too late. */ -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy); /* Dynamically update the compression level and strategy for file. See the description of deflateInit2 for the meaning of these parameters. Previously @@ -1389,7 +1392,7 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); or Z_MEM_ERROR if there is a memory allocation error. */ -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len); /* Read and decompress up to len uncompressed bytes from file into buf. If the input file is not in gzip format, gzread copies the given number of @@ -1419,8 +1422,8 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); Z_STREAM_ERROR. */ -ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, - gzFile file)); +ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, + gzFile file); /* Read and decompress up to nitems items of size size from file into buf, otherwise operating as gzread() does. This duplicates the interface of @@ -1445,14 +1448,14 @@ ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, file, resetting and retrying on end-of-file, when size is not 1. */ -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len)); +ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); /* Compress and write the len uncompressed bytes at buf to file. gzwrite returns the number of uncompressed bytes written or 0 in case of error. */ -ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, - z_size_t nitems, gzFile file)); +ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, + z_size_t nitems, gzFile file); /* Compress and write nitems items of size size from buf to file, duplicating the interface of stdio's fwrite(), with size_t request and return types. If @@ -1465,7 +1468,7 @@ ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, is returned, and the error state is set to Z_STREAM_ERROR. */ -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); /* Convert, format, compress, and write the arguments (...) to file under control of the string format, as in fprintf. gzprintf returns the number of @@ -1480,7 +1483,7 @@ ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); This can be determined using zlibCompileFlags(). */ -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); /* Compress and write the given null-terminated string s to file, excluding the terminating null character. @@ -1488,7 +1491,7 @@ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); gzputs returns the number of characters written, or -1 in case of error. */ -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); /* Read and decompress bytes from file into buf, until len-1 characters are read, or until a newline character is read and transferred to buf, or an @@ -1502,13 +1505,13 @@ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); buf are indeterminate. */ -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +ZEXTERN int ZEXPORT gzputc(gzFile file, int c); /* Compress and write c, converted to an unsigned char, into file. gzputc returns the value that was written, or -1 in case of error. */ -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +ZEXTERN int ZEXPORT gzgetc(gzFile file); /* Read and decompress one byte from file. gzgetc returns this byte or -1 in case of end of file or error. This is implemented as a macro for speed. @@ -1517,7 +1520,7 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); points to has been clobbered or not. */ -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); /* Push c back onto the stream for file to be read as the first character on the next read. At least one character of push-back is always allowed. @@ -1529,7 +1532,7 @@ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); gzseek() or gzrewind(). */ -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); /* Flush all pending output to file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function @@ -1545,8 +1548,8 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); */ /* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); +ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, + z_off_t offset, int whence); Set the starting position to offset relative to whence for the next gzread or gzwrite on file. The offset represents a number of bytes in the @@ -1564,7 +1567,7 @@ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, would be before the current position. */ -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +ZEXTERN int ZEXPORT gzrewind(gzFile file); /* Rewind file. This function is supported only for reading. @@ -1572,7 +1575,7 @@ ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); */ /* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +ZEXTERN z_off_t ZEXPORT gztell(gzFile file); Return the starting position for the next gzread or gzwrite on file. This position represents a number of bytes in the uncompressed data stream, @@ -1583,7 +1586,7 @@ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); */ /* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); +ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file); Return the current compressed (actual) read or write offset of file. This offset includes the count of bytes that precede the gzip stream, for example @@ -1592,7 +1595,7 @@ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); be used for a progress indicator. On error, gzoffset() returns -1. */ -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +ZEXTERN int ZEXPORT gzeof(gzFile file); /* Return true (1) if the end-of-file indicator for file has been set while reading, false (0) otherwise. Note that the end-of-file indicator is set @@ -1607,7 +1610,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); has grown since the previous end of file was detected. */ -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +ZEXTERN int ZEXPORT gzdirect(gzFile file); /* Return true (1) if file is being copied directly while reading, or false (0) if file is a gzip stream being decompressed. @@ -1628,7 +1631,7 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); gzip file reading and decompression, which may not be desired.) */ -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose(gzFile file); /* Flush all pending output for file, if necessary, close file and deallocate the (de)compression state. Note that once file is closed, you @@ -1641,8 +1644,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); last read ended in the middle of a gzip stream, or Z_OK on success. */ -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_r(gzFile file); +ZEXTERN int ZEXPORT gzclose_w(gzFile file); /* Same as gzclose(), but gzclose_r() is only for use when reading, and gzclose_w() is only for use when writing or appending. The advantage to @@ -1653,7 +1656,7 @@ ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); zlib library. */ -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); /* Return the error message for the last error which occurred on file. errnum is set to zlib error number. If an error occurred in the file system @@ -1669,7 +1672,7 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); functions above that do not distinguish those cases in their return values. */ -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +ZEXTERN void ZEXPORT gzclearerr(gzFile file); /* Clear the error and end-of-file flags for file. This is analogous to the clearerr() function in stdio. This is useful for continuing to read a gzip @@ -1686,7 +1689,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); library. */ -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. An Adler-32 value is in the range of a 32-bit @@ -1706,15 +1709,15 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); if (adler != original_adler) error(); */ -ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); +ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, + z_size_t len); /* Same as adler32(), but with a size_t length. */ /* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); +ZEXTERN uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, + z_off_t len2); Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for @@ -1724,7 +1727,7 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, negative, the result has no meaning or utility. */ -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. @@ -1742,30 +1745,30 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); if (crc != original_crc) error(); */ -ZEXTERN uLong ZEXPORT crc32_z OF((uLong crc, const Bytef *buf, - z_size_t len)); +ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, + z_size_t len); /* Same as crc32(), but with a size_t length. */ /* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); +ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); Combine two CRC-32 check values into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. + len2. len2 must be non-negative. */ /* -ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2)); +ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); Return the operator corresponding to length len2, to be used with - crc32_combine_op(). + crc32_combine_op(). len2 must be non-negative. */ -ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op)); +ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); /* Give the same result as crc32_combine(), using op in place of len2. op is is generated from len2 by crc32_combine_gen(). This will be faster than @@ -1778,20 +1781,20 @@ ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op)); /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); +ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateInit_(z_streamp strm, + const char *version, int stream_size); +ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size); +ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size); #ifdef Z_PREFIX_SET # define z_deflateInit(strm, level) \ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) @@ -1836,7 +1839,7 @@ struct gzFile_s { unsigned char *next; z_off64_t pos; }; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ #ifdef Z_PREFIX_SET # undef z_gzgetc # define z_gzgetc(g) \ @@ -1853,13 +1856,13 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ * without large file support, _LFS64_LARGEFILE must also be true */ #ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off64_t)); + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); #endif #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) @@ -1881,50 +1884,50 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ # define crc32_combine_gen crc32_combine_gen64 # endif # ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t)); + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); # endif #else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t)); + ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); #endif #else /* Z_SOLO */ - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t)); + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); #endif /* !Z_SOLO */ /* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); -ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF((z_streamp)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +ZEXTERN const char * ZEXPORT zError(int); +ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void); +ZEXTERN int ZEXPORT inflateUndermine(z_streamp, int); +ZEXTERN int ZEXPORT inflateValidate(z_streamp, int); +ZEXTERN unsigned long ZEXPORT inflateCodesUsed(z_streamp); +ZEXTERN int ZEXPORT inflateResetKeep(z_streamp); +ZEXTERN int ZEXPORT deflateResetKeep(z_streamp); #if defined(_WIN32) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, - const char *mode)); +ZEXTERN gzFile ZEXPORT gzopen_w(const wchar_t *path, + const char *mode); #endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) # ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, - const char *format, - va_list va)); +ZEXTERN int ZEXPORTVA gzvprintf(gzFile file, + const char *format, + va_list va); # endif #endif diff --git a/src/native/external/zlib/zlib2ansi b/src/native/external/zlib/zlib2ansi deleted file mode 100644 index 23b2a1d5a3ec2f..00000000000000 --- a/src/native/external/zlib/zlib2ansi +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/perl - -# Transform K&R C function definitions into ANSI equivalent. -# -# Author: Paul Marquess -# Version: 1.0 -# Date: 3 October 2006 - -# TODO -# -# Assumes no function pointer parameters. unless they are typedefed. -# Assumes no literal strings that look like function definitions -# Assumes functions start at the beginning of a line - -use strict; -use warnings; - -local $/; -$_ = <>; - -my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments - -my $d1 = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ; -my $decl = qr{ $sp (?: \w+ $sp )+ $d1 }xo ; -my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ; - - -while (s/^ - ( # Start $1 - ( # Start $2 - .*? # Minimal eat content - ( ^ \w [\w\s\*]+ ) # $3 -- function name - \s* # optional whitespace - ) # $2 - Matched up to before parameter list - - \( \s* # Literal "(" + optional whitespace - ( [^\)]+ ) # $4 - one or more anythings except ")" - \s* \) # optional whitespace surrounding a Literal ")" - - ( (?: $dList )+ ) # $5 - - $sp ^ { # literal "{" at start of line - ) # Remember to $1 - //xsom - ) -{ - my $all = $1 ; - my $prefix = $2; - my $param_list = $4 ; - my $params = $5; - - StripComments($params); - StripComments($param_list); - $param_list =~ s/^\s+//; - $param_list =~ s/\s+$//; - - my $i = 0 ; - my %pList = map { $_ => $i++ } - split /\s*,\s*/, $param_list; - my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ; - - my @params = split /\s*;\s*/, $params; - my @outParams = (); - foreach my $p (@params) - { - if ($p =~ /,/) - { - my @bits = split /\s*,\s*/, $p; - my $first = shift @bits; - $first =~ s/^\s*//; - push @outParams, $first; - $first =~ /^(\w+\s*)/; - my $type = $1 ; - push @outParams, map { $type . $_ } @bits; - } - else - { - $p =~ s/^\s+//; - push @outParams, $p; - } - } - - - my %tmp = map { /$pMatch/; $_ => $pList{$1} } - @outParams ; - - @outParams = map { " $_" } - sort { $tmp{$a} <=> $tmp{$b} } - @outParams ; - - print $prefix ; - print "(\n" . join(",\n", @outParams) . ")\n"; - print "{" ; - -} - -# Output any trailing code. -print ; -exit 0; - - -sub StripComments -{ - - no warnings; - - # Strip C & C++ comments - # From the perlfaq - $_[0] =~ - - s{ - /\* ## Start of /* ... */ comment - [^*]*\*+ ## Non-* followed by 1-or-more *'s - ( - [^/*][^*]*\*+ - )* ## 0-or-more things which don't start with / - ## but do end with '*' - / ## End of /* ... */ comment - - | ## OR C++ Comment - // ## Start of C++ comment // - [^\n]* ## followed by 0-or-more non end of line characters - - | ## OR various things which aren't comments: - - ( - " ## Start of " ... " string - ( - \\. ## Escaped char - | ## OR - [^"\\] ## Non "\ - )* - " ## End of " ... " string - - | ## OR - - ' ## Start of ' ... ' string - ( - \\. ## Escaped char - | ## OR - [^'\\] ## Non '\ - )* - ' ## End of ' ... ' string - - | ## OR - - . ## Anything other char - [^/"'\\]* ## Chars which doesn't start a comment, string or escape - ) - }{$2}gxs; - -} diff --git a/src/native/external/zlib/zutil.c b/src/native/external/zlib/zutil.c index 9543ae825e3250..b1c5d2d3c6daf5 100644 --- a/src/native/external/zlib/zutil.c +++ b/src/native/external/zlib/zutil.c @@ -24,13 +24,11 @@ z_const char * const z_errmsg[10] = { }; -const char * ZEXPORT zlibVersion() -{ +const char * ZEXPORT zlibVersion(void) { return ZLIB_VERSION; } -uLong ZEXPORT zlibCompileFlags() -{ +uLong ZEXPORT zlibCompileFlags(void) { uLong flags; flags = 0; @@ -121,9 +119,7 @@ uLong ZEXPORT zlibCompileFlags() # endif int ZLIB_INTERNAL z_verbose = verbose; -void ZLIB_INTERNAL z_error(m) - char *m; -{ +void ZLIB_INTERNAL z_error(char *m) { fprintf(stderr, "%s\n", m); exit(1); } @@ -132,9 +128,7 @@ void ZLIB_INTERNAL z_error(m) /* exported to allow conversion of error code to string for compress() and * uncompress() */ -const char * ZEXPORT zError(err) - int err; -{ +const char * ZEXPORT zError(int err) { return ERR_MSG(err); } @@ -148,22 +142,14 @@ const char * ZEXPORT zError(err) #ifndef HAVE_MEMCPY -void ZLIB_INTERNAL zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ +void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { if (len == 0) return; do { *dest++ = *source++; /* ??? to be unrolled */ } while (--len != 0); } -int ZLIB_INTERNAL zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ +int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { uInt j; for (j = 0; j < len; j++) { @@ -172,10 +158,7 @@ int ZLIB_INTERNAL zmemcmp(s1, s2, len) return 0; } -void ZLIB_INTERNAL zmemzero(dest, len) - Bytef* dest; - uInt len; -{ +void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { if (len == 0) return; do { *dest++ = 0; /* ??? to be unrolled */ @@ -216,8 +199,7 @@ local ptr_table table[MAX_PTR]; * a protected system like OS/2. Use Microsoft C instead. */ -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) -{ +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { voidpf buf; ulg bsize = (ulg)items*size; @@ -242,8 +224,7 @@ voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) return buf; } -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) -{ +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { int n; (void)opaque; @@ -279,14 +260,12 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) # define _hfree hfree #endif -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) -{ +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { (void)opaque; return _halloc((long)items, size); } -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) -{ +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { (void)opaque; _hfree(ptr); } @@ -299,25 +278,18 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) #ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); +extern voidp malloc(uInt size); +extern voidp calloc(uInt items, uInt size); +extern void free(voidpf ptr); #endif -voidpf ZLIB_INTERNAL zcalloc(opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { (void)opaque; return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : (voidpf)calloc(items, size); } -void ZLIB_INTERNAL zcfree(opaque, ptr) - voidpf opaque; - voidpf ptr; -{ +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { (void)opaque; free(ptr); } diff --git a/src/native/external/zlib/zutil.h b/src/native/external/zlib/zutil.h index 0bc7f4ecd1c0e5..48dd7febae65ee 100644 --- a/src/native/external/zlib/zutil.h +++ b/src/native/external/zlib/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -56,7 +56,7 @@ typedef unsigned long ulg; extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] +#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] #define ERR_RETURN(strm,err) \ return (strm->msg = ERR_MSG(err), (err)) @@ -137,17 +137,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # endif #endif -#if defined(MACOS) || defined(TARGET_OS_MAC) +#if defined(MACOS) # define OS_CODE 7 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif #endif #ifdef __acorn @@ -170,18 +161,6 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define OS_CODE 19 #endif -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - #if defined(__BORLANDC__) && !defined(MSDOS) #pragma warn -8004 #pragma warn -8008 @@ -191,9 +170,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* provide prototypes for these when building zlib without LFS */ #if !defined(_WIN32) && \ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t)); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); #endif /* common defaults */ @@ -232,16 +211,16 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define zmemzero(dest, len) memset(dest, 0, len) # endif #else - void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); + void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len); + int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); + void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); #endif /* Diagnostic functions */ #ifdef ZLIB_DEBUG # include extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error OF((char *m)); + extern void ZLIB_INTERNAL z_error(char *m); # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) {if (z_verbose>=0) fprintf x ;} # define Tracev(x) {if (z_verbose>0) fprintf x ;} @@ -258,9 +237,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif #ifndef Z_SOLO - voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); - void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); + voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, + unsigned size); + void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr); #endif #define ZALLOC(strm, items, size) \ From 250354be83584ba28e9f50c39ce06348408782a3 Mon Sep 17 00:00:00 2001 From: Radek Zikmund <32671551+rzikm@users.noreply.github.com> Date: Wed, 20 Mar 2024 09:39:35 +0100 Subject: [PATCH 656/783] Fix failing CertificateValidationRemoteServer.ConnectWithRevocation_WithCallback test (#99950) * Don't add empty Organization to Subject string * Make sure testName is populated when creating test PKI * Minor changes --- .../X509Certificates/CertificateAuthority.cs | 10 ++++------ .../CertificateValidationRemoteServer.cs | 5 ++++- .../SslStreamCertificateContextTests.cs | 1 + 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs index 184d8a62e99366..beb32116171200 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs @@ -179,7 +179,7 @@ internal X509Certificate2 CreateOcspSigner(string subject, RSA publicKey) subject, publicKey, TimeSpan.FromSeconds(1), - new X509ExtensionCollection() { s_eeConstraints, s_eeKeyUsage, s_ocspResponderEku}, + new X509ExtensionCollection() { s_eeConstraints, s_eeKeyUsage, s_ocspResponderEku }, ocspResponder: true); } @@ -950,12 +950,10 @@ private static string BuildSubject( PkiOptions pkiOptions, bool includePkiOptions) { - if (includePkiOptions) - { - return $"CN=\"{cn}\", O=\"{testName}\", OU=\"{pkiOptions}\""; - } + string testNamePart = !string.IsNullOrWhiteSpace(testName) ? $", O=\"{testName}\"" : ""; + string pkiOptionsPart = includePkiOptions ? $", OU=\"{pkiOptions}\"" : ""; - return $"CN=\"{cn}\", O=\"{testName}\""; + return $"CN=\"{cn}\"" + testNamePart + pkiOptionsPart; } } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs index e804849dd7f5c9..35cefd116acd8d 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs @@ -7,6 +7,7 @@ using System.Net.Sockets; using System.Net.Test.Common; using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates.Tests.Common; @@ -188,7 +189,8 @@ static bool CertificateValidationCallback( private async Task ConnectWithRevocation_WithCallback_Core( X509RevocationMode revocationMode, bool? offlineContext = false, - bool noIntermediates = false) + bool noIntermediates = false, + [CallerMemberName] string testName = null) { string offlinePart = offlineContext.HasValue ? offlineContext.GetValueOrDefault().ToString().ToLower() : "null"; string serverName = $"{revocationMode.ToString().ToLower()}.{offlinePart}.server.example"; @@ -201,6 +203,7 @@ private async Task ConnectWithRevocation_WithCallback_Core( out CertificateAuthority rootAuthority, out CertificateAuthority[] intermediateAuthorities, out X509Certificate2 serverCert, + testName: testName, intermediateAuthorityCount: noIntermediates ? 0 : 1, subjectName: serverName, keySize: 2048, diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamCertificateContextTests.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamCertificateContextTests.cs index a3fd09c41ef680..69cb644243aa44 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamCertificateContextTests.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamCertificateContextTests.cs @@ -24,6 +24,7 @@ public static async Task Create_OcspDoesNotReturnOrCacheInvalidStapleData() out CertificateAuthority rootAuthority, out CertificateAuthority[] intermediateAuthorities, out X509Certificate2 serverCert, + testName: nameof(Create_OcspDoesNotReturnOrCacheInvalidStapleData), intermediateAuthorityCount: 1, subjectName: serverName, keySize: 2048, From afb3fcad64be34154300264a65ff324208e76d32 Mon Sep 17 00:00:00 2001 From: Matous Kozak <55735845+matouskozak@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:01:57 +0100 Subject: [PATCH 657/783] [mono] Stop exporting ICU symbols from Mono (#99449) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * do not export ICU symbols from Mono (libmonosgen-2.0.dylib and libSystem.Globalization.Native.dylib) --------- Co-authored-by: Alexander Köplinger --- src/mono/mono/mini/CMakeLists.txt | 10 +++++++++- .../libs/System.Globalization.Native/CMakeLists.txt | 10 +++++++++- src/tasks/AppleAppBuilder/Xcode.cs | 11 ++++++++--- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/mini/CMakeLists.txt b/src/mono/mono/mini/CMakeLists.txt index 5d6ef3dfa3c31e..08b90567eb288b 100644 --- a/src/mono/mono/mini/CMakeLists.txt +++ b/src/mono/mono/mini/CMakeLists.txt @@ -421,7 +421,15 @@ if(NOT DISABLE_SHARED_LIBS) # to avoid a conflict we rename the import library with the .import.lib suffix set_target_properties(monosgen-shared PROPERTIES IMPORT_SUFFIX ".import.lib") endif() - target_link_libraries(monosgen-shared PRIVATE ${OS_LIBS} ${LLVM_LIBS} ${ICU_LIBS} ${Z_LIBS}) + if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) + target_link_libraries(monosgen-shared PRIVATE ${OS_LIBS} ${LLVM_LIBS} ${Z_LIBS}) + add_linker_flag(-Wl,-L${ICU_LIBDIR}) + add_linker_flag(-Wl,-hidden-licuuc) + add_linker_flag(-Wl,-hidden-licui18n) + add_linker_flag(-Wl,-hidden-licudata) + else() + target_link_libraries(monosgen-shared PRIVATE ${OS_LIBS} ${LLVM_LIBS} ${ICU_LIBS} ${Z_LIBS}) + endif() if(ICU_LDFLAGS) set_property(TARGET monosgen-shared APPEND_STRING PROPERTY LINK_FLAGS " ${ICU_LDFLAGS}") endif() diff --git a/src/native/libs/System.Globalization.Native/CMakeLists.txt b/src/native/libs/System.Globalization.Native/CMakeLists.txt index 0545ace30f4dd7..1fcaf0b6bd583c 100644 --- a/src/native/libs/System.Globalization.Native/CMakeLists.txt +++ b/src/native/libs/System.Globalization.Native/CMakeLists.txt @@ -66,7 +66,15 @@ set(NATIVEGLOBALIZATION_SOURCES if (DEFINED CMAKE_ICU_DIR) include_directories(${CMAKE_ICU_DIR}/include) - link_libraries(${CMAKE_ICU_DIR}/lib/libicuuc.a ${CMAKE_ICU_DIR}/lib/libicui18n.a ${CMAKE_ICU_DIR}/lib/libicudata.a) + if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) + add_linker_flag(-Wl,-L${CMAKE_ICU_DIR}/lib) + add_linker_flag(-Wl,-hidden-licuuc) + add_linker_flag(-Wl,-hidden-licui18n) + add_linker_flag(-Wl,-hidden-licudata) + else() + link_libraries(${CMAKE_ICU_DIR}/lib/libicuuc.a ${CMAKE_ICU_DIR}/lib/libicui18n.a ${CMAKE_ICU_DIR}/lib/libicudata.a) + endif() + link_libraries(stdc++) endif() diff --git a/src/tasks/AppleAppBuilder/Xcode.cs b/src/tasks/AppleAppBuilder/Xcode.cs index 0e05d9168423e0..f253b41a2b188e 100644 --- a/src/tasks/AppleAppBuilder/Xcode.cs +++ b/src/tasks/AppleAppBuilder/Xcode.cs @@ -396,9 +396,14 @@ public string GenerateCMake( } else if (forceAOT || !(preferDylibs && dylibExists)) { - // these libraries are pinvoked - // -force_load will be removed once we enable direct-pinvokes for AOT - toLink += $" \"-force_load {lib}\"{Environment.NewLine}"; + // do not export symbols from ICU libraries + if (libName == "libicui18n" || libName == "libicudata" || libName == "libicuuc") { + toLink += $" \"-load_hidden {lib}\"{Environment.NewLine}"; + } else { + // these libraries are pinvoked + // -force_load will be removed once we enable direct-pinvokes for AOT + toLink += $" \"-force_load {lib}\"{Environment.NewLine}"; + } } } From 99c7022f7644866770c4a3bd6a73d4e27922097c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 21 Mar 2024 19:50:28 +0100 Subject: [PATCH 658/783] [release/8.0-staging] Fix AV in HttpTelemetry.WriteEvent (#99607) * Fix AV in HttpTelemetry.WriteEvent * Move descrs into fixed scope --------- Co-authored-by: Miha Zupan --- .../src/System/Net/Http/HttpTelemetry.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpTelemetry.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpTelemetry.cs index 9989bc4568e617..3dfc789919b33c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpTelemetry.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpTelemetry.cs @@ -339,13 +339,13 @@ private unsafe void WriteEvent(int eventId, byte arg1, byte arg2, long arg3, str arg5 ??= ""; arg7 ??= ""; - const int NumEventDatas = 7; - EventData* descrs = stackalloc EventData[NumEventDatas]; - fixed (char* arg4Ptr = arg4) fixed (char* arg5Ptr = arg5) fixed (char* arg7Ptr = arg7) { + const int NumEventDatas = 7; + EventData* descrs = stackalloc EventData[NumEventDatas]; + descrs[0] = new EventData { DataPointer = (IntPtr)(&arg1), @@ -381,9 +381,9 @@ private unsafe void WriteEvent(int eventId, byte arg1, byte arg2, long arg3, str DataPointer = (IntPtr)arg7Ptr, Size = (arg7.Length + 1) * sizeof(char) }; - } - WriteEventCore(eventId, NumEventDatas, descrs); + WriteEventCore(eventId, NumEventDatas, descrs); + } } } } From b7f047793b9377bd01b51421d8e5740af97c0d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20P=C3=ADchov=C3=A1?= <11718369+ManickaP@users.noreply.github.com> Date: Tue, 26 Mar 2024 17:54:03 +0100 Subject: [PATCH 659/783] [Http/2] Fix handling of effectively empty DATA frame (#99502) (#99677) * Fix handling effectively empty DATA frame * Added test --- .../SocketsHttpHandler/Http2Connection.cs | 6 ++- .../HttpClientHandlerTest.Http2.cs | 44 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs index e9cce1c24d34d5..5b795f0a88457d 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs @@ -765,12 +765,14 @@ private void ProcessDataFrame(FrameHeader frameHeader) // Just ignore the frame in this case. ReadOnlySpan frameData = GetFrameData(_incomingBuffer.ActiveSpan.Slice(0, frameHeader.PayloadLength), hasPad: frameHeader.PaddedFlag, hasPriority: false); - if (http2Stream != null) { bool endStream = frameHeader.EndStreamFlag; - http2Stream.OnResponseData(frameData, endStream); + if (frameData.Length > 0 || endStream) + { + http2Stream.OnResponseData(frameData, endStream); + } if (!endStream && frameData.Length > 0) { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs index 25a3dcd7c69a2c..07f19ef3029c97 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs @@ -204,6 +204,50 @@ public async Task Http2_ZeroLengthResponseBody_Success() } } + [Fact] + public async Task Http2_DataFrameOnlyPadding_Success() + { + using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer()) + using (HttpClient client = CreateHttpClient()) + { + Task sendTask = client.GetAsync(server.Address, HttpCompletionOption.ResponseHeadersRead); + + Http2LoopbackConnection connection = await server.EstablishConnectionAsync(); + + int streamId = await connection.ReadRequestHeaderAsync(); + + await connection.SendDefaultResponseHeadersAsync(streamId); + + // Send zero-length DATA frame with padding + byte paddingLength = byte.MaxValue; + int dataLength = 1024; + DataFrame frame = new DataFrame(new byte[0], FrameFlags.Padded, paddingLength, streamId); + await connection.WriteFrameAsync(frame); + + HttpResponseMessage response = await sendTask; + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + using var responseStream = response.Content.ReadAsStream(); + + // The read must pend because we havent received any data yet. + var buffer = new byte[dataLength]; + var readTask = responseStream.ReadAtLeastAsync(buffer, dataLength); + Assert.False(readTask.IsCompleted); + + // Send DATA frame with padding + frame = new DataFrame(new byte[dataLength], FrameFlags.Padded, paddingLength, streamId); + await connection.WriteFrameAsync(frame); + + Assert.Equal(dataLength, await readTask); + + // Send zero-length, end-stream DATA frame with padding + frame = new DataFrame(new byte[0], FrameFlags.Padded | FrameFlags.EndStream, paddingLength, streamId); + await connection.WriteFrameAsync(frame); + + Assert.Equal(0, await responseStream.ReadAsync(buffer)); + } + } + [Theory] [InlineData("Client content", null)] [InlineData("Client content", "Server content")] From 3f774aa658f3963f43876846cb439dbb9eba8418 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:38:30 +0100 Subject: [PATCH 660/783] [release/8.0-staging] [HttpStress] [SslStress] Workaround image bug in 1es-windows-2022-open (#100303) Backport of #100145 to release/8.0-staging --- eng/pipelines/libraries/stress/http.yml | 3 +++ eng/pipelines/libraries/stress/ssl.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/eng/pipelines/libraries/stress/http.yml b/eng/pipelines/libraries/stress/http.yml index f4f9c45de36e48..68bfcef6c50812 100644 --- a/eng/pipelines/libraries/stress/http.yml +++ b/eng/pipelines/libraries/stress/http.yml @@ -119,6 +119,9 @@ extends: lfs: false - powershell: | + # Workaround for https://github.com/microsoft/azure-pipelines-agent/issues/4554. Undo when the image bug is fixed. + Remove-Item -Path "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\Microsoft.VCToolsVersion.v143.default.txt" + $(dockerfilesFolder)/build-docker-sdk.ps1 -w -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION) echo "##vso[task.setvariable variable=succeeded;isOutput=true]true" name: buildRuntime diff --git a/eng/pipelines/libraries/stress/ssl.yml b/eng/pipelines/libraries/stress/ssl.yml index ab93994400d346..a70a18e828f04d 100644 --- a/eng/pipelines/libraries/stress/ssl.yml +++ b/eng/pipelines/libraries/stress/ssl.yml @@ -76,6 +76,9 @@ extends: lfs: false - powershell: | + # Workaround for https://github.com/microsoft/azure-pipelines-agent/issues/4554. Undo when the image bug is fixed. + Remove-Item -Path "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\Microsoft.VCToolsVersion.v143.default.txt" + $(dockerfilesFolder)/build-docker-sdk.ps1 -w -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION) displayName: Build CLR and Libraries From ab416e9ef39c6709b815e6ca31753a4c6e44ed58 Mon Sep 17 00:00:00 2001 From: Omair Majid Date: Wed, 27 Mar 2024 15:53:19 -0400 Subject: [PATCH 661/783] Support building against clang 18 (#100258) This is a targeted backport from a few other PRs that makes it possible to build dotnet/runtme's 8.0 branch on Fedora 40 which includes clang 18. - https://github.com/dotnet/arcade/pull/14572 - https://github.com/dotnet/runtime/pull/94782 - https://github.com/dotnet/runtime/pull/99811 --- eng/common/native/init-compiler.sh | 2 +- eng/native/configurecompiler.cmake | 3 +++ src/coreclr/pal/src/include/pal/palinternal.h | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/eng/common/native/init-compiler.sh b/eng/common/native/init-compiler.sh index f5c1ec7eafeb28..2d5660642b8d48 100644 --- a/eng/common/native/init-compiler.sh +++ b/eng/common/native/init-compiler.sh @@ -63,7 +63,7 @@ if [ -z "$CLR_CC" ]; then # Set default versions if [ -z "$majorVersion" ]; then # note: gcc (all versions) and clang versions higher than 6 do not have minor version in file name, if it is zero. - if [ "$compiler" = "clang" ]; then versions="17 16 15 14 13 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5" + if [ "$compiler" = "clang" ]; then versions="18 17 16 15 14 13 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5" elif [ "$compiler" = "gcc" ]; then versions="13 12 11 10 9 8 7 6 5 4.9"; fi for version in $versions; do diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index 183811018533aa..0e6ee88b245ebe 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -590,6 +590,9 @@ if (CLR_CMAKE_HOST_UNIX) # other clang 16.0 suppressions add_compile_options(-Wno-single-bit-bitfield-constant-conversion) add_compile_options(-Wno-cast-function-type-strict) + + # clang 18.1 supressions + add_compile_options(-Wno-switch-default) else() add_compile_options(-Wno-uninitialized) add_compile_options(-Wno-strict-aliasing) diff --git a/src/coreclr/pal/src/include/pal/palinternal.h b/src/coreclr/pal/src/include/pal/palinternal.h index a7c5ba129c90fa..3b8a55a94496c9 100644 --- a/src/coreclr/pal/src/include/pal/palinternal.h +++ b/src/coreclr/pal/src/include/pal/palinternal.h @@ -426,6 +426,7 @@ function_name() to call the system's implementation #undef va_start #undef va_end #undef va_copy +#undef va_arg #undef stdin #undef stdout #undef stderr From 51c9e0b09539f4e2213306abb6c0d8d9b48a050f Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 14 Mar 2024 10:49:38 -0700 Subject: [PATCH 662/783] Ensure Number.BigInteger doesn't try to access an invalid block --- .../src/System/Number.BigInteger.cs | 104 +++++++++++++++--- 1 file changed, 88 insertions(+), 16 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.BigInteger.cs b/src/libraries/System.Private.CoreLib/src/System/Number.BigInteger.cs index aba4b814fc399a..e8b38321185555 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Number.BigInteger.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Number.BigInteger.cs @@ -358,11 +358,24 @@ public static void Add(scoped ref BigInteger lhs, scoped ref BigInteger rhs, out resultIndex++; } + int resultLength = largeLength; + // If there's still a carry, append a new block if (carry != 0) { Debug.Assert(carry == 1); - Debug.Assert((resultIndex == largeLength) && (largeLength < MaxBlockCount)); + Debug.Assert(resultIndex == resultLength); + Debug.Assert(unchecked((uint)(resultLength)) < MaxBlockCount); + + if (unchecked((uint)(resultLength)) >= MaxBlockCount) + { + // We shouldn't reach here, and the above assert will help flag this + // during testing, but we'll ensure that we return a safe value of + // zero in the case we end up overflowing in any way. + + SetZero(out result); + return; + } result._blocks[resultIndex] = 1; result._length++; @@ -724,6 +737,8 @@ public static void Multiply(scoped ref BigInteger lhs, uint value, out BigIntege int index = 0; uint carry = 0; + int resultLength = lhsLength; + while (index < lhsLength) { ulong product = ((ulong)(lhs._blocks[index]) * value) + carry; @@ -735,14 +750,23 @@ public static void Multiply(scoped ref BigInteger lhs, uint value, out BigIntege if (carry != 0) { - Debug.Assert(unchecked((uint)(lhsLength)) + 1 <= MaxBlockCount); + Debug.Assert(unchecked((uint)(resultLength)) < MaxBlockCount); + + if (unchecked((uint)(resultLength)) >= MaxBlockCount) + { + // We shouldn't reach here, and the above assert will help flag this + // during testing, but we'll ensure that we return a safe value of + // zero in the case we end up overflowing in any way. + + SetZero(out result); + return; + } + result._blocks[index] = carry; - result._length = (lhsLength + 1); - } - else - { - result._length = lhsLength; + resultLength += 1; } + + result._length = resultLength; } public static void Multiply(scoped ref BigInteger lhs, scoped ref BigInteger rhs, out BigInteger result) @@ -777,6 +801,16 @@ public static void Multiply(scoped ref BigInteger lhs, scoped ref BigInteger rhs int maxResultLength = smallLength + largeLength; Debug.Assert(unchecked((uint)(maxResultLength)) <= MaxBlockCount); + if (unchecked((uint)(maxResultLength)) > MaxBlockCount) + { + // We shouldn't reach here, and the above assert will help flag this + // during testing, but we'll ensure that we return a safe value of + // zero in the case we end up overflowing in any way. + + SetZero(out result); + return; + } + // Zero out result internal blocks. result._length = maxResultLength; result.Clear((uint)maxResultLength); @@ -822,7 +856,19 @@ public static void Pow2(uint exponent, out BigInteger result) { uint blocksToShift = DivRem32(exponent, out uint remainingBitsToShift); result._length = (int)blocksToShift + 1; + Debug.Assert(unchecked((uint)result._length) <= MaxBlockCount); + + if (unchecked((uint)result._length) > MaxBlockCount) + { + // We shouldn't reach here, and the above assert will help flag this + // during testing, but we'll ensure that we return a safe value of + // zero in the case we end up overflowing in any way. + + SetZero(out result); + return; + } + if (blocksToShift > 0) { result.Clear(blocksToShift); @@ -1012,7 +1058,18 @@ public void Add(uint value) } } - Debug.Assert(unchecked((uint)(length)) + 1 <= MaxBlockCount); + Debug.Assert(unchecked((uint)(length)) < MaxBlockCount); + + if (unchecked((uint)(length)) >= MaxBlockCount) + { + // We shouldn't reach here, and the above assert will help flag this + // during testing, but we'll ensure that we return a safe value of + // zero in the case we end up overflowing in any way. + + SetZero(out this); + return; + } + _blocks[length] = 1; _length = length + 1; } @@ -1074,9 +1131,20 @@ public void Multiply10() if (carry != 0) { - Debug.Assert(unchecked((uint)(_length)) + 1 <= MaxBlockCount); + Debug.Assert(unchecked((uint)(length)) < MaxBlockCount); + + if (unchecked((uint)(length)) >= MaxBlockCount) + { + // We shouldn't reach here, and the above assert will help flag this + // during testing, but we'll ensure that we return a safe value of + // zero in the case we end up overflowing in any way. + + SetZero(out this); + return; + } + _blocks[index] = (uint)carry; - _length++; + _length = length + 1; } } @@ -1149,11 +1217,19 @@ public void ShiftLeft(uint shift) int readIndex = (length - 1); int writeIndex = readIndex + (int)(blocksToShift); + uint remainingBitsInLastBlock = (uint)BitOperations.LeadingZeroCount(_blocks[readIndex]); + + if (remainingBitsToShift > remainingBitsInLastBlock) + { + // We need an extra block for the partial shift + writeIndex++; + } + + Debug.Assert(unchecked((uint)(writeIndex)) < MaxBlockCount); + // Check if the shift is block aligned if (remainingBitsToShift == 0) { - Debug.Assert(writeIndex < MaxBlockCount); - while (readIndex >= 0) { _blocks[writeIndex] = _blocks[readIndex]; @@ -1168,10 +1244,6 @@ public void ShiftLeft(uint shift) } else { - // We need an extra block for the partial shift - writeIndex++; - Debug.Assert(writeIndex < MaxBlockCount); - // Set the length to hold the shifted blocks _length = writeIndex + 1; From aa046223d94654213cdec4b103bfcb31b6a79385 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Fri, 15 Mar 2024 09:55:57 -0700 Subject: [PATCH 663/783] Fixing the shift-left handling to correctly account for overshifting --- .../src/System/Number.BigInteger.cs | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.BigInteger.cs b/src/libraries/System.Private.CoreLib/src/System/Number.BigInteger.cs index e8b38321185555..7cb8578fd63177 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Number.BigInteger.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Number.BigInteger.cs @@ -31,7 +31,9 @@ internal unsafe ref struct BigInteger private const int MaxBits = BitsForLongestBinaryMantissa + BitsForLongestDigitSequence + BitsPerBlock; private const int BitsPerBlock = sizeof(int) * 8; - private const int MaxBlockCount = (MaxBits + (BitsPerBlock - 1)) / BitsPerBlock; + + // We need one extra block to make our shift left algorithm significantly simpler + private const int MaxBlockCount = ((MaxBits + (BitsPerBlock - 1)) / BitsPerBlock) + 1; private static ReadOnlySpan Pow10UInt32Table => new uint[] { @@ -302,7 +304,8 @@ internal unsafe ref struct BigInteger 0xD9D61A05, 0x00000325, - // 9 Trailing blocks to ensure MaxBlockCount + // 10 Trailing blocks to ensure MaxBlockCount + 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -737,8 +740,6 @@ public static void Multiply(scoped ref BigInteger lhs, uint value, out BigIntege int index = 0; uint carry = 0; - int resultLength = lhsLength; - while (index < lhsLength) { ulong product = ((ulong)(lhs._blocks[index]) * value) + carry; @@ -748,6 +749,8 @@ public static void Multiply(scoped ref BigInteger lhs, uint value, out BigIntege index++; } + int resultLength = lhsLength; + if (carry != 0) { Debug.Assert(unchecked((uint)(resultLength)) < MaxBlockCount); @@ -1217,19 +1220,21 @@ public void ShiftLeft(uint shift) int readIndex = (length - 1); int writeIndex = readIndex + (int)(blocksToShift); - uint remainingBitsInLastBlock = (uint)BitOperations.LeadingZeroCount(_blocks[readIndex]); - - if (remainingBitsToShift > remainingBitsInLastBlock) - { - // We need an extra block for the partial shift - writeIndex++; - } - - Debug.Assert(unchecked((uint)(writeIndex)) < MaxBlockCount); - // Check if the shift is block aligned if (remainingBitsToShift == 0) { + Debug.Assert(unchecked((uint)(length)) < MaxBlockCount); + + if (unchecked((uint)(length)) >= MaxBlockCount) + { + // We shouldn't reach here, and the above assert will help flag this + // during testing, but we'll ensure that we return a safe value of + // zero in the case we end up overflowing in any way. + + SetZero(out this); + return; + } + while (readIndex >= 0) { _blocks[writeIndex] = _blocks[readIndex]; @@ -1244,6 +1249,21 @@ public void ShiftLeft(uint shift) } else { + // We need an extra block for the partial shift + + writeIndex++; + Debug.Assert(unchecked((uint)(length)) < MaxBlockCount); + + if (unchecked((uint)(length)) >= MaxBlockCount) + { + // We shouldn't reach here, and the above assert will help flag this + // during testing, but we'll ensure that we return a safe value of + // zero in the case we end up overflowing in any way. + + SetZero(out this); + return; + } + // Set the length to hold the shifted blocks _length = writeIndex + 1; From f36dd88c5ef2e59e46ca60a493cdacb0c7657129 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Thu, 28 Mar 2024 16:32:50 +0100 Subject: [PATCH 664/783] [release/8.0][browser] WebSocket works differently depending on if we look up its state or not (#99673) * Fix. * Missing change - enqueue promises even when socket is closed. * More tests. --- .../Handlers/EchoWebSocketHandler.cs | 12 +++++ .../BrowserWebSockets/BrowserInterop.cs | 8 ++-- .../BrowserWebSockets/BrowserWebSocket.cs | 6 --- .../tests/CloseTest.cs | 46 ++++++++++++++++++- src/mono/wasm/runtime/exports-internal.ts | 3 +- src/mono/wasm/runtime/web-socket.ts | 14 +++++- 6 files changed, 75 insertions(+), 14 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHandler.cs b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHandler.cs index 8304f2d1156072..a290ce63bd4ffb 100644 --- a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHandler.cs +++ b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHandler.cs @@ -144,6 +144,18 @@ await socket.CloseAsync( { await Task.Delay(5000); } + else if (receivedMessage == ".receiveMessageAfterClose") + { + byte[] buffer = new byte[1024]; + string message = $"{receivedMessage} {DateTime.Now.ToString("HH:mm:ss")}"; + buffer = System.Text.Encoding.UTF8.GetBytes(message); + await socket.SendAsync( + new ArraySegment(buffer, 0, message.Length), + WebSocketMessageType.Text, + true, + CancellationToken.None); + await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, CancellationToken.None); + } else if (socket.State == WebSocketState.Open) { sendMessage = true; diff --git a/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserInterop.cs b/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserInterop.cs index 5ea45c2a7a2224..e535924a015817 100644 --- a/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserInterop.cs +++ b/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserInterop.cs @@ -19,11 +19,13 @@ internal static partial class BrowserInterop public static int GetReadyState(JSObject? webSocket) { if (webSocket == null || webSocket.IsDisposed) return -1; - int? readyState = webSocket.GetPropertyAsInt32("readyState"); - if (!readyState.HasValue) return -1; - return readyState.Value; + return BrowserInterop.WebSocketGetState(webSocket); } + [JSImport("INTERNAL.ws_get_state")] + public static partial int WebSocketGetState( + JSObject webSocket); + [JSImport("INTERNAL.ws_wasm_create")] public static partial JSObject WebSocketCreate( string uri, diff --git a/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserWebSocket.cs b/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserWebSocket.cs index 879d45ca0da57c..6c8f7a036ed971 100644 --- a/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserWebSocket.cs +++ b/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/BrowserWebSocket.cs @@ -385,12 +385,6 @@ private void CreateCore(Uri uri, List? requestedSubProtocols) #endif _closeStatus = (WebSocketCloseStatus)code; _closeStatusDescription = reason; - _closeReceived = true; - WebSocketState state = State; - if (state == WebSocketState.Connecting || state == WebSocketState.Open || state == WebSocketState.CloseSent) - { - FastState = WebSocketState.Closed; - } #if FEATURE_WASM_THREADS } //lock #endif diff --git a/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.cs b/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.cs index 6f1e6faa490192..1e99e356a87c6c 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Linq; using Xunit; using Xunit.Abstractions; @@ -264,8 +265,8 @@ public async Task CloseOutputAsync_ClientInitiated_CanReceive_CanClose(Uri serve [ActiveIssue("https://github.com/dotnet/runtime/issues/28957", typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseOutputAsync_ServerInitiated_CanReceive(Uri server) + [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServersWithSwitch))] + public async Task CloseOutputAsync_ServerInitiated_CanReceive(Uri server, bool delayReceiving) { string message = "Hello WebSockets!"; var expectedCloseStatus = WebSocketCloseStatus.NormalClosure; @@ -281,6 +282,10 @@ await cws.SendAsync( true, cts.Token); + // let server close the output before we request receiving + if (delayReceiving) + await Task.Delay(1000); + // Should be able to receive the message echoed by the server. var recvBuffer = new byte[100]; var segmentRecv = new ArraySegment(recvBuffer); @@ -367,6 +372,43 @@ await cws.SendAsync( } } + public static IEnumerable EchoServersWithSwitch => + EchoServers.SelectMany(server => new List + { + new object[] { server[0], true }, + new object[] { server[0], false } + }); + + [ActiveIssue("https://github.com/dotnet/runtime/issues/28957", typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServersWithSwitch))] + public async Task CloseOutputAsync_ServerInitiated_CanReceiveAfterClose(Uri server, bool syncState) + { + using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + { + var cts = new CancellationTokenSource(TimeOutMilliseconds); + await cws.SendAsync( + WebSocketData.GetBufferFromText(".receiveMessageAfterClose"), + WebSocketMessageType.Text, + true, + cts.Token); + + await Task.Delay(2000); + + if (syncState) + { + var state = cws.State; + Assert.Equal(WebSocketState.Open, state); + // should be able to receive after this sync + } + + var recvBuffer = new ArraySegment(new byte[1024]); + WebSocketReceiveResult recvResult = await cws.ReceiveAsync(recvBuffer, cts.Token); + var message = Encoding.UTF8.GetString(recvBuffer.ToArray(), 0, recvResult.Count); + + Assert.Contains(".receiveMessageAfterClose", message); + } + } + [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] public async Task CloseOutputAsync_CloseDescriptionIsNull_Success(Uri server) diff --git a/src/mono/wasm/runtime/exports-internal.ts b/src/mono/wasm/runtime/exports-internal.ts index 826180282e3bbc..b009da17c6c9bd 100644 --- a/src/mono/wasm/runtime/exports-internal.ts +++ b/src/mono/wasm/runtime/exports-internal.ts @@ -8,7 +8,7 @@ import { http_wasm_supports_streaming_response, http_wasm_create_abort_controler import { exportedRuntimeAPI, Module, runtimeHelpers } from "./globals"; import { get_property, set_property, has_property, get_typeof_property, get_global_this, dynamic_import } from "./invoke-js"; import { mono_wasm_stringify_as_error_with_stack } from "./logging"; -import { ws_wasm_create, ws_wasm_open, ws_wasm_send, ws_wasm_receive, ws_wasm_close, ws_wasm_abort } from "./web-socket"; +import { ws_wasm_create, ws_wasm_open, ws_wasm_send, ws_wasm_receive, ws_wasm_close, ws_wasm_abort, ws_get_state } from "./web-socket"; import { mono_wasm_get_loaded_files } from "./assets"; import { jiterpreter_dump_stats } from "./jiterpreter"; import { getOptions, applyOptions } from "./jiterpreter-support"; @@ -62,6 +62,7 @@ export function export_internal(): any { ws_wasm_receive, ws_wasm_close, ws_wasm_abort, + ws_get_state, // BrowserHttpHandler http_wasm_supports_streaming_response, diff --git a/src/mono/wasm/runtime/web-socket.ts b/src/mono/wasm/runtime/web-socket.ts index 5cf400aca536a9..0f99b7e2eaf244 100644 --- a/src/mono/wasm/runtime/web-socket.ts +++ b/src/mono/wasm/runtime/web-socket.ts @@ -43,6 +43,17 @@ function verifyEnvironment() { } } +export function ws_get_state(ws: WebSocketExtension) : number +{ + if (ws.readyState != WebSocket.CLOSED) + return ws.readyState ?? -1; + const receive_event_queue = ws[wasm_ws_pending_receive_event_queue]; + const queued_events_count = receive_event_queue.getLength(); + if (queued_events_count == 0) + return ws.readyState ?? -1; + return WebSocket.OPEN; +} + export function ws_wasm_create(uri: string, sub_protocols: string[] | null, receive_status_ptr: VoidPtr, onClosed: (code: number, reason: string) => void): WebSocketExtension { verifyEnvironment(); mono_assert(uri && typeof uri === "string", () => `ERR12: Invalid uri ${typeof uri}`); @@ -175,8 +186,7 @@ export function ws_wasm_receive(ws: WebSocketExtension, buffer_ptr: VoidPtr, buf return null; } - const readyState = ws.readyState; - if (readyState == WebSocket.CLOSED) { + if (ws[wasm_ws_close_received]) { const receive_status_ptr = ws[wasm_ws_receive_status_ptr]; setI32(receive_status_ptr, 0); // count setI32(receive_status_ptr + 4, 2); // type:close From ba9df1e9210fd3e2d5631637eb9c70630ccc346c Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Sat, 30 Mar 2024 08:20:28 -0700 Subject: [PATCH 665/783] [release/8.0-staging] Call the Copy Constructor for stack arguments in C++/CLI on x86 (#100221) * Call the Copy Constructor for stack arguments in C++/CLI on Windows-x86 (#100050) * Add repro test case * Directly load the argument address using ldarga to avoid making a copy * Reimplement the "Copy Constructor Cookie" logic in a more modern and maintainable style to get the test passing again * Narrow support to Windows only --------- Co-authored-by: Jeremy Koritzinsky --- .../src/System/StubHelpers.cs | 69 ++++++++++++++ src/coreclr/vm/corelib.h | 15 ++++ src/coreclr/vm/dllimport.cpp | 56 ++++++++++++ src/coreclr/vm/dllimport.h | 7 ++ src/coreclr/vm/i386/asmhelpers.asm | 24 +++++ src/coreclr/vm/ilmarshalers.cpp | 36 ++++++++ src/coreclr/vm/metasig.h | 7 ++ .../CopyConstructorMarshaler.cs | 36 +++++++- .../IjwCopyConstructorMarshaler.cpp | 90 +++++++++++++++++++ .../Miscellaneous/CopyCtor/CopyCtorTest.cs | 28 +++++- 10 files changed, 361 insertions(+), 7 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index 431c2f724a02ba..ced928ae2e71a7 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -1111,6 +1111,75 @@ public IntPtr AddRef() } } // class CleanupWorkListElement + internal unsafe struct CopyConstructorCookie + { + private void* m_source; + + private nuint m_destinationOffset; + + public delegate* m_copyConstructor; + + public delegate* m_destructor; + + public CopyConstructorCookie* m_next; + + [StackTraceHidden] + public void ExecuteCopy(void* destinationBase) + { + if (m_copyConstructor != null) + { + m_copyConstructor((byte*)destinationBase + m_destinationOffset, m_source); + } + + if (m_destructor != null) + { + m_destructor(m_source); + } + } + } + + internal unsafe struct CopyConstructorChain + { + public void* m_realTarget; + public CopyConstructorCookie* m_head; + + public void Add(CopyConstructorCookie* cookie) + { + cookie->m_next = m_head; + m_head = cookie; + } + + [ThreadStatic] + private static CopyConstructorChain s_copyConstructorChain; + + public void Install(void* realTarget) + { + m_realTarget = realTarget; + s_copyConstructorChain = this; + } + + [StackTraceHidden] + private void ExecuteCopies(void* destinationBase) + { + for (CopyConstructorCookie* current = m_head; current != null; current = current->m_next) + { + current->ExecuteCopy(destinationBase); + } + } + + [UnmanagedCallersOnly] + [StackTraceHidden] + public static void* ExecuteCurrentCopiesAndGetTarget(void* destinationBase) + { + void* target = s_copyConstructorChain.m_realTarget; + s_copyConstructorChain.ExecuteCopies(destinationBase); + // Reset this instance to ensure we don't accidentally execute the copies again. + // All of the pointers point to the stack, so we don't need to free any memory. + s_copyConstructorChain = default; + return target; + } + } + internal static class StubHelpers { [MethodImpl(MethodImplOptions.InternalCall)] diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 96576a85813125..cf059679bd08fb 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -1068,6 +1068,21 @@ DEFINE_METHOD(HANDLE_MARSHALER, CONVERT_SAFEHANDLE_TO_NATIVE,ConvertSaf DEFINE_METHOD(HANDLE_MARSHALER, THROW_SAFEHANDLE_FIELD_CHANGED, ThrowSafeHandleFieldChanged, SM_RetVoid) DEFINE_METHOD(HANDLE_MARSHALER, THROW_CRITICALHANDLE_FIELD_CHANGED, ThrowCriticalHandleFieldChanged, SM_RetVoid) +#ifdef TARGET_WINDOWS +#ifdef TARGET_X86 +DEFINE_CLASS(COPY_CONSTRUCTOR_CHAIN, StubHelpers, CopyConstructorChain) +DEFINE_METHOD(COPY_CONSTRUCTOR_CHAIN, EXECUTE_CURRENT_COPIES_AND_GET_TARGET, ExecuteCurrentCopiesAndGetTarget, SM_PtrVoid_RetPtrVoid) +DEFINE_METHOD(COPY_CONSTRUCTOR_CHAIN, INSTALL, Install, IM_PtrVoid_RetVoid) +DEFINE_METHOD(COPY_CONSTRUCTOR_CHAIN, ADD, Add, IM_PtrCopyConstructorCookie_RetVoid) + +DEFINE_CLASS(COPY_CONSTRUCTOR_COOKIE, StubHelpers, CopyConstructorCookie) +DEFINE_FIELD(COPY_CONSTRUCTOR_COOKIE, SOURCE, m_source) +DEFINE_FIELD(COPY_CONSTRUCTOR_COOKIE, DESTINATION_OFFSET, m_destinationOffset) +DEFINE_FIELD(COPY_CONSTRUCTOR_COOKIE, COPY_CONSTRUCTOR, m_copyConstructor) +DEFINE_FIELD(COPY_CONSTRUCTOR_COOKIE, DESTRUCTOR, m_destructor) +#endif // TARGET_X86 +#endif // TARGET_WINDOWS + DEFINE_CLASS(NATIVEVARIANT, StubHelpers, NativeVariant) DEFINE_CLASS(NATIVEDECIMAL, StubHelpers, NativeDecimal) diff --git a/src/coreclr/vm/dllimport.cpp b/src/coreclr/vm/dllimport.cpp index 37aab6a3f530d7..31c4467b7982a6 100644 --- a/src/coreclr/vm/dllimport.cpp +++ b/src/coreclr/vm/dllimport.cpp @@ -1623,6 +1623,10 @@ NDirectStubLinker::NDirectStubLinker( m_pcsSetup->EmitSTLOC(m_dwTargetInterfacePointerLocalNum); } #endif // FEATURE_COMINTEROP + +#if defined(TARGET_X86) && defined(TARGET_WINDOWS) + m_dwCopyCtorChainLocalNum = (DWORD)-1; +#endif // defined(TARGET_X86) && defined(TARGET_WINDOWS) } void NDirectStubLinker::SetCallingConvention(CorInfoCallConvExtension unmngCallConv, BOOL fIsVarArg) @@ -1835,6 +1839,23 @@ DWORD NDirectStubLinker::GetReturnValueLocalNum() return m_dwRetValLocalNum; } +#if defined(TARGET_X86) && defined(TARGET_WINDOWS) +DWORD NDirectStubLinker::GetCopyCtorChainLocalNum() +{ + STANDARD_VM_CONTRACT; + + if (m_dwCopyCtorChainLocalNum == (DWORD)-1) + { + // The local is created and initialized lazily when first asked. + m_dwCopyCtorChainLocalNum = NewLocal(CoreLibBinder::GetClass(CLASS__COPY_CONSTRUCTOR_CHAIN)); + m_pcsSetup->EmitLDLOCA(m_dwCopyCtorChainLocalNum); + m_pcsSetup->EmitINITOBJ(m_pcsSetup->GetToken(CoreLibBinder::GetClass(CLASS__COPY_CONSTRUCTOR_CHAIN))); + } + + return m_dwCopyCtorChainLocalNum; +} +#endif // defined(TARGET_X86) && defined(TARGET_WINDOWS) + BOOL NDirectStubLinker::IsCleanupNeeded() { LIMITED_METHOD_CONTRACT; @@ -2064,6 +2085,10 @@ void NDirectStubLinker::End(DWORD dwStubFlags) } } +#if defined(TARGET_X86) && defined(TARGET_WINDOWS) +EXTERN_C void STDCALL CopyConstructorCallStub(void); +#endif // defined(TARGET_X86) && defined(TARGET_WINDOWS) + void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, MethodDesc * pStubMD) { STANDARD_VM_CONTRACT; @@ -2150,6 +2175,21 @@ void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth } } +#if defined(TARGET_X86) && defined(TARGET_WINDOWS) + if (m_dwCopyCtorChainLocalNum != (DWORD)-1) + { + // If we have a copy constructor chain local, we need to call the copy constructor stub + // to ensure that the chain is called correctly. + // Let's install the stub chain here and redirect the call to the stub. + DWORD targetLoc = NewLocal(ELEMENT_TYPE_I); + pcsEmit->EmitSTLOC(targetLoc); + pcsEmit->EmitLDLOCA(m_dwCopyCtorChainLocalNum); + pcsEmit->EmitLDLOC(targetLoc); + pcsEmit->EmitCALL(METHOD__COPY_CONSTRUCTOR_CHAIN__INSTALL, 2, 0); + pcsEmit->EmitLDC((DWORD_PTR)&CopyConstructorCallStub); + } +#endif // defined(TARGET_X86) && defined(TARGET_WINDOWS) + // For managed-to-native calls, the rest of the work is done by the JIT. It will // erect InlinedCallFrame, flip GC mode, and use the specified calling convention // to call the target. For native-to-managed calls, this is an ordinary managed @@ -6078,5 +6118,21 @@ PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD) RETURN pVASigCookie->pNDirectILStub; } +#if defined(TARGET_X86) && defined(TARGET_WINDOWS) +// Copy constructor support for C++/CLI +EXTERN_C void* STDCALL CallCopyConstructorsWorker(void* esp) +{ + STATIC_CONTRACT_THROWS; + STATIC_CONTRACT_GC_TRIGGERS; + STATIC_CONTRACT_MODE_PREEMPTIVE; // we've already switched to preemptive + + using ExecuteCallback = void*(STDMETHODCALLTYPE*)(void*); + + MethodDesc* pMD = CoreLibBinder::GetMethod(METHOD__COPY_CONSTRUCTOR_CHAIN__EXECUTE_CURRENT_COPIES_AND_GET_TARGET); + ExecuteCallback pExecute = (ExecuteCallback)pMD->GetMultiCallableAddrOfCode(); + + return pExecute(esp); +} +#endif // defined(TARGET_X86) && defined(TARGET_WINDOWS) #endif // #ifndef DACCESS_COMPILE diff --git a/src/coreclr/vm/dllimport.h b/src/coreclr/vm/dllimport.h index 256b950799336e..a89a01bc7003ca 100644 --- a/src/coreclr/vm/dllimport.h +++ b/src/coreclr/vm/dllimport.h @@ -484,6 +484,9 @@ class NDirectStubLinker : public ILStubLinker DWORD GetCleanupWorkListLocalNum(); DWORD GetThreadLocalNum(); DWORD GetReturnValueLocalNum(); +#if defined(TARGET_X86) && defined(TARGET_WINDOWS) + DWORD GetCopyCtorChainLocalNum(); +#endif // defined(TARGET_X86) && defined(TARGET_WINDOWS) void SetCleanupNeeded(); void SetExceptionCleanupNeeded(); BOOL IsCleanupWorkListSetup(); @@ -553,6 +556,10 @@ class NDirectStubLinker : public ILStubLinker DWORD m_dwTargetEntryPointLocalNum; #endif // FEATURE_COMINTEROP +#if defined(TARGET_X86) && defined(TARGET_WINDOWS) + DWORD m_dwCopyCtorChainLocalNum; +#endif // defined(TARGET_X86) && defined(TARGET_WINDOWS) + BOOL m_fHasCleanupCode; BOOL m_fHasExceptionCleanupCode; BOOL m_fCleanupWorkListIsSetup; diff --git a/src/coreclr/vm/i386/asmhelpers.asm b/src/coreclr/vm/i386/asmhelpers.asm index e03ffa9544f2ca..1d02fc48f8d8b8 100644 --- a/src/coreclr/vm/i386/asmhelpers.asm +++ b/src/coreclr/vm/i386/asmhelpers.asm @@ -41,6 +41,7 @@ EXTERN _NDirectImportWorker@4:PROC EXTERN _VarargPInvokeStubWorker@12:PROC EXTERN _GenericPInvokeCalliStubWorker@12:PROC +EXTERN _CallCopyConstructorsWorker@4:PROC EXTERN _PreStubWorker@8:PROC EXTERN _TheUMEntryPrestubWorker@4:PROC @@ -1062,6 +1063,29 @@ GoCallCalliWorker: _GenericPInvokeCalliHelper@0 endp +;========================================================================== +; This is small stub whose purpose is to record current stack pointer and +; call CallCopyConstructorsWorker to invoke copy constructors and destructors +; as appropriate. This stub operates on arguments already pushed to the +; stack by JITted IL stub and must not create a new frame, i.e. it must tail +; call to the target for it to see the arguments that copy ctors have been +; called on. +; +_CopyConstructorCallStub@0 proc public + ; there may be an argument in ecx - save it + push ecx + + ; push pointer to arguments + lea edx, [esp + 8] + push edx + + call _CallCopyConstructorsWorker@4 + + ; restore ecx and tail call to the target + pop ecx + jmp eax +_CopyConstructorCallStub@0 endp + ifdef FEATURE_COMINTEROP ;========================================================================== diff --git a/src/coreclr/vm/ilmarshalers.cpp b/src/coreclr/vm/ilmarshalers.cpp index 431064f4e121de..2e622bd725eda4 100644 --- a/src/coreclr/vm/ilmarshalers.cpp +++ b/src/coreclr/vm/ilmarshalers.cpp @@ -3459,6 +3459,38 @@ MarshalerOverrideStatus ILBlittableValueClassWithCopyCtorMarshaler::ArgumentOver #ifdef TARGET_X86 pslIL->SetStubTargetArgType(&locDesc); // native type is the value type pslILDispatch->EmitLDLOC(dwNewValueTypeLocal); // we load the local directly + +#if defined(TARGET_WINDOWS) + // Record this argument's stack slot in the copy constructor chain so we can correctly invoke the copy constructor. + DWORD ctorCookie = pslIL->NewLocal(CoreLibBinder::GetClass(CLASS__COPY_CONSTRUCTOR_COOKIE)); + pslIL->EmitLDLOCA(ctorCookie); + pslIL->EmitINITOBJ(pslIL->GetToken(CoreLibBinder::GetClass(CLASS__COPY_CONSTRUCTOR_COOKIE))); + pslIL->EmitLDLOCA(ctorCookie); + pslIL->EmitLDLOCA(dwNewValueTypeLocal); + pslIL->EmitSTFLD(pslIL->GetToken(CoreLibBinder::GetField(FIELD__COPY_CONSTRUCTOR_COOKIE__SOURCE))); + pslIL->EmitLDLOCA(ctorCookie); + pslIL->EmitLDC(nativeStackOffset); + pslIL->EmitSTFLD(pslIL->GetToken(CoreLibBinder::GetField(FIELD__COPY_CONSTRUCTOR_COOKIE__DESTINATION_OFFSET))); + + if (pargs->mm.m_pCopyCtor) + { + pslIL->EmitLDLOCA(ctorCookie); + pslIL->EmitLDFTN(pslIL->GetToken(pargs->mm.m_pCopyCtor)); + pslIL->EmitSTFLD(pslIL->GetToken(CoreLibBinder::GetField(FIELD__COPY_CONSTRUCTOR_COOKIE__COPY_CONSTRUCTOR))); + } + + if (pargs->mm.m_pDtor) + { + pslIL->EmitLDLOCA(ctorCookie); + pslIL->EmitLDFTN(pslIL->GetToken(pargs->mm.m_pDtor)); + pslIL->EmitSTFLD(pslIL->GetToken(CoreLibBinder::GetField(FIELD__COPY_CONSTRUCTOR_COOKIE__DESTRUCTOR))); + } + + pslIL->EmitLDLOCA(psl->GetCopyCtorChainLocalNum()); + pslIL->EmitLDLOCA(ctorCookie); + pslIL->EmitCALL(METHOD__COPY_CONSTRUCTOR_CHAIN__ADD, 2, 0); +#endif // defined(TARGET_WINDOWS) + #else pslIL->SetStubTargetArgType(ELEMENT_TYPE_I); // native type is a pointer EmitLoadNativeLocalAddrForByRefDispatch(pslILDispatch, dwNewValueTypeLocal); @@ -3477,9 +3509,13 @@ MarshalerOverrideStatus ILBlittableValueClassWithCopyCtorMarshaler::ArgumentOver DWORD dwNewValueTypeLocal; dwNewValueTypeLocal = pslIL->NewLocal(locDesc); +#ifdef TARGET_WINDOWS + pslILDispatch->EmitLDARGA(argidx); +#else // !TARGET_WINDOWS pslILDispatch->EmitLDARG(argidx); pslILDispatch->EmitSTLOC(dwNewValueTypeLocal); pslILDispatch->EmitLDLOCA(dwNewValueTypeLocal); +#endif // TARGET_WINDOWS #else LocalDesc locDesc(pargs->mm.m_pMT); locDesc.MakeCopyConstructedPointer(); diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 6adf044a0170df..ed277458c9b22e 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -578,6 +578,13 @@ DEFINE_METASIG_T(SM(RefCleanupWorkListElement_RetVoid, r(C(CLEANUP_WORK_LIST_ELE DEFINE_METASIG_T(SM(RefCleanupWorkListElement_SafeHandle_RetIntPtr, r(C(CLEANUP_WORK_LIST_ELEMENT)) C(SAFE_HANDLE), I)) DEFINE_METASIG_T(SM(RefCleanupWorkListElement_Obj_RetVoid, r(C(CLEANUP_WORK_LIST_ELEMENT)) j, v)) +DEFINE_METASIG(SM(PtrVoid_RetPtrVoid, P(v), P(v))) +DEFINE_METASIG(IM(PtrVoid_RetVoid, P(v), v)) +#if defined(TARGET_X86) && defined(TARGET_WINDOWS) +DEFINE_METASIG_T(IM(PtrCopyConstructorCookie_RetVoid, P(g(COPY_CONSTRUCTOR_COOKIE)), v)) +#endif // defined(TARGET_X86) && defined(TARGET_WINDOWS) + + #ifdef FEATURE_ICASTABLE DEFINE_METASIG_T(SM(ICastable_RtType_RefException_RetBool, C(ICASTABLE) C(CLASS) r(C(EXCEPTION)), F)) DEFINE_METASIG_T(SM(ICastable_RtType_RetRtType, C(ICASTABLE) C(CLASS), C(CLASS))) diff --git a/src/tests/Interop/IJW/CopyConstructorMarshaler/CopyConstructorMarshaler.cs b/src/tests/Interop/IJW/CopyConstructorMarshaler/CopyConstructorMarshaler.cs index 95afea492be764..baf3ebd4579e8b 100644 --- a/src/tests/Interop/IJW/CopyConstructorMarshaler/CopyConstructorMarshaler.cs +++ b/src/tests/Interop/IJW/CopyConstructorMarshaler/CopyConstructorMarshaler.cs @@ -25,34 +25,62 @@ static int Main() object testInstance = Activator.CreateInstance(testType); MethodInfo testMethod = testType.GetMethod("PInvokeNumCopies"); + // On x86, we have an additional copy on every P/Invoke from the "native" parameter to the actual location on the stack. + int platformExtra = 0; + if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + { + platformExtra = 1; + } + // PInvoke will copy twice. Once from argument to parameter, and once from the managed to native parameter. - Assert.Equal(2, (int)testMethod.Invoke(testInstance, null)); + Assert.Equal(2 + platformExtra, (int)testMethod.Invoke(testInstance, null)); testMethod = testType.GetMethod("ReversePInvokeNumCopies"); // Reverse PInvoke will copy 3 times. Two are from the same paths as the PInvoke, // and the third is from the reverse P/Invoke call. - Assert.Equal(3, (int)testMethod.Invoke(testInstance, null)); + Assert.Equal(3 + platformExtra, (int)testMethod.Invoke(testInstance, null)); testMethod = testType.GetMethod("PInvokeNumCopiesDerivedType"); // PInvoke will copy twice. Once from argument to parameter, and once from the managed to native parameter. - Assert.Equal(2, (int)testMethod.Invoke(testInstance, null)); + Assert.Equal(2 + platformExtra, (int)testMethod.Invoke(testInstance, null)); testMethod = testType.GetMethod("ReversePInvokeNumCopiesDerivedType"); // Reverse PInvoke will copy 3 times. Two are from the same paths as the PInvoke, // and the third is from the reverse P/Invoke call. - Assert.Equal(3, (int)testMethod.Invoke(testInstance, null)); + Assert.Equal(3 + platformExtra, (int)testMethod.Invoke(testInstance, null)); } catch (Exception ex) { Console.WriteLine(ex); return 101; } + + try + { + CopyConstructorsInArgumentStackSlots(); + } + catch (Exception ex) + { + Console.WriteLine(ex); + return 101; + } + return 100; } + public static void CopyConstructorsInArgumentStackSlots() + { + Assembly ijwNativeDll = Assembly.Load("IjwCopyConstructorMarshaler"); + Type testType = ijwNativeDll.GetType("TestClass"); + object testInstance = Activator.CreateInstance(testType); + MethodInfo testMethod = testType.GetMethod("ExposedThisCopyConstructorScenario"); + + Assert.Equal(0, (int)testMethod.Invoke(testInstance, null)); + } + [DllImport("kernel32.dll")] static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, int dwFlags); diff --git a/src/tests/Interop/IJW/CopyConstructorMarshaler/IjwCopyConstructorMarshaler.cpp b/src/tests/Interop/IJW/CopyConstructorMarshaler/IjwCopyConstructorMarshaler.cpp index bd1d1b80829d3c..c3d50cf77836ea 100644 --- a/src/tests/Interop/IJW/CopyConstructorMarshaler/IjwCopyConstructorMarshaler.cpp +++ b/src/tests/Interop/IJW/CopyConstructorMarshaler/IjwCopyConstructorMarshaler.cpp @@ -1,5 +1,90 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#pragma unmanaged +#include +#include + +namespace ExposedThis +{ + struct Relative; + + std::vector relatives; + + int numMissedCopies = 0; + + struct Relative + { + void* relative; + Relative() + { + std::cout << "Registering " << std::hex << this << "\n"; + relatives.push_back(this); + relative = this - 1; + } + + Relative(const Relative& other) + { + std::cout << "Registering copy of " << std::hex << &other << " at " << this << "\n"; + relatives.push_back(this); + relative = this - 1; + } + + ~Relative() + { + auto location = std::find(relatives.begin(), relatives.end(), this); + if (location != relatives.end()) + { + std::cout << "Unregistering " << std::hex << this << "\n"; + relatives.erase(location); + } + else + { + std::cout << "Error: Relative object " << std::hex << this << " not registered\n"; + numMissedCopies++; + } + + if (relative != this - 1) + { + std::cout << " Error: Relative object " << std::hex << this << " has invalid relative pointer " << std::hex << relative << "\n"; + numMissedCopies++; + } + } + }; + + void UseRelative(Relative rel) + { + std::cout << "Unmanaged: Using relative at address " << std::hex << &rel << "\n"; + } + + void UseRelativeManaged(Relative rel); + + void CallRelative() + { + Relative rel; + UseRelativeManaged(rel); + } + +#pragma managed + + int RunScenario() + { + // Managed to unmanaged + { + Relative rel; + UseRelative(rel); + } + + // Unmanaged to managed + CallRelative(); + + return numMissedCopies; + } + + void UseRelativeManaged(Relative rel) + { + std::cout << "Managed: Using relative at address " << std::hex << &rel << "\n"; + } +} #pragma managed class A @@ -102,4 +187,9 @@ public ref class TestClass B b; return GetCopyCount_ViaManaged(b); } + + int ExposedThisCopyConstructorScenario() + { + return ExposedThis::RunScenario(); + } }; diff --git a/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.cs b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.cs index 37e8e3c48f5202..ace0f2ba315243 100644 --- a/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.cs +++ b/src/tests/Interop/PInvoke/Miscellaneous/CopyCtor/CopyCtorTest.cs @@ -13,21 +13,43 @@ static unsafe class CopyCtor public static unsafe int StructWithCtorTest(StructWithCtor* ptrStruct, ref StructWithCtor refStruct) { if (ptrStruct->_instanceField != 1) + { + Console.WriteLine($"Fail: {ptrStruct->_instanceField} != {1}"); return 1; + } if (refStruct._instanceField != 2) + { + Console.WriteLine($"Fail: {refStruct._instanceField} != {2}"); return 2; + } - if (StructWithCtor.CopyCtorCallCount != 2) + int expectedCallCount = 2; + if (RuntimeInformation.ProcessArchitecture == Architecture.X86) + { + expectedCallCount = 4; + } + + if (StructWithCtor.CopyCtorCallCount != expectedCallCount) + { + Console.WriteLine($"Fail: {StructWithCtor.CopyCtorCallCount} != {expectedCallCount}"); return 3; - if (StructWithCtor.DtorCallCount != 2) + } + if (StructWithCtor.DtorCallCount != expectedCallCount) + { + Console.WriteLine($"Fail: {StructWithCtor.DtorCallCount} != {expectedCallCount}"); return 4; - + } return 100; } public static unsafe int Main() { + if (!TestLibrary.PlatformDetection.IsWindows) + { + return 100; + } + TestDelegate del = (TestDelegate)Delegate.CreateDelegate(typeof(TestDelegate), typeof(CopyCtor).GetMethod("StructWithCtorTest")); StructWithCtor s1 = new StructWithCtor(); StructWithCtor s2 = new StructWithCtor(); From 3ea18f2b16a8ead9d888e26d031f264abe27b12c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 11:34:12 +0200 Subject: [PATCH 666/783] [release/8.0] Don't unset ALPN list pointer during ALPN selection callback. (#99670) * Don't unset ALPN list pointer during ALPN selection callback. * Move AlpnHandle.Free to ReleaseHandle --------- Co-authored-by: Radek Zikmund --- .../Interop.OpenSsl.cs | 3 --- .../Interop.Ssl.cs | 12 ++++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index d180aa98538f1f..c526f37b0b9fbf 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -694,9 +694,6 @@ private static unsafe int AlpnServerSelectCallback(IntPtr ssl, byte** outp, byte return Ssl.SSL_TLSEXT_ERR_ALERT_FATAL; } - // reset application data to avoid dangling pointer. - Ssl.SslSetData(ssl, IntPtr.Zero); - GCHandle protocolHandle = GCHandle.FromIntPtr(sslData); if (!(protocolHandle.Target is List protocolList)) { diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs index 71d23c26d34532..0848ca5ed21bc4 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs @@ -420,12 +420,6 @@ protected override void Dispose(bool disposing) _writeBio?.Dispose(); } - if (AlpnHandle.IsAllocated) - { - Interop.Ssl.SslSetData(handle, IntPtr.Zero); - AlpnHandle.Free(); - } - base.Dispose(disposing); } @@ -438,6 +432,12 @@ protected override bool ReleaseHandle() SslContextHandle?.DangerousRelease(); + if (AlpnHandle.IsAllocated) + { + Interop.Ssl.SslSetData(handle, IntPtr.Zero); + AlpnHandle.Free(); + } + IntPtr h = handle; SetHandle(IntPtr.Zero); Interop.Ssl.SslDestroy(h); // will free the handles underlying _readBio and _writeBio From 9de64a25bb81552de32a928c4219b09ffa49e30d Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Tue, 2 Apr 2024 15:34:38 -0300 Subject: [PATCH 667/783] Backport of #99843 (#99844) --- src/mono/mono/component/debugger-agent.c | 1 + .../debugger/DebuggerTestSuite/MiscTests.cs | 19 +++++++++++++++++++ .../tests/debugger-test/debugger-test.cs | 9 +++++++++ 3 files changed, 29 insertions(+) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index 80918c38876824..5389f30803ccf1 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -5589,6 +5589,7 @@ decode_value_compute_size (MonoType *t, int type, MonoDomain *domain, guint8 *bu if (type != t->type && !MONO_TYPE_IS_REFERENCE (t) && !(t->type == MONO_TYPE_I && type == MONO_TYPE_VALUETYPE) && !(type == VALUE_TYPE_ID_FIXED_ARRAY) && + !(type == MDBGPROT_VALUE_TYPE_ID_NULL) && !(t->type == MONO_TYPE_U && type == MONO_TYPE_VALUETYPE) && !(t->type == MONO_TYPE_PTR && type == MONO_TYPE_I8) && !(t->type == MONO_TYPE_FNPTR && type == MONO_TYPE_I8) && diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/MiscTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/MiscTests.cs index 35fd867cb7ab49..5a65521a13747d 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/MiscTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/MiscTests.cs @@ -1188,5 +1188,24 @@ public async Task TestDebugUsingMultiThreadedRuntime() Assert.Equal(locals[1]["value"]["type"], "number"); Assert.Equal(locals[1]["name"], "currentThread"); } + + [Fact] + public async Task InspectSpanByte() + { + var expression = $"{{ invoke_static_method('[debugger-test] SpanByte:Run'); }}"; + + await EvaluateAndCheck( + "window.setTimeout(function() {" + expression + "; }, 1);", + "dotnet://debugger-test.dll/debugger-test.cs", 1664, 8, + "SpanByte.Run", + wait_for_event_fn: async (pause_location) => + { + var id = pause_location["callFrames"][0]["callFrameId"].Value(); + await EvaluateOnCallFrameAndCheck(id, + ("span", TObject("System.Span", null)) + ); + } + ); + } } } diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-test.cs index 4a43032a4b3943..b69baf08552d56 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-test.cs @@ -1656,3 +1656,12 @@ public void CallMethod() public int myField; } + +public class SpanByte +{ + public static void Run() + { + System.Span span = new (); + System.Diagnostics.Debugger.Break(); + } +} \ No newline at end of file From f8132e673bfba45e71db14eac12cf1effddbac41 Mon Sep 17 00:00:00 2001 From: vseanreesermsft <78103370+vseanreesermsft@users.noreply.github.com> Date: Tue, 2 Apr 2024 16:25:58 -0700 Subject: [PATCH 668/783] Update branding to 8.0.5 (#100547) --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 5fb45746a0f2e9..a43374e3220d23 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,11 +1,11 @@ - 8.0.4 + 8.0.5 8 0 - 4 + 5 8.0.100 7.0.$([MSBuild]::Add($(PatchVersion),14)) 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) From 7d45915a7e7ba7b830d90998eca4cd064b6626b7 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 4 Apr 2024 13:37:06 -0700 Subject: [PATCH 669/783] [release/8.0-staging] Ensure that Sse3.MoveAndDuplicate correctly tracks supporting SIMD scalar loads (#100417) * Ensure that Sse3.MoveAndDuplicate correctly tracks supporting SIMD scalar loads (#97783) * Add a regression test for dotnet/runtime#100404 * Fix the regression test to not be called Main --- src/coreclr/jit/lowerxarch.cpp | 37 ++++++++++++++----- .../JitBlue/Runtime_100404/Runtime_100404.cs | 31 ++++++++++++++++ .../Runtime_100404/Runtime_100404.csproj | 8 ++++ 3 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_100404/Runtime_100404.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_100404/Runtime_100404.csproj diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index f0e7fc6322f2be..dad1df9ffcfb76 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -7652,15 +7652,17 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre } case NI_SSE2_ConvertToVector128Double: - case NI_SSE3_MoveAndDuplicate: case NI_AVX_ConvertToVector256Double: + case NI_AVX512F_ConvertToVector512Double: + case NI_AVX512F_VL_ConvertToVector128Double: + case NI_AVX512F_VL_ConvertToVector256Double: { assert(!supportsSIMDScalarLoads); // Most instructions under the non-VEX encoding require aligned operands. // Those used for Sse2.ConvertToVector128Double (CVTDQ2PD and CVTPS2PD) - // and Sse3.MoveAndDuplicate (MOVDDUP) are exceptions and don't fail for - // unaligned inputs as they read mem64 (half the vector width) instead + // are exceptions and don't fail for unaligned inputs as they read half + // the vector width instead supportsAlignedSIMDLoads = !comp->opts.MinOpts(); supportsUnalignedSIMDLoads = true; @@ -7668,10 +7670,29 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre const unsigned expectedSize = genTypeSize(parentNode->TypeGet()) / 2; const unsigned operandSize = genTypeSize(childNode->TypeGet()); - // For broadcasts we can only optimize constants and memory operands - const bool broadcastIsContainable = childNode->OperIsConst() || childNode->isMemoryOp(); - supportsGeneralLoads = - broadcastIsContainable && supportsUnalignedSIMDLoads && (operandSize >= expectedSize); + if (childNode->OperIsConst() || childNode->isMemoryOp()) + { + // For broadcasts we can only optimize constants and memory operands + // since we're going from a smaller base type to a larger base type + supportsGeneralLoads = supportsUnalignedSIMDLoads && (operandSize >= expectedSize); + } + break; + } + + case NI_SSE3_MoveAndDuplicate: + { + // Most instructions under the non-VEX encoding require aligned operands. + // Those used for Sse3.MoveAndDuplicate (MOVDDUP) are exceptions and don't + // fail for unaligned inputs as they read half the vector width instead + + supportsAlignedSIMDLoads = !comp->opts.MinOpts(); + supportsUnalignedSIMDLoads = true; + + const unsigned expectedSize = genTypeSize(parentNode->TypeGet()) / 2; + const unsigned operandSize = genTypeSize(childNode->TypeGet()); + + supportsGeneralLoads = supportsUnalignedSIMDLoads && (operandSize >= expectedSize); + supportsSIMDScalarLoads = true; break; } @@ -7697,8 +7718,6 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre break; } } - - assert(supportsSIMDScalarLoads == false); break; } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_100404/Runtime_100404.cs b/src/tests/JIT/Regression/JitBlue/Runtime_100404/Runtime_100404.cs new file mode 100644 index 00000000000000..0725a973faedf5 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_100404/Runtime_100404.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using Xunit; + +public static class Runtime_100404 +{ + [Fact] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TestMultiplyVector128DoubleByConstant() + { + Vector128 result = Map(Vector128.One, new FloatPoint(2.0, 3.0)); + Assert.Equal(2.0, result[0]); + Assert.Equal(2.0, result[1]); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Vector128 Map(Vector128 m0, FloatPoint point) + { + return m0 * Vector128.Create(point.X); + } + + private struct FloatPoint(double x, double y) + { + public double X = x; + public double Y = y; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_100404/Runtime_100404.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_100404/Runtime_100404.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_100404/Runtime_100404.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From 7ae2d0071e394fcafeec4f55e9b5faff5992b88e Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 4 Apr 2024 14:40:03 -0700 Subject: [PATCH 670/783] Fix allocation of empty array in the frozen heap for collectible types (#100444) (#100509) * Fix allocation of empty array in the frozen heap for collectible types (#100437) * Remove Optimize from csproj * Add test for generic with static * Apply suggestions from code review * Better test * Disable tests on Mono --------- Co-authored-by: Alexandre Mutel --- src/coreclr/jit/importer.cpp | 3 +- src/coreclr/vm/frozenobjectheap.cpp | 1 + .../JitBlue/Runtime_100437/Runtime_100437.cs | 112 ++++++++++++++++++ .../Runtime_100437/Runtime_100437.csproj | 5 + 4 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_100437/Runtime_100437.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_100437/Runtime_100437.csproj diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 6087b1499301cf..9bf654ffc35a20 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -9393,7 +9393,8 @@ void Compiler::impImportBlockCode(BasicBlock* block) CORINFO_FIELD_INFO fi; eeGetFieldInfo(&fldToken, CORINFO_ACCESS_SET, &fi); unsigned flagsToCheck = CORINFO_FLG_FIELD_STATIC | CORINFO_FLG_FIELD_FINAL; - if ((fi.fieldFlags & flagsToCheck) == flagsToCheck) + if (((fi.fieldFlags & flagsToCheck) == flagsToCheck) && + ((info.compCompHnd->getClassAttribs(info.compClassHnd) & CORINFO_FLG_SHAREDINST) == 0)) { #ifdef FEATURE_READYTORUN if (opts.IsReadyToRun()) diff --git a/src/coreclr/vm/frozenobjectheap.cpp b/src/coreclr/vm/frozenobjectheap.cpp index 8f11f3c8c74d64..bd25b4ba7b3e3d 100644 --- a/src/coreclr/vm/frozenobjectheap.cpp +++ b/src/coreclr/vm/frozenobjectheap.cpp @@ -47,6 +47,7 @@ Object* FrozenObjectHeapManager::TryAllocateObject(PTR_MethodTable type, size_t _ASSERT(type != nullptr); _ASSERT(FOH_COMMIT_SIZE >= MIN_OBJECT_SIZE); + _ASSERT(!type->Collectible()); // Currently we don't support frozen objects with special alignment requirements // TODO: We should also give up on arrays of doubles on 32-bit platforms. diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_100437/Runtime_100437.cs b/src/tests/JIT/Regression/JitBlue/Runtime_100437/Runtime_100437.cs new file mode 100644 index 00000000000000..810b99acab3076 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_100437/Runtime_100437.cs @@ -0,0 +1,112 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Loader; +using Xunit; + +public class Runtime_100437 +{ + [Fact] + [SkipOnMono("PlatformDetection.IsPreciseGcSupported false on mono", TestPlatforms.Any)] + public static void TestNonCollectibleType() => TestCollectibleReadOnlyStatics(nameof(NonCollectibleType)); + + [Fact] + [SkipOnMono("PlatformDetection.IsPreciseGcSupported false on mono", TestPlatforms.Any)] + public static void TestNonCollectibleTypeInSharedGenericCode() => TestCollectibleReadOnlyStatics(nameof(NonCollectibleTypeInSharedGenericCode)); + + [Fact] + [SkipOnMono("PlatformDetection.IsPreciseGcSupported false on mono", TestPlatforms.Any)] + public static void TestNonCollectibleArrayTypeInSharedGenericCode() => TestCollectibleReadOnlyStatics(nameof(NonCollectibleArrayTypeInSharedGenericCode)); + + [Fact] + [SkipOnMono("PlatformDetection.IsPreciseGcSupported false on mono", TestPlatforms.Any)] + public static void TestCollectibleEmptyArray() => TestCollectibleReadOnlyStatics(nameof(CollectibleEmptyArray)); + + private static void TestCollectibleReadOnlyStatics(string methodName) + { + string assemblyPath = typeof(Runtime_100437).Assembly.Location; + + // Skip this test for single file + if (string.IsNullOrEmpty(assemblyPath)) + return; + + WeakReference wr = CreateReadOnlyStaticWeakReference(); + + for (int i = 0; i < 10; i++) + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + + if (!IsTargetAlive(wr)) + return; + } + + throw new Exception("Test failed - readonly static has not been collected."); + + [MethodImpl(MethodImplOptions.NoInlining)] + WeakReference CreateReadOnlyStaticWeakReference() + { + AssemblyLoadContext alc = new CollectibleAssemblyLoadContext(); + Assembly a = alc.LoadFromAssemblyPath(assemblyPath); + return (WeakReference)a.GetType(nameof(Runtime_100437)).GetMethod(methodName).Invoke(null, new object[] { typeof(Runtime_100437).Assembly }); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + bool IsTargetAlive(WeakReference wr) + { + return wr.Target != null; + } + } + + public static WeakReference NonCollectibleType(Assembly assemblyInDefaultContext) + { + return new WeakReference(Holder.Singleton, trackResurrection: true); + } + + public static WeakReference NonCollectibleTypeInSharedGenericCode(Assembly assemblyInDefaultContext) + { + // Create instance of a non-collectible generic type definition over a collectible type + var type = assemblyInDefaultContext.GetType("Runtime_100437+GenericHolder`1", throwOnError: true).MakeGenericType(typeof(Runtime_100437)); + var field = type.GetField("Singleton", BindingFlags.Static | BindingFlags.Public); + return new WeakReference(field.GetValue(null), trackResurrection: true); + } + + public static WeakReference NonCollectibleArrayTypeInSharedGenericCode(Assembly assemblyInDefaultContext) + { + // Create instance of a non-collectible generic type definition over a collectible type + var type = assemblyInDefaultContext.GetType("Runtime_100437+GenericArrayHolder`1", throwOnError: true).MakeGenericType(typeof(Runtime_100437)); + var field = type.GetField("Singleton", BindingFlags.Static | BindingFlags.Public); + return new WeakReference(field.GetValue(null), trackResurrection: true); + } + + public static WeakReference CollectibleEmptyArray(Assembly assemblyInDefaultContext) + { + return new WeakReference(Array.Empty(), trackResurrection: true); + } + + private class CollectibleAssemblyLoadContext : AssemblyLoadContext + { + public CollectibleAssemblyLoadContext() + : base(isCollectible: true) + { + } + } + + private class Holder + { + public static readonly object Singleton = new object(); + } + + private class GenericHolder + { + public static readonly object Singleton = new object(); + } + + private class GenericArrayHolder + { + public static readonly int[] Singleton = new int[0]; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_100437/Runtime_100437.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_100437/Runtime_100437.csproj new file mode 100644 index 00000000000000..197767e2c4e249 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_100437/Runtime_100437.csproj @@ -0,0 +1,5 @@ + + + + + From 479defb07667b30c3eb69bdcea00e75e1ef0b015 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:42:15 -0700 Subject: [PATCH 671/783] Use clang --version to get Apple toolset version (#100199) Fixes #100189 Co-authored-by: Jan Kotas --- .../BuildIntegration/Microsoft.NETCore.Native.Unix.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index c9ae3083cf5cd4..8013121de4f8bb 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -166,7 +166,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + From d49f6cfd43af1e022d96d1a62c441134aff1f813 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:26:58 -0700 Subject: [PATCH 672/783] Azure Linux 3.0 deps package (#100684) Co-authored-by: Nikola Milosavljevic --- src/installer/pkg/sfx/installers.proj | 1 + .../dotnet-runtime-deps/dotnet-runtime-deps-azl.3.proj | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-azl.3.proj diff --git a/src/installer/pkg/sfx/installers.proj b/src/installer/pkg/sfx/installers.proj index 06e366db911d06..7f4ce6b9c1c409 100644 --- a/src/installer/pkg/sfx/installers.proj +++ b/src/installer/pkg/sfx/installers.proj @@ -10,6 +10,7 @@ + diff --git a/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-azl.3.proj b/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-azl.3.proj new file mode 100644 index 00000000000000..ee363967c365fd --- /dev/null +++ b/src/installer/pkg/sfx/installers/dotnet-runtime-deps/dotnet-runtime-deps-azl.3.proj @@ -0,0 +1,10 @@ + + + false + azl.3 + + + + + + From 2b94204aa04ae15806c559820517cba31acf1b2b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:31:12 +0200 Subject: [PATCH 673/783] Fix Http2 deadlock (#100086) Co-authored-by: Miha Zupan --- .../SocketsHttpHandler/Http2Connection.cs | 23 +++++++++++++++---- .../SocketsHttpHandler/HttpConnectionPool.cs | 6 ++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs index 5b795f0a88457d..54857380a3a2c8 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs @@ -257,6 +257,7 @@ private void Shutdown() if (NetEventSource.Log.IsEnabled()) Trace($"{nameof(_shutdown)}={_shutdown}, {nameof(_abortException)}={_abortException}"); Debug.Assert(Monitor.IsEntered(SyncObject)); + Debug.Assert(!_pool.HasSyncObjLock); if (!_shutdown) { @@ -276,6 +277,8 @@ private void Shutdown() public bool TryReserveStream() { + Debug.Assert(!_pool.HasSyncObjLock); + lock (SyncObject) { if (_shutdown) @@ -302,6 +305,8 @@ public bool TryReserveStream() // Otherwise, will be called when the request is complete and stream is closed. public void ReleaseStream() { + Debug.Assert(!_pool.HasSyncObjLock); + lock (SyncObject) { if (NetEventSource.Log.IsEnabled()) Trace($"{nameof(_streamsInUse)}={_streamsInUse}"); @@ -333,6 +338,8 @@ public void ReleaseStream() // Returns false to indicate that the connection is shutting down and cannot be used anymore public Task WaitForAvailableStreamsAsync() { + Debug.Assert(!_pool.HasSyncObjLock); + lock (SyncObject) { Debug.Assert(_availableStreamsWaiter is null, "As used currently, shouldn't already have a waiter"); @@ -730,6 +737,7 @@ private void ProcessAltSvcFrame(FrameHeader frameHeader) { if (NetEventSource.Log.IsEnabled()) Trace($"{frameHeader}"); Debug.Assert(frameHeader.Type == FrameType.AltSvc); + Debug.Assert(!Monitor.IsEntered(SyncObject)); ReadOnlySpan span = _incomingBuffer.ActiveSpan.Slice(0, frameHeader.PayloadLength); @@ -1308,6 +1316,8 @@ private Task SendRstStreamAsync(int streamId, Http2ProtocolErrorCode errorCode) internal void HeartBeat() { + Debug.Assert(!_pool.HasSyncObjLock); + if (_shutdown) return; @@ -1800,10 +1810,14 @@ private void ExtendWindow(int amount) public override long GetIdleTicks(long nowTicks) { - lock (SyncObject) - { - return _streamsInUse == 0 ? base.GetIdleTicks(nowTicks) : 0; - } + // The pool is holding the lock as part of its scavenging logic. + // We must not lock on Http2Connection.SyncObj here as that could lead to lock ordering problems. + Debug.Assert(_pool.HasSyncObjLock); + + // There is a race condition here where the connection pool may see this connection as idle right before + // we start processing a new request and start its disposal. This is okay as we will either + // return false from TryReserveStream, or process pending requests before tearing down the transport. + return _streamsInUse == 0 ? base.GetIdleTicks(nowTicks) : 0; } /// Abort all streams and cause further processing to fail. @@ -1992,6 +2006,7 @@ private static TaskCompletionSourceWithCancellation CreateSuccessfullyComp public async Task SendAsync(HttpRequestMessage request, bool async, CancellationToken cancellationToken) { Debug.Assert(async); + Debug.Assert(!_pool.HasSyncObjLock); if (NetEventSource.Log.IsEnabled()) Trace($"Sending request: {request}"); try diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs index 163a9492ab41cf..17ed807eeefec4 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs @@ -406,7 +406,7 @@ private object SyncObj } } - private bool HasSyncObjLock => Monitor.IsEntered(_availableHttp11Connections); + public bool HasSyncObjLock => Monitor.IsEntered(_availableHttp11Connections); // Overview of connection management (mostly HTTP version independent): // @@ -459,6 +459,8 @@ private static void ThrowGetVersionException(HttpRequestMessage request, int des private bool CheckExpirationOnGet(HttpConnectionBase connection) { + Debug.Assert(!HasSyncObjLock); + TimeSpan pooledConnectionLifetime = _poolManager.Settings._pooledConnectionLifetime; if (pooledConnectionLifetime != Timeout.InfiniteTimeSpan) { @@ -2000,6 +2002,7 @@ private void ReturnHttp2Connection(Http2Connection connection, bool isNewConnect { if (NetEventSource.Log.IsEnabled()) connection.Trace($"{nameof(isNewConnection)}={isNewConnection}"); + Debug.Assert(!HasSyncObjLock); Debug.Assert(isNewConnection || initialRequestWaiter is null, "Shouldn't have a request unless the connection is new"); if (!isNewConnection && CheckExpirationOnReturn(connection)) @@ -2403,6 +2406,7 @@ internal void HeartBeat() localHttp2Connections = _availableHttp2Connections?.ToArray(); } + // Avoid calling HeartBeat under the lock, as it may call back into HttpConnectionPool.InvalidateHttp2Connection. if (localHttp2Connections is not null) { foreach (Http2Connection http2Connection in localHttp2Connections) From c031937d06e535f22785cd13198b47c3f72adbc1 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Tue, 9 Apr 2024 13:12:37 -0500 Subject: [PATCH 674/783] Fix unbound MAC work in GetCertContentType --- .../X509Certificates/X509Pal.macOS.cs | 7 +++- ...PfxIterationCountTests.X509Certificate2.cs | 29 +++++++++++++ .../tests/X509Certificates/TestData.cs | 20 +++++++++ .../pal_x509.c | 41 +++---------------- 4 files changed, 59 insertions(+), 38 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.macOS.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.macOS.cs index 7a6e555b12ceda..a9cda7f973509d 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.macOS.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.macOS.cs @@ -111,6 +111,7 @@ private static DSA DecodeDsaPublicKey(byte[] encodedKeyValue, byte[] encodedPara public X509ContentType GetCertContentType(ReadOnlySpan rawData) { const int errSecUnknownFormat = -25257; + if (rawData.IsEmpty) { // Throw to match Windows and Unix behavior. @@ -119,7 +120,7 @@ public X509ContentType GetCertContentType(ReadOnlySpan rawData) X509ContentType contentType = Interop.AppleCrypto.X509GetContentType(rawData); - // Apple doesn't seem to recognize PFX files with no MAC, so try a quick maybe-it's-a-PFX test + // Apple's native check can't check for PKCS12, so do a quick decode test to see if it is PKCS12 / PFX. if (contentType == X509ContentType.Unknown) { try @@ -128,9 +129,11 @@ public X509ContentType GetCertContentType(ReadOnlySpan rawData) { fixed (byte* pin = rawData) { + AsnValueReader reader = new AsnValueReader(rawData, AsnEncodingRules.BER); + using (var manager = new PointerMemoryManager(pin, rawData.Length)) { - PfxAsn.Decode(manager.Memory, AsnEncodingRules.BER); + PfxAsn.Decode(ref reader, manager.Memory, out _); } contentType = X509ContentType.Pkcs12; diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxIterationCountTests.X509Certificate2.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxIterationCountTests.X509Certificate2.cs index 6e4697f406548d..ce5c3be483da75 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxIterationCountTests.X509Certificate2.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxIterationCountTests.X509Certificate2.cs @@ -1,8 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.DotNet.RemoteExecutor; +using Microsoft.DotNet.XUnitExtensions; +using Xunit; + namespace System.Security.Cryptography.X509Certificates.Tests { + [SkipOnPlatform(TestPlatforms.Browser, "Browser doesn't support X.509 certificates")] public class PfxIterationCountTests_X509Certificate2 : PfxIterationCountTests { internal override X509Certificate Import(byte[] blob) @@ -22,5 +27,29 @@ internal override X509Certificate Import(string fileName, string password) internal override X509Certificate Import(string fileName, SecureString password) => new X509Certificate2(fileName, password); + + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public static void Import_IterationCountLimitExceeded_ThrowsInAllottedTime() + { + const int AllottedTime = 5000; + + if (!PfxTests.Pkcs12PBES2Supported) + { + throw new SkipTestException("Pkcs12NoPassword100MRounds uses PBES2, which is not supported on this version."); + } + + RemoteInvokeOptions options = new() + { + TimeOut = AllottedTime + }; + + RemoteExecutor.Invoke(static () => + { + byte[] blob = TestData.Pkcs12NoPassword100MRounds; + CryptographicException ce = Assert.Throws(() => new X509Certificate2(blob)); + Assert.Contains(FwlinkId, ce.Message); + }, options).Dispose(); + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs index 0d7633f9992ef2..0e0295ecf7f6e7 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs @@ -3437,6 +3437,26 @@ internal static DSAParameters GetDSA1024Params() "04020105000420AD0EB570ACFB8357A8E99B17672353CFBA69C76FFE5B6BC113" + "05577F12AE24040408D04E60444B79672302030927C1").HexToByteArray(); + internal static readonly byte[] Pkcs12NoPassword100MRounds = Convert.FromBase64String( + "MIIDygIBAzCCA4QGCSqGSIb3DQEHAaCCA3UEggNxMIIDbTCCA2kGCSqGSIb3DQEHBqCCA1owggNW" + + "AgEAMIIDTwYJKoZIhvcNAQcBMF4GCSqGSIb3DQEFDTBRMDAGCSqGSIb3DQEFDDAjBBCNparJkj/3" + + "Uk8N7n0KCMeQAgEBMAwGCCqGSIb3DQILBQAwHQYJYIZIAWUDBAEqBBAcqpBrSDFcXYAWVWKcsEi9" + + "gIIC4P/ANdPYWI1vBH1U5sZGMIwLjY96pYaBelyZd0ZfKA8QfGHVNP9+E9hplBKGvRfIMiqmFutj" + + "RO4v7Ls8HZEk0hwBt9+6zXPWDJLxBDfSMHUd08+ZAH1yzEqq8aBMyIRVHOQkJFuFuCQJ9Ke5HzVi" + + "39S1rgHpnKYFvy+xZAhgI9OO1YxuFt4P9nhlEV/JCoyEQ/2iY99kKc3z7ArrV7BBFhfYGKhWQCBu" + + "kAmNBKweRldNWgDuW21WJEl5sByOmyDwpiK55Zxy1K1aIY8DYJTtIzzcX4CILaj6tClMH1G9w4jW" + + "BkQI2CG4vCsMl/28BbIP9EyH2C+gBAxvc1N32y3NSvO0/GPVenmQFF9KBMc4FVy4Z21syMKzUkBi" + + "PtIbDkcQbGAfyPgFk4SXCgn8OpIIvOOGI50/r+Hj14qex9VIrlwAAWCH8Y+YjwqFAQJYHQpb47zp" + + "B1fTwJFOrsXrBgLUzJLZKLR43yW2E9u6b8RsTuFHjh985naCHLuWPYOXS1zduBpHKpwoPUyCwD2r" + + "DAokCvA7RCsSXroUkpJarN4CAqsEB8COnzV1Dl2xcAYMerJxrTCKX6WIQUYo0/qeCoqTT38lDAlE" + + "7Ydjyx12iVM6eWejAdjORvlVtCQQtCxz8fZpdFGbMP8rf35A8hu++e4u0CLHnhTx38zPIm6H6YfN" + + "qj5h1Kz0xLzqnRfa7EGfDEERSHOy/DqNY4nUNG2DTjGOHy1QJelToG7Vo2L7CCZV+leX0nwLNExf" + + "hKEp+uQCiYSJe9iDm9fS9VymED79OJbr2bxdq3MggEGksLZv/H0ZT8Wsue0vq9jQ6J6YIEM+DKYr" + + "Zt2l4WgTBEKbpqmRvOqYRh9O8Sp+3IRNPzMC2ehzlYXqoPbtG4vxpoRsAMCM/W2x61jbsBSaNSFA" + + "eaUwcnKswRg30UonHUAIOJkqtadI57WE/Rat5eHVyya9f7ZN8bTFZjx0BQs6Bo8PK9yfqoidSN8w" + + "PTAfMAcGBSsOAwIaBBTt8zpgzygINykjoAwr2GKEywYFwgQUA+L1vfCVASwiE++gTfRgIScMGycC" + + "BAX14QA="); + internal static readonly byte[] Pkcs12OpenSslOneCertDefaultEmptyPassword = ("308209CF0201033082098506092A864886F70D010701A0820976048209723082" + "096E308203E206092A864886F70D010706A08203D3308203CF020100308203C8" + diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509.c b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509.c index 8335c1c362c0ea..94e22f28c8794a 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509.c @@ -70,7 +70,6 @@ PAL_X509ContentType AppleCryptoNative_X509GetContentType(uint8_t* pbData, int32_ // The sniffing order is: // * X509 DER // * PKCS7 PEM/DER - // * PKCS12 DER (or PEM if Apple has non-standard support for that) // * X509 PEM or PEM aggregate (or DER, but that already matched) // // If the X509 PEM check is done first SecItemImport will erroneously match @@ -78,6 +77,11 @@ PAL_X509ContentType AppleCryptoNative_X509GetContentType(uint8_t* pbData, int32_ // // Likewise, if the X509 DER check isn't done first, Apple will report it as // being a PKCS#7. + // + // This does not attempt to open a PFX / PKCS12 as Apple does not provide + // a suitable API to determine if it is PKCS12 without doing potentially + // unbound MAC / KDF work. Instead, let that return Unknown and let the managed + // decoding do the check. SecCertificateRef certref = SecCertificateCreateWithData(NULL, cfData); if (certref != NULL) @@ -104,41 +108,6 @@ PAL_X509ContentType AppleCryptoNative_X509GetContentType(uint8_t* pbData, int32_ } } - dataFormat = kSecFormatPKCS12; - actualFormat = dataFormat; - itemType = kSecItemTypeAggregate; - actualType = itemType; - - osStatus = SecItemImport(cfData, NULL, &actualFormat, &actualType, 0, NULL, NULL, NULL); - - if (osStatus == errSecPassphraseRequired) - { - dataFormat = kSecFormatPKCS12; - actualFormat = dataFormat; - itemType = kSecItemTypeAggregate; - actualType = itemType; - - SecItemImportExportKeyParameters importParams; - memset(&importParams, 0, sizeof(SecItemImportExportKeyParameters)); - - importParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; - importParams.passphrase = CFSTR(""); - - osStatus = SecItemImport(cfData, NULL, &actualFormat, &actualType, 0, &importParams, NULL, NULL); - - CFRelease(importParams.passphrase); - importParams.passphrase = NULL; - } - - if (osStatus == noErr || osStatus == errSecPkcs12VerifyFailure) - { - if (actualType == itemType && actualFormat == dataFormat) - { - CFRelease(cfData); - return PAL_Pkcs12; - } - } - dataFormat = kSecFormatX509Cert; actualFormat = dataFormat; itemType = kSecItemTypeCertificate; From 0de70233bd5b314e2923540a03f50820c47f0f2d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 10 Apr 2024 10:38:45 -0700 Subject: [PATCH 675/783] [release/8.0-staging] Update CI builds to not use VS Previews (#100622) * Update CI to use Release VS2022. * fixing incorrect deletion --------- Co-authored-by: Manish Godse <61718172+mangod9@users.noreply.github.com> --- eng/pipelines/common/xplat-setup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/common/xplat-setup.yml b/eng/pipelines/common/xplat-setup.yml index 1f0c10166950c9..eb19570aeecac2 100644 --- a/eng/pipelines/common/xplat-setup.yml +++ b/eng/pipelines/common/xplat-setup.yml @@ -168,12 +168,12 @@ jobs: # Official Build Windows Pool ${{ if and(or(eq(parameters.osGroup, 'windows'), eq(parameters.jobParameters.hostedOs, 'windows')), ne(variables['System.TeamProject'], 'public')) }}: name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2022preview.amd64 + demands: ImageOverride -equals windows.vs2022.amd64 # Public Windows Build Pool ${{ if and(or(eq(parameters.osGroup, 'windows'), eq(parameters.jobParameters.hostedOs, 'windows')), eq(variables['System.TeamProject'], 'public')) }}: name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals windows.vs2022preview.amd64.open + demands: ImageOverride -equals windows.vs2022.amd64.open ${{ if eq(parameters.helixQueuesTemplate, '') }}: From 4be29ad2fea7233f0e3397bfa8ca85ba3ef75ba1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 18:02:41 -0700 Subject: [PATCH 676/783] Update dependencies from https://github.com/dotnet/hotreload-utils build 20240410.1 (#100892) Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.24072.2 -> To Version 8.0.0-alpha.0.24210.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 7bad61f7c233a2..5705ffaa791b44 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -354,9 +354,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 67613417f5e1af250e6ddfba79f8f2885d8e90fb - + https://github.com/dotnet/hotreload-utils - bc857c64c5c5f1fc73048261e8f471c3310224d2 + 85d6e21ac1d4e0977dfd1321131be0c912d70d80 https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index 609fc2931ba508..efa8e0d81207cc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -186,7 +186,7 @@ 8.0.0-prerelease.24112.2 8.0.0-prerelease.24112.2 8.0.0-prerelease.24112.2 - 8.0.0-alpha.0.24072.2 + 8.0.0-alpha.0.24210.1 2.4.2 1.0.0 2.4.5 From cca20d0d1bb6d9ad4f2d090f1348326df5cd158b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 18:04:55 -0700 Subject: [PATCH 677/783] [release/8.0-staging] Update dependencies from dotnet/runtime-assets (#100073) * Update dependencies from https://github.com/dotnet/runtime-assets build Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240320.9 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24115.2 -> To Version 8.0.0-beta.24170.9 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 56 ++++++++++++++++++++--------------------- eng/Versions.props | 28 ++++++++++----------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5705ffaa791b44..199869d6638945 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -185,57 +185,57 @@ https://github.com/dotnet/arcade da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 https://github.com/dotnet/llvm-project @@ -358,9 +358,9 @@ https://github.com/dotnet/hotreload-utils 85d6e21ac1d4e0977dfd1321131be0c912d70d80 - + https://github.com/dotnet/runtime-assets - 0827f89642a6443c96a87990e3b910f6aa4cc4ed + 7b59ef83974ea3c51d746daf415e9ea9991f9519 https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index efa8e0d81207cc..d57332064415a9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -143,20 +143,20 @@ 4.5.0 8.0.0-rc.1.23406.6 - 8.0.0-beta.24115.2 - 8.0.0-beta.24115.2 - 8.0.0-beta.24115.2 - 8.0.0-beta.24115.2 - 8.0.0-beta.24115.2 - 8.0.0-beta.24115.2 - 8.0.0-beta.24115.2 - 8.0.0-beta.24115.2 - 8.0.0-beta.24115.2 - 8.0.0-beta.24115.2 - 8.0.0-beta.24115.2 - 8.0.0-beta.24115.2 - 8.0.0-beta.24115.2 - 8.0.0-beta.24115.2 + 8.0.0-beta.24170.9 + 8.0.0-beta.24170.9 + 8.0.0-beta.24170.9 + 8.0.0-beta.24170.9 + 8.0.0-beta.24170.9 + 8.0.0-beta.24170.9 + 8.0.0-beta.24170.9 + 8.0.0-beta.24170.9 + 8.0.0-beta.24170.9 + 8.0.0-beta.24170.9 + 8.0.0-beta.24170.9 + 8.0.0-beta.24170.9 + 8.0.0-beta.24170.9 + 8.0.0-beta.24170.9 1.0.0-prerelease.23566.3 1.0.0-prerelease.23566.3 From f37eb4819791a97b31fc6e29bae44589c0f88319 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 18:39:59 -0700 Subject: [PATCH 678/783] Update dependencies from https://github.com/dotnet/source-build-externals build 20240311.1 (#99601) Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24161.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ba7e1dd064f612..9c16befab48017 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -104,9 +104,9 @@ 453a37ef7ae6c335cd49b3b9ab7713c87faeb265 - + https://github.com/dotnet/source-build-externals - 7a9b99e457a2b9792a3c17ccaf95d80038725108 + 00fb7841c80b44262646e57bcfbe90a1b7bc3151 From 0a26d20196959c00f58cc3c6146e51fc27ad97c8 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 18:47:49 -0700 Subject: [PATCH 679/783] Update dependencies from https://github.com/dotnet/xharness build 20240408.4 (#100883) Microsoft.DotNet.XHarness.CLI , Microsoft.DotNet.XHarness.TestRunners.Common , Microsoft.DotNet.XHarness.TestRunners.Xunit From Version 8.0.0-prerelease.24112.2 -> To Version 8.0.0-prerelease.24208.4 Co-authored-by: dotnet-maestro[bot] Co-authored-by: Eric StJohn --- .config/dotnet-tools.json | 2 +- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 6ff1559a00ab98..deb9fb7b21bbe9 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "8.0.0-prerelease.24112.2", + "version": "8.0.0-prerelease.24208.4", "commands": [ "xharness" ] diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9c16befab48017..04d3d4429ae044 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -322,17 +322,17 @@ https://github.com/dotnet/runtime edbd5c769a19798b6955050baccf99e6797d3208 - + https://github.com/dotnet/xharness - c055cc57f21796e79ace4bca2b070a8777f2446a + 9d21162000c444b2da3d6cdd805d43e1af51453a - + https://github.com/dotnet/xharness - c055cc57f21796e79ace4bca2b070a8777f2446a + 9d21162000c444b2da3d6cdd805d43e1af51453a - + https://github.com/dotnet/xharness - c055cc57f21796e79ace4bca2b070a8777f2446a + 9d21162000c444b2da3d6cdd805d43e1af51453a https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index f6572992a769a0..65b9a961153dee 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -183,9 +183,9 @@ 1.1.0 17.4.0-preview-20220707-01 - 8.0.0-prerelease.24112.2 - 8.0.0-prerelease.24112.2 - 8.0.0-prerelease.24112.2 + 8.0.0-prerelease.24208.4 + 8.0.0-prerelease.24208.4 + 8.0.0-prerelease.24208.4 8.0.0-alpha.0.24210.1 2.4.2 1.0.0 From 24e52a017380186e436457c80651e2cdec1b0095 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 08:46:02 -0700 Subject: [PATCH 680/783] [release/8.0-staging] Update dependencies from dotnet/source-build-reference-packages (#99902) * Update dependencies from https://github.com/dotnet/source-build-reference-packages build Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.24061.1 -> To Version 8.0.0-alpha.1.24163.3 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.24061.1 -> To Version 8.0.0-alpha.1.24163.3 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20240313.3 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.24061.1 -> To Version 8.0.0-alpha.1.24163.3 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20240313.3 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.24061.1 -> To Version 8.0.0-alpha.1.24163.3 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 04d3d4429ae044..2f0eb24fa191e1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -99,9 +99,9 @@ 08a90ca2c88b17f1b5d081318354a41db0882cff - + https://github.com/dotnet/source-build-reference-packages - 453a37ef7ae6c335cd49b3b9ab7713c87faeb265 + 79827eed138fd2575a8b24820b4f385ee4ffb6e6 From b1b775e58c07060150e75e73779661f8949524d2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 09:04:59 -0700 Subject: [PATCH 681/783] [release/8.0-staging] Update dependencies from dotnet/source-build-externals (#100015) * Update dependencies from https://github.com/dotnet/source-build-externals build Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24168.2 * Update dependencies from https://github.com/dotnet/source-build-externals build Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24168.2 * Update dependencies from https://github.com/dotnet/source-build-externals build Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24168.2 * Update dependencies from https://github.com/dotnet/source-build-externals build Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24168.2 * Update dependencies from https://github.com/dotnet/source-build-externals build Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24168.2 * Update dependencies from https://github.com/dotnet/source-build-externals build Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24168.2 * Update dependencies from https://github.com/dotnet/source-build-externals build Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24175.3 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240325.3 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24161.1 -> To Version 8.0.0-alpha.1.24175.3 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Eric StJohn --- NuGet.config | 2 ++ eng/Version.Details.xml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/NuGet.config b/NuGet.config index 50349586bd3ca0..86aa3c4ed5898c 100644 --- a/NuGet.config +++ b/NuGet.config @@ -10,6 +10,8 @@ + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2f0eb24fa191e1..7fabe9f4f99e30 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -104,9 +104,9 @@ 79827eed138fd2575a8b24820b4f385ee4ffb6e6 - + https://github.com/dotnet/source-build-externals - 00fb7841c80b44262646e57bcfbe90a1b7bc3151 + 300e99190e6ae1983681694dbdd5f75f0c692081 From be4864fe7e2c46d60ca2bfaeb4495ccc6568c610 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 09:07:03 -0700 Subject: [PATCH 682/783] Update dependencies from https://github.com/dotnet/runtime-assets build 20240411.2 (#100958) Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24170.9 -> To Version 8.0.0-beta.24211.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 56 ++++++++++++++++++++--------------------- eng/Versions.props | 28 ++++++++++----------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 7fabe9f4f99e30..be15ab04c85430 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -185,57 +185,57 @@ https://github.com/dotnet/arcade da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d https://github.com/dotnet/llvm-project @@ -358,9 +358,9 @@ https://github.com/dotnet/hotreload-utils 85d6e21ac1d4e0977dfd1321131be0c912d70d80 - + https://github.com/dotnet/runtime-assets - 7b59ef83974ea3c51d746daf415e9ea9991f9519 + dc8ac7417ae48bfbf2516a346723107af0ad603d https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index 65b9a961153dee..b1ee52a12ebd6f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -143,20 +143,20 @@ 4.5.0 8.0.0-rc.1.23406.6 - 8.0.0-beta.24170.9 - 8.0.0-beta.24170.9 - 8.0.0-beta.24170.9 - 8.0.0-beta.24170.9 - 8.0.0-beta.24170.9 - 8.0.0-beta.24170.9 - 8.0.0-beta.24170.9 - 8.0.0-beta.24170.9 - 8.0.0-beta.24170.9 - 8.0.0-beta.24170.9 - 8.0.0-beta.24170.9 - 8.0.0-beta.24170.9 - 8.0.0-beta.24170.9 - 8.0.0-beta.24170.9 + 8.0.0-beta.24211.2 + 8.0.0-beta.24211.2 + 8.0.0-beta.24211.2 + 8.0.0-beta.24211.2 + 8.0.0-beta.24211.2 + 8.0.0-beta.24211.2 + 8.0.0-beta.24211.2 + 8.0.0-beta.24211.2 + 8.0.0-beta.24211.2 + 8.0.0-beta.24211.2 + 8.0.0-beta.24211.2 + 8.0.0-beta.24211.2 + 8.0.0-beta.24211.2 + 8.0.0-beta.24211.2 1.0.0-prerelease.23566.3 1.0.0-prerelease.23566.3 From 78cde8759043a7f2b550c7278cfb40d9909071dc Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 09:53:51 -0700 Subject: [PATCH 683/783] Update dependencies from https://github.com/dotnet/arcade build 20240404.3 (#100885) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24113.2 -> To Version 8.0.0-beta.24204.3 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 72 ++--- eng/Versions.props | 30 +- eng/common/SetupNugetSources.ps1 | 26 +- eng/common/templates-official/job/job.yml | 264 ++++++++++++++++ .../templates-official/job/onelocbuild.yml | 112 +++++++ .../job/publish-build-assets.yml | 155 ++++++++++ .../templates-official/job/source-build.yml | 67 ++++ .../job/source-index-stage1.yml | 68 +++++ .../templates-official/jobs/codeql-build.yml | 31 ++ eng/common/templates-official/jobs/jobs.yml | 97 ++++++ .../templates-official/jobs/source-build.yml | 46 +++ .../post-build/common-variables.yml | 22 ++ .../post-build/post-build.yml | 285 ++++++++++++++++++ .../post-build/setup-maestro-vars.yml | 70 +++++ .../post-build/trigger-subscription.yml | 13 + .../steps/add-build-to-channel.yml | 13 + .../templates-official/steps/build-reason.yml | 12 + .../steps/component-governance.yml | 13 + .../steps/execute-codeql.yml | 32 ++ .../templates-official/steps/execute-sdl.yml | 88 ++++++ .../steps/generate-sbom.yml | 48 +++ .../templates-official/steps/publish-logs.yml | 23 ++ .../templates-official/steps/retain-build.yml | 28 ++ .../steps/send-to-helix.yml | 91 ++++++ .../templates-official/steps/source-build.yml | 129 ++++++++ .../variables/pool-providers.yml | 45 +++ .../variables/sdl-variables.yml | 7 + eng/common/templates/job/job.yml | 4 + .../templates/steps/component-governance.yml | 2 +- eng/common/templates/steps/generate-sbom.yml | 2 +- global.json | 6 +- 31 files changed, 1832 insertions(+), 69 deletions(-) create mode 100644 eng/common/templates-official/job/job.yml create mode 100644 eng/common/templates-official/job/onelocbuild.yml create mode 100644 eng/common/templates-official/job/publish-build-assets.yml create mode 100644 eng/common/templates-official/job/source-build.yml create mode 100644 eng/common/templates-official/job/source-index-stage1.yml create mode 100644 eng/common/templates-official/jobs/codeql-build.yml create mode 100644 eng/common/templates-official/jobs/jobs.yml create mode 100644 eng/common/templates-official/jobs/source-build.yml create mode 100644 eng/common/templates-official/post-build/common-variables.yml create mode 100644 eng/common/templates-official/post-build/post-build.yml create mode 100644 eng/common/templates-official/post-build/setup-maestro-vars.yml create mode 100644 eng/common/templates-official/post-build/trigger-subscription.yml create mode 100644 eng/common/templates-official/steps/add-build-to-channel.yml create mode 100644 eng/common/templates-official/steps/build-reason.yml create mode 100644 eng/common/templates-official/steps/component-governance.yml create mode 100644 eng/common/templates-official/steps/execute-codeql.yml create mode 100644 eng/common/templates-official/steps/execute-sdl.yml create mode 100644 eng/common/templates-official/steps/generate-sbom.yml create mode 100644 eng/common/templates-official/steps/publish-logs.yml create mode 100644 eng/common/templates-official/steps/retain-build.yml create mode 100644 eng/common/templates-official/steps/send-to-helix.yml create mode 100644 eng/common/templates-official/steps/source-build.yml create mode 100644 eng/common/templates-official/variables/pool-providers.yml create mode 100644 eng/common/templates-official/variables/sdl-variables.yml diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index be15ab04c85430..f91d99477583be 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -111,9 +111,9 @@ - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba @@ -121,69 +121,69 @@ 73f0850939d96131c28cf6ea6ee5aacb4da0083a - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba https://github.com/dotnet/runtime-assets @@ -334,9 +334,9 @@ https://github.com/dotnet/xharness 9d21162000c444b2da3d6cdd805d43e1af51453a - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 188340e12c0a372b1681ad6a5e72c608021efdba https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index b1ee52a12ebd6f..afc5da2fc7d595 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -87,21 +87,21 @@ 8.0.100 - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 - 2.5.1-beta.24113.2 - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 - 8.0.0-beta.24113.2 + 8.0.0-beta.24204.3 + 8.0.0-beta.24204.3 + 8.0.0-beta.24204.3 + 8.0.0-beta.24204.3 + 8.0.0-beta.24204.3 + 2.5.1-beta.24204.3 + 8.0.0-beta.24204.3 + 8.0.0-beta.24204.3 + 8.0.0-beta.24204.3 + 8.0.0-beta.24204.3 + 8.0.0-beta.24204.3 + 8.0.0-beta.24204.3 + 8.0.0-beta.24204.3 + 8.0.0-beta.24204.3 + 8.0.0-beta.24204.3 6.0.0-preview.1.102 diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1 index 6c65e81925f2a3..efa2fd72bfaa22 100644 --- a/eng/common/SetupNugetSources.ps1 +++ b/eng/common/SetupNugetSources.ps1 @@ -35,7 +35,7 @@ Set-StrictMode -Version 2.0 . $PSScriptRoot\tools.ps1 # Add source entry to PackageSources -function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Username, $Password) { +function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Username, $pwd) { $packageSource = $sources.SelectSingleNode("add[@key='$SourceName']") if ($packageSource -eq $null) @@ -48,12 +48,11 @@ function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Usern else { Write-Host "Package source $SourceName already present." } - - AddCredential -Creds $creds -Source $SourceName -Username $Username -Password $Password + AddCredential -Creds $creds -Source $SourceName -Username $Username -pwd $pwd } # Add a credential node for the specified source -function AddCredential($creds, $source, $username, $password) { +function AddCredential($creds, $source, $username, $pwd) { # Looks for credential configuration for the given SourceName. Create it if none is found. $sourceElement = $creds.SelectSingleNode($Source) if ($sourceElement -eq $null) @@ -82,17 +81,18 @@ function AddCredential($creds, $source, $username, $password) { $passwordElement.SetAttribute("key", "ClearTextPassword") $sourceElement.AppendChild($passwordElement) | Out-Null } - $passwordElement.SetAttribute("value", $Password) + + $passwordElement.SetAttribute("value", $pwd) } -function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $Password) { +function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $pwd) { $maestroPrivateSources = $Sources.SelectNodes("add[contains(@key,'darc-int')]") Write-Host "Inserting credentials for $($maestroPrivateSources.Count) Maestro's private feeds." ForEach ($PackageSource in $maestroPrivateSources) { Write-Host "`tInserting credential for Maestro's feed:" $PackageSource.Key - AddCredential -Creds $creds -Source $PackageSource.Key -Username $Username -Password $Password + AddCredential -Creds $creds -Source $PackageSource.Key -Username $Username -pwd $pwd } } @@ -144,13 +144,13 @@ if ($disabledSources -ne $null) { $userName = "dn-bot" # Insert credential nodes for Maestro's private feeds -InsertMaestroPrivateFeedCredentials -Sources $sources -Creds $creds -Username $userName -Password $Password +InsertMaestroPrivateFeedCredentials -Sources $sources -Creds $creds -Username $userName -pwd $Password # 3.1 uses a different feed url format so it's handled differently here $dotnet31Source = $sources.SelectSingleNode("add[@key='dotnet3.1']") if ($dotnet31Source -ne $null) { - AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2" -Creds $creds -Username $userName -Password $Password - AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -Password $Password + AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password + AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password } $dotnetVersions = @('5','6','7','8') @@ -159,9 +159,9 @@ foreach ($dotnetVersion in $dotnetVersions) { $feedPrefix = "dotnet" + $dotnetVersion; $dotnetSource = $sources.SelectSingleNode("add[@key='$feedPrefix']") if ($dotnetSource -ne $null) { - AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal/nuget/v2" -Creds $creds -Username $userName -Password $Password - AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/v2" -Creds $creds -Username $userName -Password $Password + AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password + AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password } } -$doc.Save($filename) +$doc.Save($filename) \ No newline at end of file diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml new file mode 100644 index 00000000000000..1f035fee73f4a9 --- /dev/null +++ b/eng/common/templates-official/job/job.yml @@ -0,0 +1,264 @@ +# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, +# and some (Microbuild) should only be applied to non-PR cases for internal builds. + +parameters: +# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + cancelTimeoutInMinutes: '' + condition: '' + container: '' + continueOnError: false + dependsOn: '' + displayName: '' + pool: '' + steps: [] + strategy: '' + timeoutInMinutes: '' + variables: [] + workspace: '' + templateContext: '' + +# Job base template specific parameters + # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md + artifacts: '' + enableMicrobuild: false + enablePublishBuildArtifacts: false + enablePublishBuildAssets: false + enablePublishTestResults: false + enablePublishUsingPipelines: false + enableBuildRetry: false + disableComponentGovernance: '' + componentGovernanceIgnoreDirectories: '' + mergeTestResults: false + testRunTitle: '' + testResultsFormat: '' + name: '' + preSteps: [] + runAsPublic: false +# Sbom related params + enableSbom: true + PackageVersion: 7.0.0 + BuildDropPath: '$(Build.SourcesDirectory)/artifacts' + +jobs: +- job: ${{ parameters.name }} + + ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}: + cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }} + + ${{ if ne(parameters.condition, '') }}: + condition: ${{ parameters.condition }} + + ${{ if ne(parameters.container, '') }}: + container: ${{ parameters.container }} + + ${{ if ne(parameters.continueOnError, '') }}: + continueOnError: ${{ parameters.continueOnError }} + + ${{ if ne(parameters.dependsOn, '') }}: + dependsOn: ${{ parameters.dependsOn }} + + ${{ if ne(parameters.displayName, '') }}: + displayName: ${{ parameters.displayName }} + + ${{ if ne(parameters.pool, '') }}: + pool: ${{ parameters.pool }} + + ${{ if ne(parameters.strategy, '') }}: + strategy: ${{ parameters.strategy }} + + ${{ if ne(parameters.timeoutInMinutes, '') }}: + timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + + ${{ if ne(parameters.templateContext, '') }}: + templateContext: ${{ parameters.templateContext }} + + variables: + - ${{ if ne(parameters.enableTelemetry, 'false') }}: + - name: DOTNET_CLI_TELEMETRY_PROFILE + value: '$(Build.Repository.Uri)' + - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}: + - name: EnableRichCodeNavigation + value: 'true' + # Retry signature validation up to three times, waiting 2 seconds between attempts. + # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures + - name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY + value: 3,2000 + - ${{ each variable in parameters.variables }}: + # handle name-value variable syntax + # example: + # - name: [key] + # value: [value] + - ${{ if ne(variable.name, '') }}: + - name: ${{ variable.name }} + value: ${{ variable.value }} + + # handle variable groups + - ${{ if ne(variable.group, '') }}: + - group: ${{ variable.group }} + + # handle template variable syntax + # example: + # - template: path/to/template.yml + # parameters: + # [key]: [value] + - ${{ if ne(variable.template, '') }}: + - template: ${{ variable.template }} + ${{ if ne(variable.parameters, '') }}: + parameters: ${{ variable.parameters }} + + # handle key-value variable syntax. + # example: + # - [key]: [value] + - ${{ if and(eq(variable.name, ''), eq(variable.group, ''), eq(variable.template, '')) }}: + - ${{ each pair in variable }}: + - name: ${{ pair.key }} + value: ${{ pair.value }} + + # DotNet-HelixApi-Access provides 'HelixApiAccessToken' for internal builds + - ${{ if and(eq(parameters.enableTelemetry, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: DotNet-HelixApi-Access + + ${{ if ne(parameters.workspace, '') }}: + workspace: ${{ parameters.workspace }} + + steps: + - ${{ if ne(parameters.preSteps, '') }}: + - ${{ each preStep in parameters.preSteps }}: + - ${{ preStep }} + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - task: MicroBuildSigningPlugin@4 + displayName: Install MicroBuild plugin + inputs: + signType: $(_SignType) + zipSources: false + feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + env: + TeamName: $(_TeamName) + MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)' + continueOnError: ${{ parameters.continueOnError }} + condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + + - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}: + - task: NuGetAuthenticate@1 + + - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}: + - task: DownloadPipelineArtifact@2 + inputs: + buildType: current + artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }} + targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }} + itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }} + + - ${{ each step in parameters.steps }}: + - ${{ step }} + + - ${{ if eq(parameters.enableRichCodeNavigation, true) }}: + - task: RichCodeNavIndexer@0 + displayName: RichCodeNav Upload + inputs: + languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }} + environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'production') }} + richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin + uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }} + continueOnError: true + + - template: /eng/common/templates-official/steps/component-governance.yml + parameters: + ${{ if eq(parameters.disableComponentGovernance, '') }}: + ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: + disableComponentGovernance: false + ${{ else }}: + disableComponentGovernance: true + ${{ else }}: + disableComponentGovernance: ${{ parameters.disableComponentGovernance }} + componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} + + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: MicroBuildCleanup@1 + displayName: Execute Microbuild cleanup tasks + condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + env: + TeamName: $(_TeamName) + + - ${{ if ne(parameters.artifacts.publish, '') }}: + - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: + - task: CopyFiles@2 + displayName: Gather binaries for publish to artifacts + inputs: + SourceFolder: 'artifacts/bin' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin' + - task: CopyFiles@2 + displayName: Gather packages for publish to artifacts + inputs: + SourceFolder: 'artifacts/packages' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages' + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish pipeline artifacts + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts' + PublishLocation: Container + ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} + continueOnError: true + condition: always() + - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: + - task: 1ES.PublishPipelineArtifact@1 + inputs: + targetPath: 'artifacts/log' + artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} + displayName: 'Publish logs' + continueOnError: true + condition: always() + + - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish Logs + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' + PublishLocation: Container + ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + continueOnError: true + condition: always() + + - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}: + - task: PublishTestResults@2 + displayName: Publish XUnit Test Results + inputs: + testResultsFormat: 'xUnit' + testResultsFiles: '*.xml' + searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit + mergeTestResults: ${{ parameters.mergeTestResults }} + continueOnError: true + condition: always() + - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}: + - task: PublishTestResults@2 + displayName: Publish TRX Test Results + inputs: + testResultsFormat: 'VSTest' + testResultsFiles: '*.trx' + searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx + mergeTestResults: ${{ parameters.mergeTestResults }} + continueOnError: true + condition: always() + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: + - template: /eng/common/templates-official/steps/generate-sbom.yml + parameters: + PackageVersion: ${{ parameters.packageVersion}} + BuildDropPath: ${{ parameters.buildDropPath }} + IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} + + - ${{ if eq(parameters.enableBuildRetry, 'true') }}: + - task: 1ES.PublishPipelineArtifact@1 + inputs: + targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration' + artifactName: 'BuildConfiguration' + displayName: 'Publish build retry configuration' + continueOnError: true \ No newline at end of file diff --git a/eng/common/templates-official/job/onelocbuild.yml b/eng/common/templates-official/job/onelocbuild.yml new file mode 100644 index 00000000000000..52b4d05d3f8dd6 --- /dev/null +++ b/eng/common/templates-official/job/onelocbuild.yml @@ -0,0 +1,112 @@ +parameters: + # Optional: dependencies of the job + dependsOn: '' + + # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool + pool: '' + + CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex + GithubPat: $(BotAccount-dotnet-bot-repo-PAT) + + SourcesDirectory: $(Build.SourcesDirectory) + CreatePr: true + AutoCompletePr: false + ReusePr: true + UseLfLineEndings: true + UseCheckedInLocProjectJson: false + SkipLocProjectJsonGeneration: false + LanguageSet: VS_Main_Languages + LclSource: lclFilesInRepo + LclPackageId: '' + RepoType: gitHub + GitHubOrg: dotnet + MirrorRepo: '' + MirrorBranch: main + condition: '' + JobNameSuffix: '' + +jobs: +- job: OneLocBuild${{ parameters.JobNameSuffix }} + + dependsOn: ${{ parameters.dependsOn }} + + displayName: OneLocBuild${{ parameters.JobNameSuffix }} + + variables: + - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat + - name: _GenerateLocProjectArguments + value: -SourcesDirectory ${{ parameters.SourcesDirectory }} + -LanguageSet "${{ parameters.LanguageSet }}" + -CreateNeutralXlfs + - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}: + - name: _GenerateLocProjectArguments + value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson + - template: /eng/common/templates-official/variables/pool-providers.yml + + ${{ if ne(parameters.pool, '') }}: + pool: ${{ parameters.pool }} + ${{ if eq(parameters.pool, '') }}: + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022 + os: windows + + steps: + - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}: + - task: Powershell@2 + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1 + arguments: $(_GenerateLocProjectArguments) + displayName: Generate LocProject.json + condition: ${{ parameters.condition }} + + - task: OneLocBuild@2 + displayName: OneLocBuild + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + inputs: + locProj: eng/Localize/LocProject.json + outDir: $(Build.ArtifactStagingDirectory) + lclSource: ${{ parameters.LclSource }} + lclPackageId: ${{ parameters.LclPackageId }} + isCreatePrSelected: ${{ parameters.CreatePr }} + isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }} + ${{ if eq(parameters.CreatePr, true) }}: + isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }} + ${{ if eq(parameters.RepoType, 'gitHub') }}: + isShouldReusePrSelected: ${{ parameters.ReusePr }} + packageSourceAuth: patAuth + patVariable: ${{ parameters.CeapexPat }} + ${{ if eq(parameters.RepoType, 'gitHub') }}: + repoType: ${{ parameters.RepoType }} + gitHubPatVariable: "${{ parameters.GithubPat }}" + ${{ if ne(parameters.MirrorRepo, '') }}: + isMirrorRepoSelected: true + gitHubOrganization: ${{ parameters.GitHubOrg }} + mirrorRepo: ${{ parameters.MirrorRepo }} + mirrorBranch: ${{ parameters.MirrorBranch }} + condition: ${{ parameters.condition }} + + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish Localization Files + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)/loc' + PublishLocation: Container + ArtifactName: Loc + condition: ${{ parameters.condition }} + + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish LocProject.json + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/eng/Localize/' + PublishLocation: Container + ArtifactName: Loc + condition: ${{ parameters.condition }} \ No newline at end of file diff --git a/eng/common/templates-official/job/publish-build-assets.yml b/eng/common/templates-official/job/publish-build-assets.yml new file mode 100644 index 00000000000000..589ac80a18b749 --- /dev/null +++ b/eng/common/templates-official/job/publish-build-assets.yml @@ -0,0 +1,155 @@ +parameters: + configuration: 'Debug' + + # Optional: condition for the job to run + condition: '' + + # Optional: 'true' if future jobs should run even if this job fails + continueOnError: false + + # Optional: dependencies of the job + dependsOn: '' + + # Optional: Include PublishBuildArtifacts task + enablePublishBuildArtifacts: false + + # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool + pool: {} + + # Optional: should run as a public build even in the internal project + # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + runAsPublic: false + + # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing + publishUsingPipelines: false + + # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing + publishAssetsImmediately: false + + artifactsPublishingAdditionalParameters: '' + + signingValidationAdditionalParameters: '' + +jobs: +- job: Asset_Registry_Publish + + dependsOn: ${{ parameters.dependsOn }} + timeoutInMinutes: 150 + + ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: + displayName: Publish Assets + ${{ else }}: + displayName: Publish to Build Asset Registry + + variables: + - template: /eng/common/templates-official/variables/pool-providers.yml + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: Publish-Build-Assets + - group: AzureDevOps-Artifact-Feeds-Pats + - name: runCodesignValidationInjection + value: false + - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: + - template: /eng/common/templates-official/post-build/common-variables.yml + + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: + name: NetCore1ESPool-Publishing-Internal + image: windows.vs2019.amd64 + os: windows + steps: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: DownloadBuildArtifacts@0 + displayName: Download artifact + inputs: + artifactName: AssetManifests + downloadPath: '$(Build.StagingDirectory)/Download' + checkDownloadedFiles: true + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + + - task: NuGetAuthenticate@1 + + - task: PowerShell@2 + displayName: Publish Build Assets + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet + /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' + /p:BuildAssetRegistryToken=$(MaestroAccessToken) + /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com + /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} + /p:OfficialBuildId=$(Build.BuildNumber) + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + + - task: powershell@2 + displayName: Create ReleaseConfigs Artifact + inputs: + targetType: inline + script: | + New-Item -Path "$(Build.StagingDirectory)/ReleaseConfigs" -ItemType Directory -Force + $filePath = "$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt" + Add-Content -Path $filePath -Value $(BARBuildId) + Add-Content -Path $filePath -Value "$(DefaultChannels)" + Add-Content -Path $filePath -Value $(IsStableBuild) + + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish ReleaseConfigs Artifact + inputs: + PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs' + PublishLocation: Container + ArtifactName: ReleaseConfigs + + - task: powershell@2 + displayName: Check if SymbolPublishingExclusionsFile.txt exists + inputs: + targetType: inline + script: | + $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt" + if(Test-Path -Path $symbolExclusionfile) + { + Write-Host "SymbolExclusionFile exists" + Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]true" + } + else{ + Write-Host "Symbols Exclusion file does not exists" + Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]false" + } + + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish SymbolPublishingExclusionsFile Artifact + condition: eq(variables['SymbolExclusionFile'], 'true') + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' + PublishLocation: Container + ArtifactName: ReleaseConfigs + + - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: + - template: /eng/common/templates-official/post-build/setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: PowerShell@2 + displayName: Publish Using Darc + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 + arguments: -BuildId $(BARBuildId) + -PublishingInfraVersion 3 + -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' + -MaestroToken '$(MaestroApiAccessToken)' + -WaitPublishingFinish true + -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' + -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' + + - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: + - template: /eng/common/templates-official/steps/publish-logs.yml + parameters: + JobLabel: 'Publish_Artifacts_Logs' diff --git a/eng/common/templates-official/job/source-build.yml b/eng/common/templates-official/job/source-build.yml new file mode 100644 index 00000000000000..f193dfbe236683 --- /dev/null +++ b/eng/common/templates-official/job/source-build.yml @@ -0,0 +1,67 @@ +parameters: + # This template adds arcade-powered source-build to CI. The template produces a server job with a + # default ID 'Source_Build_Complete' to put in a dependency list if necessary. + + # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed. + jobNamePrefix: 'Source_Build' + + # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for + # managed-only repositories. This is an object with these properties: + # + # name: '' + # The name of the job. This is included in the job ID. + # targetRID: '' + # The name of the target RID to use, instead of the one auto-detected by Arcade. + # nonPortable: false + # Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than + # linux-x64), and compiling against distro-provided packages rather than portable ones. + # skipPublishValidation: false + # Disables publishing validation. By default, a check is performed to ensure no packages are + # published by source-build. + # container: '' + # A container to use. Runs in docker. + # pool: {} + # A pool to use. Runs directly on an agent. + # buildScript: '' + # Specifies the build script to invoke to perform the build in the repo. The default + # './build.sh' should work for typical Arcade repositories, but this is customizable for + # difficult situations. + # jobProperties: {} + # A list of job properties to inject at the top level, for potential extensibility beyond + # container and pool. + platform: {} + +jobs: +- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }} + displayName: Source-Build (${{ parameters.platform.name }}) + + ${{ each property in parameters.platform.jobProperties }}: + ${{ property.key }}: ${{ property.value }} + + ${{ if ne(parameters.platform.container, '') }}: + container: ${{ parameters.platform.container }} + + ${{ if eq(parameters.platform.pool, '') }}: + # The default VM host AzDO pool. This should be capable of running Docker containers: almost all + # source-build builds run in Docker, including the default managed platform. + # /eng/common/templates-official/variables/pool-providers.yml can't be used here (some customers declare variables already), so duplicate its logic + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')] + demands: ImageOverride -equals Build.Ubuntu.1804.Amd64.Open + + ${{ if eq(variables['System.TeamProject'], 'internal') }}: + name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')] + image: 1es-mariner-2 + os: linux + + ${{ if ne(parameters.platform.pool, '') }}: + pool: ${{ parameters.platform.pool }} + + workspace: + clean: all + + steps: + - template: /eng/common/templates-official/steps/source-build.yml + parameters: + platform: ${{ parameters.platform }} diff --git a/eng/common/templates-official/job/source-index-stage1.yml b/eng/common/templates-official/job/source-index-stage1.yml new file mode 100644 index 00000000000000..f0513aee5b0da6 --- /dev/null +++ b/eng/common/templates-official/job/source-index-stage1.yml @@ -0,0 +1,68 @@ +parameters: + runAsPublic: false + sourceIndexPackageVersion: 1.0.1-20230228.2 + sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json + sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" + preSteps: [] + binlogPath: artifacts/log/Debug/Build.binlog + condition: '' + dependsOn: '' + pool: '' + +jobs: +- job: SourceIndexStage1 + dependsOn: ${{ parameters.dependsOn }} + condition: ${{ parameters.condition }} + variables: + - name: SourceIndexPackageVersion + value: ${{ parameters.sourceIndexPackageVersion }} + - name: SourceIndexPackageSource + value: ${{ parameters.sourceIndexPackageSource }} + - name: BinlogPath + value: ${{ parameters.binlogPath }} + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: source-dot-net stage1 variables + - template: /eng/common/templates-official/variables/pool-providers.yml + + ${{ if ne(parameters.pool, '') }}: + pool: ${{ parameters.pool }} + ${{ if eq(parameters.pool, '') }}: + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $(DncEngPublicBuildPool) + demands: ImageOverride -equals windows.vs2019.amd64.open + ${{ if eq(variables['System.TeamProject'], 'internal') }}: + name: $(DncEngInternalBuildPool) + image: windows.vs2022.amd64 + os: windows + + steps: + - ${{ each preStep in parameters.preSteps }}: + - ${{ preStep }} + + - task: UseDotNet@2 + displayName: Use .NET Core SDK 6 + inputs: + packageType: sdk + version: 6.0.x + installationPath: $(Agent.TempDirectory)/dotnet + workingDirectory: $(Agent.TempDirectory) + + - script: | + $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + displayName: Download Tools + # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. + workingDirectory: $(Agent.TempDirectory) + + - script: ${{ parameters.sourceIndexBuildCommand }} + displayName: Build Repository + + - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output + displayName: Process Binlog into indexable sln + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) + displayName: Upload stage1 artifacts to source index + env: + BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url) diff --git a/eng/common/templates-official/jobs/codeql-build.yml b/eng/common/templates-official/jobs/codeql-build.yml new file mode 100644 index 00000000000000..b68d3c2f31990f --- /dev/null +++ b/eng/common/templates-official/jobs/codeql-build.yml @@ -0,0 +1,31 @@ +parameters: + # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md + continueOnError: false + # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + jobs: [] + # Optional: if specified, restore and use this version of Guardian instead of the default. + overrideGuardianVersion: '' + +jobs: +- template: /eng/common/templates-official/jobs/jobs.yml + parameters: + enableMicrobuild: false + enablePublishBuildArtifacts: false + enablePublishTestResults: false + enablePublishBuildAssets: false + enablePublishUsingPipelines: false + enableTelemetry: true + + variables: + - group: Publish-Build-Assets + # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in + # sync with the packages.config file. + - name: DefaultGuardianVersion + value: 0.109.0 + - name: GuardianPackagesConfigFile + value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config + - name: GuardianVersion + value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} + + jobs: ${{ parameters.jobs }} + diff --git a/eng/common/templates-official/jobs/jobs.yml b/eng/common/templates-official/jobs/jobs.yml new file mode 100644 index 00000000000000..857a0f8ba43e84 --- /dev/null +++ b/eng/common/templates-official/jobs/jobs.yml @@ -0,0 +1,97 @@ +parameters: + # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md + continueOnError: false + + # Optional: Include PublishBuildArtifacts task + enablePublishBuildArtifacts: false + + # Optional: Enable publishing using release pipelines + enablePublishUsingPipelines: false + + # Optional: Enable running the source-build jobs to build repo from source + enableSourceBuild: false + + # Optional: Parameters for source-build template. + # See /eng/common/templates-official/jobs/source-build.yml for options + sourceBuildParameters: [] + + graphFileGeneration: + # Optional: Enable generating the graph files at the end of the build + enabled: false + # Optional: Include toolset dependencies in the generated graph files + includeToolset: false + + # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + jobs: [] + + # Optional: Override automatically derived dependsOn value for "publish build assets" job + publishBuildAssetsDependsOn: '' + + # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage. + publishAssetsImmediately: false + + # Optional: If using publishAssetsImmediately and additional parameters are needed, can be used to send along additional parameters (normally sent to post-build.yml) + artifactsPublishingAdditionalParameters: '' + signingValidationAdditionalParameters: '' + + # Optional: should run as a public build even in the internal project + # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + runAsPublic: false + + enableSourceIndex: false + sourceIndexParams: {} + +# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, +# and some (Microbuild) should only be applied to non-PR cases for internal builds. + +jobs: +- ${{ each job in parameters.jobs }}: + - template: ../job/job.yml + parameters: + # pass along parameters + ${{ each parameter in parameters }}: + ${{ if ne(parameter.key, 'jobs') }}: + ${{ parameter.key }}: ${{ parameter.value }} + + # pass along job properties + ${{ each property in job }}: + ${{ if ne(property.key, 'job') }}: + ${{ property.key }}: ${{ property.value }} + + name: ${{ job.job }} + +- ${{ if eq(parameters.enableSourceBuild, true) }}: + - template: /eng/common/templates-official/jobs/source-build.yml + parameters: + allCompletedJobId: Source_Build_Complete + ${{ each parameter in parameters.sourceBuildParameters }}: + ${{ parameter.key }}: ${{ parameter.value }} + +- ${{ if eq(parameters.enableSourceIndex, 'true') }}: + - template: ../job/source-index-stage1.yml + parameters: + runAsPublic: ${{ parameters.runAsPublic }} + ${{ each parameter in parameters.sourceIndexParams }}: + ${{ parameter.key }}: ${{ parameter.value }} + +- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}: + - template: ../job/publish-build-assets.yml + parameters: + continueOnError: ${{ parameters.continueOnError }} + dependsOn: + - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.publishBuildAssetsDependsOn }}: + - ${{ job.job }} + - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.jobs }}: + - ${{ job.job }} + - ${{ if eq(parameters.enableSourceBuild, true) }}: + - Source_Build_Complete + + runAsPublic: ${{ parameters.runAsPublic }} + publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }} + publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }} + enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }} diff --git a/eng/common/templates-official/jobs/source-build.yml b/eng/common/templates-official/jobs/source-build.yml new file mode 100644 index 00000000000000..08e5db9bb11616 --- /dev/null +++ b/eng/common/templates-official/jobs/source-build.yml @@ -0,0 +1,46 @@ +parameters: + # This template adds arcade-powered source-build to CI. A job is created for each platform, as + # well as an optional server job that completes when all platform jobs complete. + + # The name of the "join" job for all source-build platforms. If set to empty string, the job is + # not included. Existing repo pipelines can use this job depend on all source-build jobs + # completing without maintaining a separate list of every single job ID: just depend on this one + # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'. + allCompletedJobId: '' + + # See /eng/common/templates-official/job/source-build.yml + jobNamePrefix: 'Source_Build' + + # This is the default platform provided by Arcade, intended for use by a managed-only repo. + defaultManagedPlatform: + name: 'Managed' + container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8' + + # Defines the platforms on which to run build jobs. One job is created for each platform, and the + # object in this array is sent to the job template as 'platform'. If no platforms are specified, + # one job runs on 'defaultManagedPlatform'. + platforms: [] + +jobs: + +- ${{ if ne(parameters.allCompletedJobId, '') }}: + - job: ${{ parameters.allCompletedJobId }} + displayName: Source-Build Complete + pool: server + dependsOn: + - ${{ each platform in parameters.platforms }}: + - ${{ parameters.jobNamePrefix }}_${{ platform.name }} + - ${{ if eq(length(parameters.platforms), 0) }}: + - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }} + +- ${{ each platform in parameters.platforms }}: + - template: /eng/common/templates-official/job/source-build.yml + parameters: + jobNamePrefix: ${{ parameters.jobNamePrefix }} + platform: ${{ platform }} + +- ${{ if eq(length(parameters.platforms), 0) }}: + - template: /eng/common/templates-official/job/source-build.yml + parameters: + jobNamePrefix: ${{ parameters.jobNamePrefix }} + platform: ${{ parameters.defaultManagedPlatform }} diff --git a/eng/common/templates-official/post-build/common-variables.yml b/eng/common/templates-official/post-build/common-variables.yml new file mode 100644 index 00000000000000..c24193acfc981f --- /dev/null +++ b/eng/common/templates-official/post-build/common-variables.yml @@ -0,0 +1,22 @@ +variables: + - group: Publish-Build-Assets + + # Whether the build is internal or not + - name: IsInternalBuild + value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} + + # Default Maestro++ API Endpoint and API Version + - name: MaestroApiEndPoint + value: "https://maestro-prod.westus2.cloudapp.azure.com" + - name: MaestroApiAccessToken + value: $(MaestroAccessToken) + - name: MaestroApiVersion + value: "2020-02-20" + + - name: SourceLinkCLIVersion + value: 3.0.0 + - name: SymbolToolVersion + value: 1.0.1 + + - name: runCodesignValidationInjection + value: false diff --git a/eng/common/templates-official/post-build/post-build.yml b/eng/common/templates-official/post-build/post-build.yml new file mode 100644 index 00000000000000..da1f40958b450d --- /dev/null +++ b/eng/common/templates-official/post-build/post-build.yml @@ -0,0 +1,285 @@ +parameters: + # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST. + # Publishing V1 is no longer supported + # Publishing V2 is no longer supported + # Publishing V3 is the default + - name: publishingInfraVersion + displayName: Which version of publishing should be used to promote the build definition? + type: number + default: 3 + values: + - 3 + + - name: BARBuildId + displayName: BAR Build Id + type: number + default: 0 + + - name: PromoteToChannelIds + displayName: Channel to promote BARBuildId to + type: string + default: '' + + - name: enableSourceLinkValidation + displayName: Enable SourceLink validation + type: boolean + default: false + + - name: enableSigningValidation + displayName: Enable signing validation + type: boolean + default: true + + - name: enableSymbolValidation + displayName: Enable symbol validation + type: boolean + default: false + + - name: enableNugetValidation + displayName: Enable NuGet validation + type: boolean + default: true + + - name: publishInstallersAndChecksums + displayName: Publish installers and checksums + type: boolean + default: true + + - name: SDLValidationParameters + type: object + default: + enable: false + publishGdn: false + continueOnError: false + params: '' + artifactNames: '' + downloadArtifacts: true + + # These parameters let the user customize the call to sdk-task.ps1 for publishing + # symbols & general artifacts as well as for signing validation + - name: symbolPublishingAdditionalParameters + displayName: Symbol publishing additional parameters + type: string + default: '' + + - name: artifactsPublishingAdditionalParameters + displayName: Artifact publishing additional parameters + type: string + default: '' + + - name: signingValidationAdditionalParameters + displayName: Signing validation additional parameters + type: string + default: '' + + # Which stages should finish execution before post-build stages start + - name: validateDependsOn + type: object + default: + - build + + - name: publishDependsOn + type: object + default: + - Validate + + # Optional: Call asset publishing rather than running in a separate stage + - name: publishAssetsImmediately + type: boolean + default: false + +stages: +- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: + - stage: Validate + dependsOn: ${{ parameters.validateDependsOn }} + displayName: Validate Build Assets + variables: + - template: common-variables.yml + - template: /eng/common/templates-official/variables/pool-providers.yml + jobs: + - job: + displayName: NuGet Validation + condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true')) + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022 + os: windows + + steps: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: PackageArtifacts + checkDownloadedFiles: true + + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 + arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ + -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ + + - job: + displayName: Signing Validation + condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true')) + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022 + os: windows + steps: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: PackageArtifacts + checkDownloadedFiles: true + itemPattern: | + ** + !**/Microsoft.SourceBuild.Intermediate.*.nupkg + + # This is necessary whenever we want to publish/restore to an AzDO private feed + # Since sdk-task.ps1 tries to restore packages we need to do this authentication here + # otherwise it'll complain about accessing a private feed. + - task: NuGetAuthenticate@1 + displayName: 'Authenticate to AzDO Feeds' + + # Signing validation will optionally work with the buildmanifest file which is downloaded from + # Azure DevOps above. + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task SigningValidation -restore -msbuildEngine vs + /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts' + /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt' + ${{ parameters.signingValidationAdditionalParameters }} + + - template: ../steps/publish-logs.yml + parameters: + StageLabel: 'Validation' + JobLabel: 'Signing' + BinlogToolVersion: $(BinlogToolVersion) + + - job: + displayName: SourceLink Validation + condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true') + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022 + os: windows + steps: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Blob Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: BlobArtifacts + checkDownloadedFiles: true + + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1 + arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ + -ExtractPath $(Agent.BuildDirectory)/Extract/ + -GHRepoName $(Build.Repository.Name) + -GHCommit $(Build.SourceVersion) + -SourcelinkCliVersion $(SourceLinkCLIVersion) + continueOnError: true + +- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}: + - stage: publish_using_darc + ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: + dependsOn: ${{ parameters.publishDependsOn }} + ${{ else }}: + dependsOn: ${{ parameters.validateDependsOn }} + displayName: Publish using Darc + variables: + - template: common-variables.yml + - template: /eng/common/templates-official/variables/pool-providers.yml + jobs: + - job: + displayName: Publish Using Darc + timeoutInMinutes: 120 + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: NetCore1ESPool-Publishing-Internal + image: windows.vs2019.amd64 + os: windows + steps: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: NuGetAuthenticate@1 + + - task: PowerShell@2 + displayName: Publish Using Darc + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 + arguments: -BuildId $(BARBuildId) + -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} + -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' + -MaestroToken '$(MaestroApiAccessToken)' + -WaitPublishingFinish true + -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' + -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' diff --git a/eng/common/templates-official/post-build/setup-maestro-vars.yml b/eng/common/templates-official/post-build/setup-maestro-vars.yml new file mode 100644 index 00000000000000..0c87f149a4ad77 --- /dev/null +++ b/eng/common/templates-official/post-build/setup-maestro-vars.yml @@ -0,0 +1,70 @@ +parameters: + BARBuildId: '' + PromoteToChannelIds: '' + +steps: + - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}: + - task: DownloadBuildArtifacts@0 + displayName: Download Release Configs + inputs: + buildType: current + artifactName: ReleaseConfigs + checkDownloadedFiles: true + + - task: PowerShell@2 + name: setReleaseVars + displayName: Set Release Configs Vars + inputs: + targetType: inline + pwsh: true + script: | + try { + if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') { + $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt + + $BarId = $Content | Select -Index 0 + $Channels = $Content | Select -Index 1 + $IsStableBuild = $Content | Select -Index 2 + + $AzureDevOpsProject = $Env:System_TeamProject + $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId + $AzureDevOpsBuildId = $Env:Build_BuildId + } + else { + $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}" + + $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' + $apiHeaders.Add('Accept', 'application/json') + $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}") + + $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } + + $BarId = $Env:BARBuildId + $Channels = $Env:PromoteToMaestroChannels -split "," + $Channels = $Channels -join "][" + $Channels = "[$Channels]" + + $IsStableBuild = $buildInfo.stable + $AzureDevOpsProject = $buildInfo.azureDevOpsProject + $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId + $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId + } + + Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId" + Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels" + Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild" + + Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject" + Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId" + Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId" + } + catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + exit 1 + } + env: + MAESTRO_API_TOKEN: $(MaestroApiAccessToken) + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }} diff --git a/eng/common/templates-official/post-build/trigger-subscription.yml b/eng/common/templates-official/post-build/trigger-subscription.yml new file mode 100644 index 00000000000000..da669030daf6e9 --- /dev/null +++ b/eng/common/templates-official/post-build/trigger-subscription.yml @@ -0,0 +1,13 @@ +parameters: + ChannelId: 0 + +steps: +- task: PowerShell@2 + displayName: Triggering subscriptions + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1 + arguments: -SourceRepo $(Build.Repository.Uri) + -ChannelId ${{ parameters.ChannelId }} + -MaestroApiAccessToken $(MaestroAccessToken) + -MaestroApiEndPoint $(MaestroApiEndPoint) + -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates-official/steps/add-build-to-channel.yml b/eng/common/templates-official/steps/add-build-to-channel.yml new file mode 100644 index 00000000000000..f67a210d62f3e5 --- /dev/null +++ b/eng/common/templates-official/steps/add-build-to-channel.yml @@ -0,0 +1,13 @@ +parameters: + ChannelId: 0 + +steps: +- task: PowerShell@2 + displayName: Add Build to Channel + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1 + arguments: -BuildId $(BARBuildId) + -ChannelId ${{ parameters.ChannelId }} + -MaestroApiAccessToken $(MaestroApiAccessToken) + -MaestroApiEndPoint $(MaestroApiEndPoint) + -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates-official/steps/build-reason.yml b/eng/common/templates-official/steps/build-reason.yml new file mode 100644 index 00000000000000..eba58109b52c9d --- /dev/null +++ b/eng/common/templates-official/steps/build-reason.yml @@ -0,0 +1,12 @@ +# build-reason.yml +# Description: runs steps if build.reason condition is valid. conditions is a string of valid build reasons +# to include steps (',' separated). +parameters: + conditions: '' + steps: [] + +steps: + - ${{ if and( not(startsWith(parameters.conditions, 'not')), contains(parameters.conditions, variables['build.reason'])) }}: + - ${{ parameters.steps }} + - ${{ if and( startsWith(parameters.conditions, 'not'), not(contains(parameters.conditions, variables['build.reason']))) }}: + - ${{ parameters.steps }} diff --git a/eng/common/templates-official/steps/component-governance.yml b/eng/common/templates-official/steps/component-governance.yml new file mode 100644 index 00000000000000..cbba0596709da7 --- /dev/null +++ b/eng/common/templates-official/steps/component-governance.yml @@ -0,0 +1,13 @@ +parameters: + disableComponentGovernance: false + componentGovernanceIgnoreDirectories: '' + +steps: +- ${{ if eq(parameters.disableComponentGovernance, 'true') }}: + - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true" + displayName: Set skipComponentGovernanceDetection variable +- ${{ if ne(parameters.disableComponentGovernance, 'true') }}: + - task: ComponentGovernanceComponentDetection@0 + continueOnError: true + inputs: + ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} \ No newline at end of file diff --git a/eng/common/templates-official/steps/execute-codeql.yml b/eng/common/templates-official/steps/execute-codeql.yml new file mode 100644 index 00000000000000..9b4a5ffa30a788 --- /dev/null +++ b/eng/common/templates-official/steps/execute-codeql.yml @@ -0,0 +1,32 @@ +parameters: + # Language that should be analyzed. Defaults to csharp + language: csharp + # Build Commands + buildCommands: '' + overrideParameters: '' # Optional: to override values for parameters. + additionalParameters: '' # Optional: parameters that need user specific values eg: '-SourceToolsList @("abc","def") -ArtifactToolsList @("ghi","jkl")' + # Optional: if specified, restore and use this version of Guardian instead of the default. + overrideGuardianVersion: '' + # Optional: if true, publish the '.gdn' folder as a pipeline artifact. This can help with in-depth + # diagnosis of problems with specific tool configurations. + publishGuardianDirectoryToPipeline: false + # The script to run to execute all SDL tools. Use this if you want to use a script to define SDL + # parameters rather than relying on YAML. It may be better to use a local script, because you can + # reproduce results locally without piecing together a command based on the YAML. + executeAllSdlToolsScript: 'eng/common/sdl/execute-all-sdl-tools.ps1' + # There is some sort of bug (has been reported) in Azure DevOps where if this parameter is named + # 'continueOnError', the parameter value is not correctly picked up. + # This can also be remedied by the caller (post-build.yml) if it does not use a nested parameter + # optional: determines whether to continue the build if the step errors; + sdlContinueOnError: false + +steps: +- template: /eng/common/templates-official/steps/execute-sdl.yml + parameters: + overrideGuardianVersion: ${{ parameters.overrideGuardianVersion }} + executeAllSdlToolsScript: ${{ parameters.executeAllSdlToolsScript }} + overrideParameters: ${{ parameters.overrideParameters }} + additionalParameters: '${{ parameters.additionalParameters }} + -CodeQLAdditionalRunConfigParams @("BuildCommands < ${{ parameters.buildCommands }}", "Language < ${{ parameters.language }}")' + publishGuardianDirectoryToPipeline: ${{ parameters.publishGuardianDirectoryToPipeline }} + sdlContinueOnError: ${{ parameters.sdlContinueOnError }} \ No newline at end of file diff --git a/eng/common/templates-official/steps/execute-sdl.yml b/eng/common/templates-official/steps/execute-sdl.yml new file mode 100644 index 00000000000000..07426fde05d824 --- /dev/null +++ b/eng/common/templates-official/steps/execute-sdl.yml @@ -0,0 +1,88 @@ +parameters: + overrideGuardianVersion: '' + executeAllSdlToolsScript: '' + overrideParameters: '' + additionalParameters: '' + publishGuardianDirectoryToPipeline: false + sdlContinueOnError: false + condition: '' + +steps: +- task: NuGetAuthenticate@1 + inputs: + nuGetServiceConnections: GuardianConnect + +- task: NuGetToolInstaller@1 + displayName: 'Install NuGet.exe' + +- ${{ if ne(parameters.overrideGuardianVersion, '') }}: + - pwsh: | + Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl + . .\sdl.ps1 + $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts -Version ${{ parameters.overrideGuardianVersion }} + Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" + displayName: Install Guardian (Overridden) + +- ${{ if eq(parameters.overrideGuardianVersion, '') }}: + - pwsh: | + Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl + . .\sdl.ps1 + $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts + Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" + displayName: Install Guardian + +- ${{ if ne(parameters.overrideParameters, '') }}: + - powershell: ${{ parameters.executeAllSdlToolsScript }} ${{ parameters.overrideParameters }} + displayName: Execute SDL (Overridden) + continueOnError: ${{ parameters.sdlContinueOnError }} + condition: ${{ parameters.condition }} + +- ${{ if eq(parameters.overrideParameters, '') }}: + - powershell: ${{ parameters.executeAllSdlToolsScript }} + -GuardianCliLocation $(GuardianCliLocation) + -NugetPackageDirectory $(Build.SourcesDirectory)\.packages + -AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw) + ${{ parameters.additionalParameters }} + displayName: Execute SDL + continueOnError: ${{ parameters.sdlContinueOnError }} + condition: ${{ parameters.condition }} + +- ${{ if ne(parameters.publishGuardianDirectoryToPipeline, 'false') }}: + # We want to publish the Guardian results and configuration for easy diagnosis. However, the + # '.gdn' dir is a mix of configuration, results, extracted dependencies, and Guardian default + # tooling files. Some of these files are large and aren't useful during an investigation, so + # exclude them by simply deleting them before publishing. (As of writing, there is no documented + # way to selectively exclude a dir from the pipeline artifact publish task.) + - task: DeleteFiles@1 + displayName: Delete Guardian dependencies to avoid uploading + inputs: + SourceFolder: $(Agent.BuildDirectory)/.gdn + Contents: | + c + i + condition: succeededOrFailed() + + - publish: $(Agent.BuildDirectory)/.gdn + artifact: GuardianConfiguration + displayName: Publish GuardianConfiguration + condition: succeededOrFailed() + + # Publish the SARIF files in a container named CodeAnalysisLogs to enable integration + # with the "SARIF SAST Scans Tab" Azure DevOps extension + - task: CopyFiles@2 + displayName: Copy SARIF files + inputs: + flattenFolders: true + sourceFolder: $(Agent.BuildDirectory)/.gdn/rc/ + contents: '**/*.sarif' + targetFolder: $(Build.SourcesDirectory)/CodeAnalysisLogs + condition: succeededOrFailed() + + # Use PublishBuildArtifacts because the SARIF extension only checks this case + # see microsoft/sarif-azuredevops-extension#4 + - task: PublishBuildArtifacts@1 + displayName: Publish SARIF files to CodeAnalysisLogs container + inputs: + pathToPublish: $(Build.SourcesDirectory)/CodeAnalysisLogs + artifactName: CodeAnalysisLogs + condition: succeededOrFailed() \ No newline at end of file diff --git a/eng/common/templates-official/steps/generate-sbom.yml b/eng/common/templates-official/steps/generate-sbom.yml new file mode 100644 index 00000000000000..1bf43bf807af39 --- /dev/null +++ b/eng/common/templates-official/steps/generate-sbom.yml @@ -0,0 +1,48 @@ +# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated. +# PackageName - The name of the package this SBOM represents. +# PackageVersion - The version of the package this SBOM represents. +# ManifestDirPath - The path of the directory where the generated manifest files will be placed +# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector. + +parameters: + PackageVersion: 8.0.0 + BuildDropPath: '$(Build.SourcesDirectory)/artifacts' + PackageName: '.NET' + ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom + IgnoreDirectories: '' + sbomContinueOnError: true + +steps: +- task: PowerShell@2 + displayName: Prep for SBOM generation in (Non-linux) + condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin')) + inputs: + filePath: ./eng/common/generate-sbom-prep.ps1 + arguments: ${{parameters.manifestDirPath}} + +# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461 +- script: | + chmod +x ./eng/common/generate-sbom-prep.sh + ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}} + displayName: Prep for SBOM generation in (Linux) + condition: eq(variables['Agent.Os'], 'Linux') + continueOnError: ${{ parameters.sbomContinueOnError }} + +- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: 'Generate SBOM manifest' + continueOnError: ${{ parameters.sbomContinueOnError }} + inputs: + PackageName: ${{ parameters.packageName }} + BuildDropPath: ${{ parameters.buildDropPath }} + PackageVersion: ${{ parameters.packageVersion }} + ManifestDirPath: ${{ parameters.manifestDirPath }} + ${{ if ne(parameters.IgnoreDirectories, '') }}: + AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}' + +- task: 1ES.PublishPipelineArtifact@1 + displayName: Publish SBOM manifest + continueOnError: ${{parameters.sbomContinueOnError}} + inputs: + targetPath: '${{parameters.manifestDirPath}}' + artifactName: $(ARTIFACT_NAME) + diff --git a/eng/common/templates-official/steps/publish-logs.yml b/eng/common/templates-official/steps/publish-logs.yml new file mode 100644 index 00000000000000..04012fed182a1f --- /dev/null +++ b/eng/common/templates-official/steps/publish-logs.yml @@ -0,0 +1,23 @@ +parameters: + StageLabel: '' + JobLabel: '' + +steps: +- task: Powershell@2 + displayName: Prepare Binlogs to Upload + inputs: + targetType: inline + script: | + New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + continueOnError: true + condition: always() + +- task: 1ES.PublishBuildArtifacts@1 + displayName: Publish Logs + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs' + PublishLocation: Container + ArtifactName: PostBuildLogs + continueOnError: true + condition: always() diff --git a/eng/common/templates-official/steps/retain-build.yml b/eng/common/templates-official/steps/retain-build.yml new file mode 100644 index 00000000000000..83d97a26a01ff9 --- /dev/null +++ b/eng/common/templates-official/steps/retain-build.yml @@ -0,0 +1,28 @@ +parameters: + # Optional azure devops PAT with build execute permissions for the build's organization, + # only needed if the build that should be retained ran on a different organization than + # the pipeline where this template is executing from + Token: '' + # Optional BuildId to retain, defaults to the current running build + BuildId: '' + # Azure devops Organization URI for the build in the https://dev.azure.com/ format. + # Defaults to the organization the current pipeline is running on + AzdoOrgUri: '$(System.CollectionUri)' + # Azure devops project for the build. Defaults to the project the current pipeline is running on + AzdoProject: '$(System.TeamProject)' + +steps: + - task: powershell@2 + inputs: + targetType: 'filePath' + filePath: eng/common/retain-build.ps1 + pwsh: true + arguments: > + -AzdoOrgUri: ${{parameters.AzdoOrgUri}} + -AzdoProject ${{parameters.AzdoProject}} + -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }} + -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}} + displayName: Enable permanent build retention + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + BUILD_ID: $(Build.BuildId) \ No newline at end of file diff --git a/eng/common/templates-official/steps/send-to-helix.yml b/eng/common/templates-official/steps/send-to-helix.yml new file mode 100644 index 00000000000000..3eb7e2d5f840c7 --- /dev/null +++ b/eng/common/templates-official/steps/send-to-helix.yml @@ -0,0 +1,91 @@ +# Please remember to update the documentation if you make changes to these parameters! +parameters: + HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/ + HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/' + HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number + HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues + HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group + HelixConfiguration: '' # optional -- additional property attached to a job + HelixPreCommands: '' # optional -- commands to run before Helix work item execution + HelixPostCommands: '' # optional -- commands to run after Helix work item execution + WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects + WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects + WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects + CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload + XUnitProjects: '' # optional -- semicolon-delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true + XUnitWorkItemTimeout: '' # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects + XUnitPublishTargetFramework: '' # optional -- framework to use to publish your xUnit projects + XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner + XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects + IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion + DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json + DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json + WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget." + IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set + HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting https://helix.int-dot.net ) + Creator: '' # optional -- if the build is external, use this to specify who is sending the job + DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO + condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() + continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false + +steps: + - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY\eng\common\helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env:BuildConfig\SendToHelix.binlog"' + displayName: ${{ parameters.DisplayNamePrefix }} (Windows) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixAccessToken: ${{ parameters.HelixAccessToken }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} + Creator: ${{ parameters.Creator }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog + displayName: ${{ parameters.DisplayNamePrefix }} (Unix) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixAccessToken: ${{ parameters.HelixAccessToken }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} + Creator: ${{ parameters.Creator }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} diff --git a/eng/common/templates-official/steps/source-build.yml b/eng/common/templates-official/steps/source-build.yml new file mode 100644 index 00000000000000..829f17c34d118c --- /dev/null +++ b/eng/common/templates-official/steps/source-build.yml @@ -0,0 +1,129 @@ +parameters: + # This template adds arcade-powered source-build to CI. + + # This is a 'steps' template, and is intended for advanced scenarios where the existing build + # infra has a careful build methodology that must be followed. For example, a repo + # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline + # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to + # GitHub. Using this steps template leaves room for that infra to be included. + + # Defines the platform on which to run the steps. See 'eng/common/templates-official/job/source-build.yml' + # for details. The entire object is described in the 'job' template for simplicity, even though + # the usage of the properties on this object is split between the 'job' and 'steps' templates. + platform: {} + +steps: +# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.) +- script: | + set -x + df -h + + # If building on the internal project, the artifact feeds variable may be available (usually only if needed) + # In that case, call the feed setup script to add internal feeds corresponding to public ones. + # In addition, add an msbuild argument to copy the WIP from the repo to the target build location. + # This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those + # changes. + internalRestoreArgs= + if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then + # Temporarily work around https://github.com/dotnet/arcade/issues/7709 + chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh + $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh $(Build.SourcesDirectory)/NuGet.config $(dn-bot-dnceng-artifact-feeds-rw) + internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true' + + # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo. + # This only works if there is a username/email configured, which won't be the case in most CI runs. + git config --get user.email + if [ $? -ne 0 ]; then + git config user.email dn-bot@microsoft.com + git config user.name dn-bot + fi + fi + + # If building on the internal project, the internal storage variable may be available (usually only if needed) + # In that case, add variables to allow the download of internal runtimes if the specified versions are not found + # in the default public locations. + internalRuntimeDownloadArgs= + if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then + internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' + fi + + buildConfig=Release + # Check if AzDO substitutes in a build config from a variable, and use it if so. + if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then + buildConfig='$(_BuildConfig)' + fi + + officialBuildArgs= + if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then + officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)' + fi + + targetRidArgs= + if [ '${{ parameters.platform.targetRID }}' != '' ]; then + targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}' + fi + + runtimeOsArgs= + if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then + runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}' + fi + + baseOsArgs= + if [ '${{ parameters.platform.baseOS }}' != '' ]; then + baseOsArgs='/p:BaseOS=${{ parameters.platform.baseOS }}' + fi + + publishArgs= + if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then + publishArgs='--publish' + fi + + assetManifestFileName=SourceBuild_RidSpecific.xml + if [ '${{ parameters.platform.name }}' != '' ]; then + assetManifestFileName=SourceBuild_${{ parameters.platform.name }}.xml + fi + + ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \ + --configuration $buildConfig \ + --restore --build --pack $publishArgs -bl \ + $officialBuildArgs \ + $internalRuntimeDownloadArgs \ + $internalRestoreArgs \ + $targetRidArgs \ + $runtimeOsArgs \ + $baseOsArgs \ + /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \ + /p:ArcadeBuildFromSource=true \ + /p:AssetManifestFileName=$assetManifestFileName + displayName: Build + +# Upload build logs for diagnosis. +- task: CopyFiles@2 + displayName: Prepare BuildLogs staging directory + inputs: + SourceFolder: '$(Build.SourcesDirectory)' + Contents: | + **/*.log + **/*.binlog + artifacts/source-build/self/prebuilt-report/** + TargetFolder: '$(Build.StagingDirectory)/BuildLogs' + CleanTargetFolder: true + continueOnError: true + condition: succeededOrFailed() + +- task: 1ES.PublishPipelineArtifact@1 + displayName: Publish BuildLogs + inputs: + targetPath: '$(Build.StagingDirectory)/BuildLogs' + artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt) + continueOnError: true + condition: succeededOrFailed() + +# Manually inject component detection so that we can ignore the source build upstream cache, which contains +# a nupkg cache of input packages (a local feed). +# This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir' +# in src\Microsoft.DotNet.Arcade.Sdk\tools\SourceBuild\SourceBuildArcade.targets +- task: ComponentGovernanceComponentDetection@0 + displayName: Component Detection (Exclude upstream cache) + inputs: + ignoreDirectories: '$(Build.SourcesDirectory)/artifacts/source-build/self/src/artifacts/obj/source-built-upstream-cache' diff --git a/eng/common/templates-official/variables/pool-providers.yml b/eng/common/templates-official/variables/pool-providers.yml new file mode 100644 index 00000000000000..1f308b24efc43d --- /dev/null +++ b/eng/common/templates-official/variables/pool-providers.yml @@ -0,0 +1,45 @@ +# Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool, +# otherwise it should go into the "normal" pools. This separates out the queueing and billing of released branches. + +# Motivation: +# Once a given branch of a repository's output has been officially "shipped" once, it is then considered to be COGS +# (Cost of goods sold) and should be moved to a servicing pool provider. This allows both separation of queueing +# (allowing release builds and main PR builds to not intefere with each other) and billing (required for COGS. +# Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services +# team needs to move resources around and create new and potentially differently-named pools. Using this template +# file from an Arcade-ified repo helps guard against both having to update one's release/* branches and renaming. + +# How to use: +# This yaml assumes your shipped product branches use the naming convention "release/..." (which many do). +# If we find alternate naming conventions in broad usage it can be added to the condition below. +# +# First, import the template in an arcade-ified repo to pick up the variables, e.g.: +# +# variables: +# - template: /eng/common/templates-official/variables/pool-providers.yml +# +# ... then anywhere specifying the pool provider use the runtime variables, +# $(DncEngInternalBuildPool) +# +# pool: +# name: $(DncEngInternalBuildPool) +# image: 1es-windows-2022 + +variables: + # Coalesce the target and source branches so we know when a PR targets a release branch + # If these variables are somehow missing, fall back to main (tends to have more capacity) + + # Any new -Svc alternative pools should have variables added here to allow for splitting work + + - name: DncEngInternalBuildPool + value: $[ + replace( + replace( + eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), + True, + 'NetCore1ESPool-Svc-Internal' + ), + False, + 'NetCore1ESPool-Internal' + ) + ] \ No newline at end of file diff --git a/eng/common/templates-official/variables/sdl-variables.yml b/eng/common/templates-official/variables/sdl-variables.yml new file mode 100644 index 00000000000000..dbdd66d4a4b3a0 --- /dev/null +++ b/eng/common/templates-official/variables/sdl-variables.yml @@ -0,0 +1,7 @@ +variables: +# The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in +# sync with the packages.config file. +- name: DefaultGuardianVersion + value: 0.109.0 +- name: GuardianPackagesConfigFile + value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config \ No newline at end of file diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index e24ca2f46f98f9..8ec5c4f2d9f910 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -15,6 +15,7 @@ parameters: timeoutInMinutes: '' variables: [] workspace: '' + templateContext: '' # Job base template specific parameters # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md @@ -68,6 +69,9 @@ jobs: ${{ if ne(parameters.timeoutInMinutes, '') }}: timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + ${{ if ne(parameters.templateContext, '') }}: + templateContext: ${{ parameters.templateContext }} + variables: - ${{ if ne(parameters.enableTelemetry, 'false') }}: - name: DOTNET_CLI_TELEMETRY_PROFILE diff --git a/eng/common/templates/steps/component-governance.yml b/eng/common/templates/steps/component-governance.yml index 0ecec47b0c9177..cbba0596709da7 100644 --- a/eng/common/templates/steps/component-governance.yml +++ b/eng/common/templates/steps/component-governance.yml @@ -4,7 +4,7 @@ parameters: steps: - ${{ if eq(parameters.disableComponentGovernance, 'true') }}: - - script: "echo ##vso[task.setvariable variable=skipComponentGovernanceDetection]true" + - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true" displayName: Set skipComponentGovernanceDetection variable - ${{ if ne(parameters.disableComponentGovernance, 'true') }}: - task: ComponentGovernanceComponentDetection@0 diff --git a/eng/common/templates/steps/generate-sbom.yml b/eng/common/templates/steps/generate-sbom.yml index a06373f38fa5d5..2b21eae4273288 100644 --- a/eng/common/templates/steps/generate-sbom.yml +++ b/eng/common/templates/steps/generate-sbom.yml @@ -5,7 +5,7 @@ # IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector. parameters: - PackageVersion: 7.0.0 + PackageVersion: 8.0.0 BuildDropPath: '$(Build.SourcesDirectory)/artifacts' PackageName: '.NET' ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom diff --git a/global.json b/global.json index c987cd4bc00e7d..e0a39423109f36 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.101" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24113.2", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24113.2", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.24113.2", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24204.3", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24204.3", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.24204.3", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From 9b82dcc5e647c503802a41bb00036386560466c1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 10:05:45 -0700 Subject: [PATCH 684/783] Fix native leak in CryptoNative_GetX509nameInfo The implementation was previously only freeing the STACK_OF, but not the contents of the stack. This change fixes not freeing the individual GENERAL_NAME items. (#100793) Co-authored-by: Kevin Jones --- .../libs/System.Security.Cryptography.Native/openssl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/native/libs/System.Security.Cryptography.Native/openssl.c b/src/native/libs/System.Security.Cryptography.Native/openssl.c index 73822045895425..fa2302b780e3e5 100644 --- a/src/native/libs/System.Security.Cryptography.Native/openssl.c +++ b/src/native/libs/System.Security.Cryptography.Native/openssl.c @@ -627,8 +627,8 @@ BIO* CryptoNative_GetX509NameInfo(X509* x509, int32_t nameType, int32_t forIssue break; } - STACK_OF(GENERAL_NAME)* altNames = (STACK_OF(GENERAL_NAME)*)( - X509_get_ext_d2i(x509, forIssuer ? NID_issuer_alt_name : NID_subject_alt_name, NULL, NULL)); + GENERAL_NAMES* altNames = (GENERAL_NAMES*) + X509_get_ext_d2i(x509, forIssuer ? NID_issuer_alt_name : NID_subject_alt_name, NULL, NULL); if (altNames) { @@ -686,13 +686,13 @@ BIO* CryptoNative_GetX509NameInfo(X509* x509, int32_t nameType, int32_t forIssue { BIO* b = BIO_new(BIO_s_mem()); ASN1_STRING_print_ex(b, str, ASN1_STRFLGS_UTF8_CONVERT); - sk_GENERAL_NAME_free(altNames); + GENERAL_NAMES_free(altNames); return b; } } } - sk_GENERAL_NAME_free(altNames); + GENERAL_NAMES_free(altNames); } } From 7fa8815b1a2bc5183a0ea4549b4aad8d2e82acd6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 18:01:15 -0500 Subject: [PATCH 685/783] [release/8.0-staging] Update dependencies from dotnet/emsdk (#99696) * Update dependencies from https://github.com/dotnet/emsdk build Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.4-servicing.24163.1 * Update dependencies from https://github.com/dotnet/emsdk build Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.4-servicing.24165.3 * Update dependencies from https://github.com/dotnet/emsdk build Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.4-servicing.24170.6 * Update dependencies from https://github.com/dotnet/emsdk build Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.4-servicing.24172.5 * Update dependencies from https://github.com/dotnet/emsdk build Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.4-servicing.24175.3 * Update dependencies from https://github.com/dotnet/emsdk build Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.4-servicing.24176.3 * Update dependencies from https://github.com/dotnet/emsdk build 20240327.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.4-servicing.24177.1 * Update dependencies from https://github.com/dotnet/emsdk build 20240327.3 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.4-servicing.24177.3 * Update dependencies from https://github.com/dotnet/emsdk build 20240328.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.4-servicing.24178.2 * Update dependencies from https://github.com/dotnet/emsdk build 20240329.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.4-servicing.24179.1 * Update dependencies from https://github.com/dotnet/emsdk build 20240403.3 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.5-servicing.24203.3 * Update dependencies from https://github.com/dotnet/emsdk build 20240405.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.5-servicing.24205.1 * Update dependencies from https://github.com/dotnet/emsdk build 20240409.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.5-servicing.24209.2 * Update dependencies from https://github.com/dotnet/emsdk build 20240410.3 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.5-servicing.24210.3 * Update dependencies from https://github.com/dotnet/emsdk build 20240411.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.5-servicing.24211.2 * Update dependencies from https://github.com/dotnet/emsdk build 20240411.3 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.5-servicing.24211.3 * Update dependencies from https://github.com/dotnet/emsdk build 20240411.3 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24156.2 -> To Version 8.0.5-servicing.24211.3 * Update dependencies from https://github.com/dotnet/emsdk build 20240411.3 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.4-servicing.24163.1 -> To Version 8.0.5-servicing.24211.3 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Eric StJohn --- NuGet.config | 4 +--- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/NuGet.config b/NuGet.config index 86aa3c4ed5898c..a0aef486d231a2 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,9 +9,7 @@ - - - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f91d99477583be..91df0c87d9cbce 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,13 +90,13 @@ 45dd3a73dd5b64b010c4251303b3664bb30df029 - + https://github.com/dotnet/emsdk - 08a90ca2c88b17f1b5d081318354a41db0882cff + 71359b18c2d83c01a68bf155244a65962a7e8c8e - + https://github.com/dotnet/emsdk - 08a90ca2c88b17f1b5d081318354a41db0882cff + 71359b18c2d83c01a68bf155244a65962a7e8c8e diff --git a/eng/Versions.props b/eng/Versions.props index afc5da2fc7d595..d0418b1a22e4c1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.4 + 8.0.5 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda From f9feb6865ffbbbdb213bfe75229b431932b28a0f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 17:48:22 -0500 Subject: [PATCH 686/783] Try to find seqpoints directly from jitinfo if it's not find on get_default_jit_mm (#100978) Co-authored-by: Thays Grazia --- src/mono/mono/component/debugger-engine.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mono/mono/component/debugger-engine.c b/src/mono/mono/component/debugger-engine.c index 5ec3e68b62aee4..9a3648b311b824 100644 --- a/src/mono/mono/component/debugger-engine.c +++ b/src/mono/mono/component/debugger-engine.c @@ -449,6 +449,16 @@ mono_de_set_breakpoint (MonoMethod *method, long il_offset, EventRequest *req, M set_bp_in_method (domain, m, seq_points, bp, error); } + // trying to get the seqpoints directly from the jit info of the method + // the seqpoints in get_default_jit_mm may not be found for AOTed methods in arm64 + if (methods->len == 0) + { + MonoJitInfo *ji; + (void)mono_jit_search_all_backends_for_jit_info (method, &ji); + if (ji && ji->seq_points) + set_bp_in_method (mono_get_root_domain (), method, ji->seq_points, bp, error); + } + g_ptr_array_add (breakpoints, bp); mono_debugger_log_add_bp (bp, bp->method, bp->il_offset); mono_loader_unlock (); From af764fd245c4a90b59ac8b29ad9ae95f705beac4 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Mon, 15 Apr 2024 16:29:49 +0200 Subject: [PATCH 687/783] [release/8.0][browser] fix emscripten out/err overrides (#100818) * backport of https://github.com/dotnet/runtime/pull/100630/ * fix * fix --- .../scenarios/BuildWasmAppsJobsList.txt | 2 +- src/mono/sample/wasm/browser-advanced/main.js | 1 + ...eProgressTests.cs => ModuleConfigTests.cs} | 26 +++++++++++++++-- src/mono/wasm/runtime/loader/assets.ts | 3 +- src/mono/wasm/runtime/loader/icu.ts | 3 +- src/mono/wasm/runtime/loader/run.ts | 2 +- src/mono/wasm/runtime/startup.ts | 29 +++++++++++-------- src/mono/wasm/runtime/types/internal.ts | 6 ++-- .../WasmBasicTestApp/App/Common/Program.cs | 1 + .../WasmBasicTestApp/App/wwwroot/main.js | 15 ++++++++++ 10 files changed, 67 insertions(+), 21 deletions(-) rename src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/{DownloadResourceProgressTests.cs => ModuleConfigTests.cs} (68%) diff --git a/eng/testing/scenarios/BuildWasmAppsJobsList.txt b/eng/testing/scenarios/BuildWasmAppsJobsList.txt index 51bb6bcbb3f293..e16c74fe4f0750 100644 --- a/eng/testing/scenarios/BuildWasmAppsJobsList.txt +++ b/eng/testing/scenarios/BuildWasmAppsJobsList.txt @@ -41,5 +41,5 @@ Wasm.Build.Tests.WasmRunOutOfAppBundleTests Wasm.Build.Tests.WasmSIMDTests Wasm.Build.Tests.WasmTemplateTests Wasm.Build.Tests.WorkloadTests -Wasm.Build.Tests.TestAppScenarios.DownloadResourceProgressTests +Wasm.Build.Tests.TestAppScenarios.ModuleConfigTests Wasm.Build.Tests.MT.Blazor.SimpleMultiThreadedTests diff --git a/src/mono/sample/wasm/browser-advanced/main.js b/src/mono/sample/wasm/browser-advanced/main.js index b5c414322fefd0..85b1a64e8e4228 100644 --- a/src/mono/sample/wasm/browser-advanced/main.js +++ b/src/mono/sample/wasm/browser-advanced/main.js @@ -59,6 +59,7 @@ try { console.log('user code Module.onDotnetReady'); }, postRun: () => { console.log('user code Module.postRun'); }, + out: (text) => { console.log("ADVANCED:" + text) }, }) .withResourceLoader((type, name, defaultUri, integrity, behavior) => { // loadBootResource could return string with unqualified name of resource. It assumes that we resolve it with document.baseURI diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/DownloadResourceProgressTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/ModuleConfigTests.cs similarity index 68% rename from src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/DownloadResourceProgressTests.cs rename to src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/ModuleConfigTests.cs index 70f9b4f1507d28..1b8c43ecea77b0 100644 --- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/DownloadResourceProgressTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/ModuleConfigTests.cs @@ -13,9 +13,9 @@ namespace Wasm.Build.Tests.TestAppScenarios; -public class DownloadResourceProgressTests : AppTestBase +public class ModuleConfigTests : AppTestBase { - public DownloadResourceProgressTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) + public ModuleConfigTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) : base(output, buildContext) { } @@ -25,7 +25,7 @@ public DownloadResourceProgressTests(ITestOutputHelper output, SharedBuildPerTes [InlineData(true)] public async Task DownloadProgressFinishes(bool failAssemblyDownload) { - CopyTestAsset("WasmBasicTestApp", $"DownloadResourceProgressTests_{failAssemblyDownload}"); + CopyTestAsset("WasmBasicTestApp", $"ModuleConfigTests_DownloadProgressFinishes_{failAssemblyDownload}"); PublishProject("Debug"); var result = await RunSdkStyleApp(new( @@ -54,4 +54,24 @@ public async Task DownloadProgressFinishes(bool failAssemblyDownload) : "The download progress test did emit unexpected message about failing download" ); } + + [Fact] + public async Task OutErrOverrideWorks() + { + CopyTestAsset("WasmBasicTestApp", $"ModuleConfigTests_OutErrOverrideWorks"); + PublishProject("Debug"); + + var result = await RunSdkStyleApp(new( + Configuration: "Debug", + TestScenario: "OutErrOverrideWorks" + )); + Assert.True( + result.ConsoleOutput.Any(m => m.Contains("Emscripten out override works!")), + "Emscripten out override doesn't work" + ); + Assert.True( + result.ConsoleOutput.Any(m => m.Contains("Emscripten err override works!")), + "Emscripten err override doesn't work" + ); + } } diff --git a/src/mono/wasm/runtime/loader/assets.ts b/src/mono/wasm/runtime/loader/assets.ts index 8730988193ffd0..5e9eb8a8d3b75b 100644 --- a/src/mono/wasm/runtime/loader/assets.ts +++ b/src/mono/wasm/runtime/loader/assets.ts @@ -12,6 +12,7 @@ import { mono_exit } from "./exit"; import { addCachedReponse, findCachedResponse } from "./assetsCache"; import { getIcuResourceName } from "./icu"; import { makeURLAbsoluteWithApplicationBase } from "./polyfills"; +import { mono_log_info } from "./logging"; let throttlingPromise: PromiseAndController | undefined; @@ -545,7 +546,7 @@ async function start_asset_download_sources(asset: AssetEntryInternal): Promise< err.status = response.status; throw err; } else { - loaderHelpers.out(`optional download '${response.url}' for ${asset.name} failed ${response.status} ${response.statusText}`); + mono_log_info(`optional download '${response.url}' for ${asset.name} failed ${response.status} ${response.statusText}`); return undefined; } } diff --git a/src/mono/wasm/runtime/loader/icu.ts b/src/mono/wasm/runtime/loader/icu.ts index 927672f5db99d6..bb7213b22a88e8 100644 --- a/src/mono/wasm/runtime/loader/icu.ts +++ b/src/mono/wasm/runtime/loader/icu.ts @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +import { mono_log_error } from "./logging"; import { GlobalizationMode, MonoConfig } from "../types"; import { ENVIRONMENT_IS_WEB, loaderHelpers } from "./globals"; import { mono_log_info, mono_log_debug } from "./logging"; @@ -18,7 +19,7 @@ export function init_globalization() { loaderHelpers.preferredIcuAsset = null; } else { const msg = "invariant globalization mode is inactive and no ICU data archives are available"; - loaderHelpers.err(`ERROR: ${msg}`); + mono_log_error(`ERROR: ${msg}`); throw new Error(msg); } } diff --git a/src/mono/wasm/runtime/loader/run.ts b/src/mono/wasm/runtime/loader/run.ts index b3437a5a81d61b..112d66edab945d 100644 --- a/src/mono/wasm/runtime/loader/run.ts +++ b/src/mono/wasm/runtime/loader/run.ts @@ -458,7 +458,7 @@ async function initializeModules(es6Modules: [RuntimeModuleExportsInternal, Nati const { default: emscriptenFactory } = es6Modules[1]; setRuntimeGlobals(globalObjectsRoot); initializeExports(globalObjectsRoot); - await configureRuntimeStartup(); + await configureRuntimeStartup(globalObjectsRoot.module); loaderHelpers.runtimeModuleLoaded.promise_control.resolve(); emscriptenFactory((originalModule: EmscriptenModuleInternal) => { diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index c385844dfd30bb..324bdc78b0435d 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -39,7 +39,23 @@ import { assertNoProxies } from "./gc-handles"; // default size if MonoConfig.pthreadPoolSize is undefined const MONO_PTHREAD_POOL_SIZE = 4; -export async function configureRuntimeStartup(): Promise { +export async function configureRuntimeStartup (module: DotnetModuleInternal): Promise { + if (!module.out) { + // eslint-disable-next-line no-console + module.out = console.log.bind(console); + } + if (!module.err) { + // eslint-disable-next-line no-console + module.err = console.error.bind(console); + } + if (!module.print) { + module.print = module.out; + } + if (!module.printErr) { + module.printErr = module.err; + } + loaderHelpers.out = module.print; + loaderHelpers.err = module.printErr; await init_polyfills_async(); await checkMemorySnapshotSize(); } @@ -54,17 +70,6 @@ export function configureEmscriptenStartup(module: DotnetModuleInternal): void { module.locateFile = module.__locateFile = (path) => loaderHelpers.scriptDirectory + path; } - if (!module.out) { - // eslint-disable-next-line no-console - module.out = console.log.bind(console); - } - - if (!module.err) { - // eslint-disable-next-line no-console - module.err = console.error.bind(console); - } - loaderHelpers.out = module.out; - loaderHelpers.err = module.err; module.mainScriptUrlOrBlob = loaderHelpers.scriptUrl;// this is needed by worker threads // these all could be overridden on DotnetModuleConfig, we are chaing them to async below, as opposed to emscripten diff --git a/src/mono/wasm/runtime/types/internal.ts b/src/mono/wasm/runtime/types/internal.ts index a91b21973c8d5e..c43443a48da6bc 100644 --- a/src/mono/wasm/runtime/types/internal.ts +++ b/src/mono/wasm/runtime/types/internal.ts @@ -464,6 +464,8 @@ export declare interface EmscriptenModuleInternal { runtimeKeepalivePush(): void; runtimeKeepalivePop(): void; maybeExit(): void; + print(message: string): void; + printErr(message: string): void; } /// A PromiseController encapsulates a Promise together with easy access to its resolve and reject functions. @@ -492,7 +494,7 @@ export type setGlobalObjectsType = (globalObjects: GlobalObjects) => void; export type initializeExportsType = (globalObjects: GlobalObjects) => RuntimeAPI; export type initializeReplacementsType = (replacements: EmscriptenReplacements) => void; export type configureEmscriptenStartupType = (module: DotnetModuleInternal) => void; -export type configureRuntimeStartupType = () => Promise; +export type configureRuntimeStartupType = (module: DotnetModuleInternal) => Promise; export type configureWorkerStartupType = (module: DotnetModuleInternal) => Promise @@ -508,4 +510,4 @@ export type RuntimeModuleExportsInternal = { export type NativeModuleExportsInternal = { default: (unificator: Function) => EmscriptenModuleInternal -} \ No newline at end of file +} diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/Common/Program.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/Common/Program.cs index 4f38c02031c7ec..eda19b81f506eb 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/Common/Program.cs +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/Common/Program.cs @@ -2,3 +2,4 @@ // The .NET Foundation licenses this file to you under the MIT license. System.Console.WriteLine("WasmBasicTestApp"); +System.Console.Error.WriteLine("WasmBasicTestApp stderr"); diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js index 076f37a62a6d87..8e3485bc2e67cd 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js @@ -63,6 +63,18 @@ switch (testCase) { } }); break; + case "OutErrOverrideWorks": + dotnet.withModuleConfig({ + out: (message) => { + console.log("Emscripten out override works!"); + console.log(message) + }, + err: (message) => { + console.error("Emscripten err override works!"); + console.error(message) + }, + }); + break; } const { getAssemblyExports, getConfig, INTERNAL } = await dotnet.create(); @@ -94,6 +106,9 @@ try { case "DownloadResourceProgressTest": exit(0); break; + case "OutErrOverrideWorks": + dotnet.run(); + break; default: console.error(`Unknown test case: ${testCase}`); exit(3); From cd27afea7a3621f9b14a46553b39b4550c1ace44 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 11:19:54 -0700 Subject: [PATCH 688/783] [mono][eventpipe] Fix firing dynamic method wrappers crash (#99712) Co-authored-by: mdh1418 --- src/mono/mono/eventpipe/ep-rt-mono-runtime-provider.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mono/mono/eventpipe/ep-rt-mono-runtime-provider.c b/src/mono/mono/eventpipe/ep-rt-mono-runtime-provider.c index ccb91d0ca41694..4ab963643d4c32 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono-runtime-provider.c +++ b/src/mono/mono/eventpipe/ep-rt-mono-runtime-provider.c @@ -779,6 +779,8 @@ include_method (MonoMethod *method) return false; } else if (!m_method_is_wrapper (method)) { return true; + } else if (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD){ + return true; } else { WrapperInfo *wrapper = mono_marshal_get_wrapper_info (method); return (wrapper && wrapper->subtype == WRAPPER_SUBTYPE_PINVOKE) ? true : false; From f0f42cc1f6af798c90c1da47d914e08969e3ac24 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Mon, 15 Apr 2024 11:22:29 -0700 Subject: [PATCH 689/783] Update Alpine versions for `release/8.0-staging` (#99849) * Update Alpine versions * Backport [#99020] Disable QUIC tests on alpine arm32 --------- Co-authored-by: Natalia Kondratyeva --- .../coreclr/templates/helix-queues-setup.yml | 12 ++++++------ eng/pipelines/libraries/helix-queues-setup.yml | 8 ++++---- .../FunctionalTests/MsQuicCipherSuitesPolicyTests.cs | 3 ++- .../FunctionalTests/MsQuicPlatformDetectionTests.cs | 1 + .../tests/FunctionalTests/MsQuicTests.cs | 1 + .../tests/FunctionalTests/QuicConnectionTests.cs | 1 + .../tests/FunctionalTests/QuicListenerTests.cs | 1 + .../QuicStreamConnectedStreamConformanceTests.cs | 1 + .../tests/FunctionalTests/QuicStreamTests.cs | 1 + 9 files changed, 18 insertions(+), 11 deletions(-) diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml index 8e5ddd36759581..9a57f32f5e60d2 100644 --- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml +++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml @@ -79,23 +79,23 @@ jobs: # Linux musl x64 - ${{ if eq(parameters.platform, 'linux_musl_x64') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - (Alpine.315.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-amd64 + - (Alpine.317.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-amd64 - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - (Alpine.315.Amd64)ubuntu.1804.amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-amd64 + - (Alpine.319.Amd64)Ubuntu.2204.Amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.19-helix-amd64 # Linux musl arm32 - ${{ if eq(parameters.platform, 'linux_musl_arm') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - (Alpine.315.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7 + - (Alpine.317.Arm32.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-arm32v7 - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - (Alpine.315.Arm32)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7 + - (Alpine.319.Arm32)Ubuntu.2204.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.19-helix-arm32v7 # Linux musl arm64 - ${{ if eq(parameters.platform, 'linux_musl_arm64') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - (Alpine.315.Arm64.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm64v8 + - (Alpine.317.Arm64.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-arm64v8 - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - (Alpine.315.Arm64)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm64v8 + - (Alpine.319.Arm64)Ubuntu.2204.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.19-helix-arm64v8 # Linux x64 - ${{ if eq(parameters.platform, 'linux_x64') }}: diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 5b37825df0867d..be98c70f16130b 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -47,14 +47,14 @@ jobs: # Linux musl x64 - ${{ if eq(parameters.platform, 'linux_musl_x64') }}: - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - - (Alpine.315.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-amd64 + - (Alpine.317.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-amd64 - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - - (Alpine.317.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-amd64 + - (Alpine.319.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.19-helix-amd64 # Linux musl arm64 - ${{ if and(eq(parameters.platform, 'linux_musl_arm64'), or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true))) }}: - - (Alpine.317.Arm64.Open)ubuntu.1804.armarch.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-arm64v8 - - (Alpine.315.Arm64.Open)ubuntu.1804.armarch.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm64v8 + - (Alpine.317.Arm64.Open)ubuntu.2204.armarch.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-arm64v8 + - (Alpine.319.Arm64.Open)ubuntu.2204.armarch.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.19-helix-arm64v8 # Linux x64 - ${{ if eq(parameters.platform, 'linux_x64') }}: diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs index df827e64feadab..8d71bfc4cb072a 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs @@ -11,6 +11,7 @@ namespace System.Net.Quic.Tests [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(QuicTestBase), nameof(QuicTestBase.IsSupported))] [SkipOnPlatform(TestPlatforms.Windows, "CipherSuitesPolicy is not supported on Windows")] + [ActiveIssue("https://github.com/dotnet/runtime/issues/91757", typeof(PlatformDetection), nameof(PlatformDetection.IsAlpine), nameof(PlatformDetection.IsArmProcess))] public class MsQuicCipherSuitesPolicyTests : QuicTestBase { public MsQuicCipherSuitesPolicyTests(ITestOutputHelper output) : base(output) { } @@ -77,4 +78,4 @@ await Assert.ThrowsAsync(() => TestConnection( )); } } -} \ No newline at end of file +} diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicPlatformDetectionTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicPlatformDetectionTests.cs index 16f267fc719535..8e61c741a920bc 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicPlatformDetectionTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicPlatformDetectionTests.cs @@ -59,6 +59,7 @@ public async Task SupportedLinuxPlatformsWithMsQuic_IsSupportedIsTrue() [ActiveIssue("https://github.com/dotnet/runtime/issues/82154", typeof(PlatformDetection), nameof(PlatformDetection.IsRaspbian10), nameof(PlatformDetection.IsArmv6Process), nameof(PlatformDetection.IsInContainer))] [ActiveIssue("https://github.com/dotnet/runtime/issues/82154", typeof(PlatformDetection), nameof(PlatformDetection.IsPpc64leProcess))] [ActiveIssue("https://github.com/dotnet/runtime/issues/82154", typeof(PlatformDetection), nameof(PlatformDetection.IsUbuntu2004), nameof(PlatformDetection.IsS390xProcess))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/91757", typeof(PlatformDetection), nameof(PlatformDetection.IsAlpine), nameof(PlatformDetection.IsArmProcess))] [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsInHelix))] [PlatformSpecific(TestPlatforms.Linux)] public void SupportedLinuxPlatforms_IsSupportedIsTrue() diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 503c2d4068355d..51c4279308e56a 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -48,6 +48,7 @@ public void Dispose() [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(QuicTestBase), nameof(QuicTestBase.IsSupported))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/91757", typeof(PlatformDetection), nameof(PlatformDetection.IsAlpine), nameof(PlatformDetection.IsArmProcess))] public class MsQuicTests : QuicTestBase, IClassFixture { private static byte[] s_data = "Hello world!"u8.ToArray(); diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicConnectionTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicConnectionTests.cs index dba45d813945ff..01dbaa5fb9f0db 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicConnectionTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicConnectionTests.cs @@ -16,6 +16,7 @@ namespace System.Net.Quic.Tests [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(QuicTestBase), nameof(QuicTestBase.IsSupported))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/91757", typeof(PlatformDetection), nameof(PlatformDetection.IsAlpine), nameof(PlatformDetection.IsArmProcess))] public sealed class QuicConnectionTests : QuicTestBase { const int ExpectedErrorCode = 1234; diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicListenerTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicListenerTests.cs index 68509bf6b5571f..3abc21344c93d8 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicListenerTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicListenerTests.cs @@ -15,6 +15,7 @@ namespace System.Net.Quic.Tests { [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(QuicTestBase), nameof(QuicTestBase.IsSupported))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/91757", typeof(PlatformDetection), nameof(PlatformDetection.IsAlpine), nameof(PlatformDetection.IsArmProcess))] public sealed class QuicListenerTests : QuicTestBase { public QuicListenerTests(ITestOutputHelper output) : base(output) { } diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamConnectedStreamConformanceTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamConnectedStreamConformanceTests.cs index 762fc4230abc0e..63f577cbc695bd 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamConnectedStreamConformanceTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamConnectedStreamConformanceTests.cs @@ -16,6 +16,7 @@ namespace System.Net.Quic.Tests { [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(QuicTestBase), nameof(QuicTestBase.IsSupported))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/91757", typeof(PlatformDetection), nameof(PlatformDetection.IsAlpine), nameof(PlatformDetection.IsArmProcess))] public sealed class QuicStreamConformanceTests : ConnectedStreamConformanceTests { protected override bool UsableAfterCanceledReads => false; diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamTests.cs index e220decb1bd400..dabd0a6e40108b 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamTests.cs @@ -14,6 +14,7 @@ namespace System.Net.Quic.Tests { [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(QuicTestBase), nameof(QuicTestBase.IsSupported))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/91757", typeof(PlatformDetection), nameof(PlatformDetection.IsAlpine), nameof(PlatformDetection.IsArmProcess))] public sealed class QuicStreamTests : QuicTestBase { private static byte[] s_data = "Hello world!"u8.ToArray(); From 6f292679f9973fa80b242b6d39da1330c2ef7de9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 11:25:02 -0700 Subject: [PATCH 690/783] [release/8.0-staging] Guard against -1 Returned from sysconf for the Cache Sizes Causing Large Gen0 Sizes and Budgets for Certain Linux Distributions. (#100575) * Logging. * Fixed comparison check * Fix logical operations * Completely guard against the cacheSize as UINTMAX_MAX * Fix for right macro * Ensure we are guarded against all cases where cacheSize == SIZE_MAX * Added an extra guard and removed redundant case * Comment clean * Added some additional asserts * Removed unnecessary checks for cacheSize == SIZE_MAX * Cleaned up logic * Fix type casting comparison * Removed redundant comment * Removed one more unneccesary guard --------- Co-authored-by: mrsharm --- src/coreclr/gc/unix/gcenv.unix.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/coreclr/gc/unix/gcenv.unix.cpp b/src/coreclr/gc/unix/gcenv.unix.cpp index b45cd40d8073fe..dd591a54426351 100644 --- a/src/coreclr/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/gc/unix/gcenv.unix.cpp @@ -792,28 +792,30 @@ bool ReadMemoryValueFromFile(const char* filename, uint64_t* val) return result; } -#define UPDATE_CACHE_SIZE_AND_LEVEL(NEW_CACHE_SIZE, NEW_CACHE_LEVEL) if (NEW_CACHE_SIZE > cacheSize) { cacheSize = NEW_CACHE_SIZE; cacheLevel = NEW_CACHE_LEVEL; } +#define UPDATE_CACHE_SIZE_AND_LEVEL(NEW_CACHE_SIZE, NEW_CACHE_LEVEL) if (NEW_CACHE_SIZE > ((long)cacheSize)) { cacheSize = NEW_CACHE_SIZE; cacheLevel = NEW_CACHE_LEVEL; } static size_t GetLogicalProcessorCacheSizeFromOS() { size_t cacheLevel = 0; size_t cacheSize = 0; - size_t size; + long size; + // sysconf can return -1 if the cache size is unavailable in some distributions and 0 in others. + // UPDATE_CACHE_SIZE_AND_LEVEL should handle both the cases by not updating cacheSize if either of cases are met. #ifdef _SC_LEVEL1_DCACHE_SIZE - size = ( size_t) sysconf(_SC_LEVEL1_DCACHE_SIZE); + size = sysconf(_SC_LEVEL1_DCACHE_SIZE); UPDATE_CACHE_SIZE_AND_LEVEL(size, 1) #endif #ifdef _SC_LEVEL2_CACHE_SIZE - size = ( size_t) sysconf(_SC_LEVEL2_CACHE_SIZE); + size = sysconf(_SC_LEVEL2_CACHE_SIZE); UPDATE_CACHE_SIZE_AND_LEVEL(size, 2) #endif #ifdef _SC_LEVEL3_CACHE_SIZE - size = ( size_t) sysconf(_SC_LEVEL3_CACHE_SIZE); + size = sysconf(_SC_LEVEL3_CACHE_SIZE); UPDATE_CACHE_SIZE_AND_LEVEL(size, 3) #endif #ifdef _SC_LEVEL4_CACHE_SIZE - size = ( size_t) sysconf(_SC_LEVEL4_CACHE_SIZE); + size = sysconf(_SC_LEVEL4_CACHE_SIZE); UPDATE_CACHE_SIZE_AND_LEVEL(size, 4) #endif @@ -836,17 +838,22 @@ static size_t GetLogicalProcessorCacheSizeFromOS() { path_to_size_file[index] = (char)(48 + i); - if (ReadMemoryValueFromFile(path_to_size_file, &size)) + uint64_t cache_size_from_sys_file = 0; + + if (ReadMemoryValueFromFile(path_to_size_file, &cache_size_from_sys_file)) { + // uint64_t to long conversion as ReadMemoryValueFromFile takes a uint64_t* as an argument for the val argument. + size = (long)cache_size_from_sys_file; path_to_level_file[index] = (char)(48 + i); if (ReadMemoryValueFromFile(path_to_level_file, &level)) { UPDATE_CACHE_SIZE_AND_LEVEL(size, level) } + else { - cacheSize = std::max(cacheSize, size); + cacheSize = std::max((long)cacheSize, size); } } } From a494d22d2b50bf7811549ac26ee459aed0af6c4f Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Mon, 15 Apr 2024 20:26:53 +0200 Subject: [PATCH 691/783] [Release/8.0] Remove preventing EH at shutdown (#100836) Partial backport of #100293 to release/8.0 --- src/coreclr/vm/ceemain.cpp | 3 --- src/coreclr/vm/eepolicy.cpp | 7 ------- src/coreclr/vm/excep.cpp | 12 ++---------- src/coreclr/vm/i386/excepx86.cpp | 3 --- src/coreclr/vm/vars.cpp | 1 - src/coreclr/vm/vars.hpp | 1 - 6 files changed, 2 insertions(+), 25 deletions(-) diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index 218cda11d7f0e2..680a9a2fb2491c 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -1331,9 +1331,6 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading) // Shutdown finalizer before we suspend all background threads. Otherwise we // never get to finalize anything. - // No longer process exceptions - g_fNoExceptions = true; - // @TODO: This does things which shouldn't occur in part 2. Namely, // calling managed dll main callbacks (AppDomain::SignalProcessDetach), and // RemoveAppDomainFromIPC. diff --git a/src/coreclr/vm/eepolicy.cpp b/src/coreclr/vm/eepolicy.cpp index af27338544e861..6069f0ec124780 100644 --- a/src/coreclr/vm/eepolicy.cpp +++ b/src/coreclr/vm/eepolicy.cpp @@ -59,13 +59,6 @@ void SafeExitProcess(UINT exitCode, ShutdownCompleteAction sca = SCA_ExitProcess } } - // Turn off exception processing, because if some other random DLL has a - // fault in DLL_PROCESS_DETACH, we could get called for exception handling. - // Since we've turned off part of the runtime, we can't, for instance, - // properly execute the GC that handling an exception might trigger. - g_fNoExceptions = true; - LOG((LF_EH, LL_INFO10, "SafeExitProcess: turning off exceptions\n")); - if (sca == SCA_TerminateProcessWhenShutdownComplete) { // disabled because if we fault in this code path we will trigger our Watson code diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index ce8b325a5f41b8..b88d6a959bb321 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -4623,12 +4623,6 @@ LONG InternalUnhandledExceptionFilter_Worker( } #endif - // This shouldn't be possible, but MSVC re-installs us... for now, just bail if this happens. - if (g_fNoExceptions) - { - return EXCEPTION_CONTINUE_SEARCH; - } - // Are we looking at a stack overflow here? if ((pThread != NULL) && !pThread->DetermineIfGuardPagePresent()) { @@ -5533,8 +5527,6 @@ static LONG ThreadBaseExceptionFilter_Worker(PEXCEPTION_POINTERS pExceptionInfo, ThreadBaseExceptionFilterParam *pParam = (ThreadBaseExceptionFilterParam *) pvParam; UnhandledExceptionLocation location = pParam->location; - _ASSERTE(!g_fNoExceptions); - Thread* pThread = GetThread(); #ifdef _DEBUG @@ -7393,8 +7385,8 @@ LONG WINAPI CLRVectoredExceptionHandlerShim(PEXCEPTION_POINTERS pExceptionInfo) // WARNING WARNING WARNING WARNING WARNING WARNING WARNING // - // If exceptions (or runtime) have been disabled, then simply return. - if (g_fForbidEnterEE || g_fNoExceptions) + // If runtime have been disabled, then simply return. + if (g_fForbidEnterEE) { return EXCEPTION_CONTINUE_SEARCH; } diff --git a/src/coreclr/vm/i386/excepx86.cpp b/src/coreclr/vm/i386/excepx86.cpp index f0c4dcc8b2a2cd..616cbaea824869 100644 --- a/src/coreclr/vm/i386/excepx86.cpp +++ b/src/coreclr/vm/i386/excepx86.cpp @@ -1571,9 +1571,6 @@ EXCEPTION_HANDLER_IMPL(COMPlusFrameHandler) _ASSERTE((pContext == NULL) || ((pContext->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)); - if (g_fNoExceptions) - return ExceptionContinueSearch; // No EH during EE shutdown. - // Check if the exception represents a GCStress Marker. If it does, // we shouldnt record its entry in the TLS as such exceptions are // continuable and can confuse the VM to treat them as CSE, diff --git a/src/coreclr/vm/vars.cpp b/src/coreclr/vm/vars.cpp index 00840f9195651e..6baded4ca7ddfc 100644 --- a/src/coreclr/vm/vars.cpp +++ b/src/coreclr/vm/vars.cpp @@ -193,7 +193,6 @@ GVAL_IMPL(SIZE_T, g_runtimeVirtualSize); Volatile g_fForbidEnterEE = false; bool g_fManagedAttach = false; -bool g_fNoExceptions = false; DWORD g_FinalizerWaiterStatus = 0; diff --git a/src/coreclr/vm/vars.hpp b/src/coreclr/vm/vars.hpp index 03762a24e695d7..652c8cb7fd50a9 100644 --- a/src/coreclr/vm/vars.hpp +++ b/src/coreclr/vm/vars.hpp @@ -477,7 +477,6 @@ GVAL_DECL(bool, g_fProcessDetach); GVAL_DECL(bool, g_metadataUpdatesApplied); #endif EXTERN bool g_fManagedAttach; -EXTERN bool g_fNoExceptions; // Indicates whether we're executing shut down as a result of DllMain // (DLL_PROCESS_DETACH). See comments at code:EEShutDown for details. From 3c5a0af402aee0f9e71d38dee9f0c0f1763b8331 Mon Sep 17 00:00:00 2001 From: Jacques Eloff Date: Mon, 15 Apr 2024 11:47:01 -0700 Subject: [PATCH 692/783] Add workload metadata (#100649) --- src/workloads/workloads.csproj | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/workloads/workloads.csproj b/src/workloads/workloads.csproj index 3db05c0a803404..a986fdfdbe6bba 100644 --- a/src/workloads/workloads.csproj +++ b/src/workloads/workloads.csproj @@ -186,6 +186,15 @@ + + + + + + + + + Date: Mon, 15 Apr 2024 14:08:05 -0700 Subject: [PATCH 693/783] System.Diagnostics.DiagnosticSource (#99583) --- .../src/System.Diagnostics.DiagnosticSource.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj index 378251006567fc..013bbb2e0e81a6 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -6,7 +6,7 @@ $(NoWarn);SA1205 false true - true + false 1 Provides Classes that allow you to decouple code logging rich (unserializable) diagnostics/telemetry (e.g. framework) from code that consumes it (e.g. tools) From 88be910936b852ede1a5e50c2962ddf9ed6f5331 Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Mon, 15 Apr 2024 14:41:14 -0700 Subject: [PATCH 694/783] Always zero-init if object contains pointers (#100265) (#100426) --- src/coreclr/nativeaot/Runtime/gcrhenv.cpp | 6 ++++++ src/libraries/System.Runtime/tests/System/GCTests.cs | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/coreclr/nativeaot/Runtime/gcrhenv.cpp b/src/coreclr/nativeaot/Runtime/gcrhenv.cpp index 379bf5003f9b2a..a0f536b06420ff 100644 --- a/src/coreclr/nativeaot/Runtime/gcrhenv.cpp +++ b/src/coreclr/nativeaot/Runtime/gcrhenv.cpp @@ -129,6 +129,12 @@ Object* GcAllocInternal(MethodTable *pEEType, uint32_t uFlags, uintptr_t numElem ASSERT(!pThread->IsDoNotTriggerGcSet()); ASSERT(pThread->IsCurrentThreadInCooperativeMode()); + if (pEEType->ContainsPointers()) + { + uFlags |= GC_ALLOC_CONTAINS_REF; + uFlags &= ~GC_ALLOC_ZEROING_OPTIONAL; + } + size_t cbSize = pEEType->get_BaseSize(); if (pEEType->HasComponentSize()) diff --git a/src/libraries/System.Runtime/tests/System/GCTests.cs b/src/libraries/System.Runtime/tests/System/GCTests.cs index d161b3bbdde5bb..14b6e5de4065ae 100644 --- a/src/libraries/System.Runtime/tests/System/GCTests.cs +++ b/src/libraries/System.Runtime/tests/System/GCTests.cs @@ -1100,6 +1100,8 @@ private unsafe static void AllocateArrayPinned_ManagedValueType_CanRoundtripThro byte* pointer = (byte*)Unsafe.AsPointer(ref array[0]); var size = Unsafe.SizeOf>(); + GC.Collect(); + for(int i = 0; i < length; ++i) { int idx = rng.Next(length); From aa7c7ff6cf1d4e8f4b5dd750ded601f379e1c9b2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 14:42:25 -0700 Subject: [PATCH 695/783] [release/8.0-staging] JIT: Fixed incorrect reversed condition for GT (#100372) * Fixed incorrect reversed condition for GT * Added test case * Remove comment * Use JitStressModeNames * Cleaned up test * Update Runtime_92201.csproj --------- Co-authored-by: TIHan --- src/coreclr/jit/gentree.h | 2 +- .../JitBlue/Runtime_92201/Runtime_92201.cs | 174 ++++++++++++++++++ .../Runtime_92201/Runtime_92201.csproj | 13 ++ 3 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_92201/Runtime_92201.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_92201/Runtime_92201.csproj diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 5a06113fa8d717..2720a1e2b18341 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -8635,7 +8635,7 @@ struct GenCondition NONE, NONE, SGE, SGT, SLT, SLE, NS, S, NE, EQ, UGE, UGT, ULT, ULE, NC, C, FNEU, FEQU, FGEU, FGTU, FLTU, FLEU, NO, O, - FNE, FEQ, FGE, FGT, FLT, FGT, NP, P + FNE, FEQ, FGE, FGT, FLT, FLE, NP, P }; // clang-format on diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92201/Runtime_92201.cs b/src/tests/JIT/Regression/JitBlue/Runtime_92201/Runtime_92201.cs new file mode 100644 index 00000000000000..445cc3f915ef80 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_92201/Runtime_92201.cs @@ -0,0 +1,174 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using Xunit; + +namespace JIT.HardwareIntrinsics.General._Vector128 +{ + public static partial class Program + { + [Fact] + public static void Test() + { + var test = new VectorBooleanBinaryOpTest__LessThanOrEqualAnySingle(); + + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class VectorBooleanBinaryOpTest__LessThanOrEqualAnySingle + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + + private GCHandle inHandle1; + private GCHandle inHandle2; + + private ulong alignment; + + public DataTable(Single[] inArray1, Single[] inArray2, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + if (!int.IsPow2(alignment) || (alignment > 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Single); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Single); + + private static Single[] _data1 = new Single[Op1ElementCount]; + private static Single[] _data2 = new Single[Op2ElementCount]; + + private DataTable _dataTable; + + public VectorBooleanBinaryOpTest__LessThanOrEqualAnySingle() + { + Succeeded = true; + + _data1[0] = 0.168625f; + _data1[1] = 0.5899811f; + _data1[2] = 0.8042229f; + _data1[3] = 0.8173325f; + + _data2[0] = 0.059660614f; + _data2[1] = 0.13952714f; + _data2[2] = 0.23523656f; + _data2[3] = 0.48773053f; + + _dataTable = new DataTable(_data1, _data2, LargestVectorSize); + } + + public bool Succeeded { get; set; } + + [MethodImpl(MethodImplOptions.NoInlining)] + public bool LessThanOrEqualAnyProblem() + { + return Vector128.LessThanOrEqualAny( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public void* GetPtr1() + { + return _dataTable.inArray1Ptr; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public void* GetPtr2() + { + return _dataTable.inArray2Ptr; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public void CheckResult(bool result) + { + ValidateResult(GetPtr1(), GetPtr2(), result); + } + + public void RunBasicScenario_UnsafeRead() + { + var result = Vector128.LessThanOrEqualAny( + Unsafe.Read>(GetPtr1()), + Unsafe.Read>(GetPtr2()) + ); + + CheckResult(result); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[Op1ElementCount]; + Single[] inArray2 = new Single[Op2ElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + var expectedResult = false; + + for (var i = 0; i < Op1ElementCount; i++) + { + expectedResult |= (left[i] <= right[i]); + } + + succeeded = (expectedResult == result); + + if (!succeeded) + { + Succeeded = false; + } + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92201/Runtime_92201.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_92201/Runtime_92201.csproj new file mode 100644 index 00000000000000..717798d9d4e2bd --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_92201/Runtime_92201.csproj @@ -0,0 +1,13 @@ + + + True + True + + + + + + + + + From f4dc677f6f41404c622cb676cb0b64cdb2926128 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 10:21:15 -0500 Subject: [PATCH 696/783] Update dependencies from https://github.com/dotnet/emsdk build 20240415.1 (#101047) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.5-servicing.24211.3 -> To Version 8.0.5-servicing.24215.1 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index a0aef486d231a2..e768edae2abb39 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 91df0c87d9cbce..016d31238f339c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - 71359b18c2d83c01a68bf155244a65962a7e8c8e + 6a06b5454e26309fe4ec786857853056c2c541e0 - + https://github.com/dotnet/emsdk - 71359b18c2d83c01a68bf155244a65962a7e8c8e + 6a06b5454e26309fe4ec786857853056c2c541e0 From dce1737abed4e4077e0890b9202dba76aa883059 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:14:47 -0700 Subject: [PATCH 697/783] [release/8.0] Update MicrosoftBuildVersion to latest (#100595) * Update MicrosoftBuildVersion to latest to fix System.Security.Cryptography.XML component governance alert. * Add info to VersionDetails to allow sourcebuild to update the MSBuild dependency * Update SourceBuildPrebuiltBaseline.xml --------- Co-authored-by: Parker Bibus Co-authored-by: Eric StJohn Co-authored-by: Michael Simons --- eng/SourceBuildPrebuiltBaseline.xml | 8 +++++++- eng/Version.Details.xml | 9 +++++++++ eng/Versions.props | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/eng/SourceBuildPrebuiltBaseline.xml b/eng/SourceBuildPrebuiltBaseline.xml index 458b2d756cba9a..81041ed6ed6377 100644 --- a/eng/SourceBuildPrebuiltBaseline.xml +++ b/eng/SourceBuildPrebuiltBaseline.xml @@ -28,5 +28,11 @@ + + + + + + - \ No newline at end of file + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 016d31238f339c..39a3c00c93f0c4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -410,5 +410,14 @@ https://github.com/dotnet/installer 46a7370763921ded24dcb70c585ee97883c615d4 + + https://github.com/dotnet/msbuild + 195e7f5a3a8e51c37d83cd9e54cb99dc3fc69c22 + + + https://github.com/dotnet/msbuild + 195e7f5a3a8e51c37d83cd9e54cb99dc3fc69c22 + + diff --git a/eng/Versions.props b/eng/Versions.props index d0418b1a22e4c1..3bf003d4987e7e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -172,7 +172,7 @@ 2.0.3 1.0.4-preview6.19326.1 2.0.5 - 17.3.2 + 17.8.3 $(MicrosoftBuildVersion) $(MicrosoftBuildVersion) $(MicrosoftBuildVersion) From ca4f0fe37455882baa00c75b1ef30a7ff1494457 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:27:42 -0700 Subject: [PATCH 698/783] [release/8.0] Update MicrosoftBuildVersion to latest (#100595) (#101145) * Update MicrosoftBuildVersion to latest to fix System.Security.Cryptography.XML component governance alert. * Add info to VersionDetails to allow sourcebuild to update the MSBuild dependency * Update SourceBuildPrebuiltBaseline.xml --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Parker Bibus Co-authored-by: Eric StJohn Co-authored-by: Michael Simons --- eng/SourceBuildPrebuiltBaseline.xml | 8 +++++++- eng/Version.Details.xml | 9 +++++++++ eng/Versions.props | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/eng/SourceBuildPrebuiltBaseline.xml b/eng/SourceBuildPrebuiltBaseline.xml index 458b2d756cba9a..81041ed6ed6377 100644 --- a/eng/SourceBuildPrebuiltBaseline.xml +++ b/eng/SourceBuildPrebuiltBaseline.xml @@ -28,5 +28,11 @@ + + + + + + - \ No newline at end of file + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 91df0c87d9cbce..fe35dc0997ea20 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -410,5 +410,14 @@ https://github.com/dotnet/installer 46a7370763921ded24dcb70c585ee97883c615d4 + + https://github.com/dotnet/msbuild + 195e7f5a3a8e51c37d83cd9e54cb99dc3fc69c22 + + + https://github.com/dotnet/msbuild + 195e7f5a3a8e51c37d83cd9e54cb99dc3fc69c22 + + diff --git a/eng/Versions.props b/eng/Versions.props index 565f052fc8baab..f012e409095090 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -172,7 +172,7 @@ 2.0.3 1.0.4-preview6.19326.1 2.0.5 - 17.3.2 + 17.8.3 $(MicrosoftBuildVersion) $(MicrosoftBuildVersion) $(MicrosoftBuildVersion) From b82b0d9e248c62d8433c2ec42a19c24121d7255c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 11:18:02 +0200 Subject: [PATCH 699/783] [release/8.0-staging] [wasm] Fix AOT publish in paths with space on Windows/Linux (#101109) * Fix * Fix template wbt * Fix config wbt. * Should fix native wbt but does not. * Missing change. * Update src/tasks/AotCompilerTask/MonoAOTCompiler.cs Co-authored-by: Ankit Jain * Double quotes needed, not single. * Space on Linux should work. * Backport https://github.com/dotnet/runtime/pull/94306 --------- Co-authored-by: Ilona Tomkowicz Co-authored-by: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Co-authored-by: Ankit Jain --- .../wasm/Wasm.Build.Tests/Common/BuildEnvironment.cs | 2 +- src/mono/wasm/Wasm.Build.Tests/ConfigSrcTests.cs | 2 +- src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs | 2 +- .../Wasm.Build.Tests/Templates/WasmTemplateTests.cs | 8 ++++---- src/mono/wasm/build/WasmApp.Native.targets | 2 +- src/mono/wasm/build/WasmApp.targets | 12 ++++++------ src/tasks/AotCompilerTask/MonoAOTCompiler.cs | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/Common/BuildEnvironment.cs b/src/mono/wasm/Wasm.Build.Tests/Common/BuildEnvironment.cs index 21feaea66f28e7..0674991bc1d3a0 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Common/BuildEnvironment.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Common/BuildEnvironment.cs @@ -30,7 +30,7 @@ public class BuildEnvironment public static readonly string RelativeTestAssetsPath = @"..\testassets\"; public static readonly string TestAssetsPath = Path.Combine(AppContext.BaseDirectory, "testassets"); public static readonly string TestDataPath = Path.Combine(AppContext.BaseDirectory, "data"); - public static readonly string TmpPath = Path.Combine(AppContext.BaseDirectory, "wbt"); + public static readonly string TmpPath = Path.Combine(AppContext.BaseDirectory, "wbt artifacts"); public static readonly string DefaultRuntimeIdentifier = #if TARGET_WASI diff --git a/src/mono/wasm/Wasm.Build.Tests/ConfigSrcTests.cs b/src/mono/wasm/Wasm.Build.Tests/ConfigSrcTests.cs index ac71dafe0eb305..329ecbe0b49ca7 100644 --- a/src/mono/wasm/Wasm.Build.Tests/ConfigSrcTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/ConfigSrcTests.cs @@ -32,6 +32,6 @@ public void ConfigSrcAbsolutePath(BuildArgs buildArgs, RunHost host, string id) string bundleDir = Path.Combine(binDir, "AppBundle"); string configSrc = Path.GetFullPath(Path.Combine(bundleDir, "_framework", "blazor.boot.json")); - RunAndTestWasmApp(buildArgs, expectedExitCode: 42, host: host, id: id, extraXHarnessMonoArgs: $"--config-src={configSrc}"); + RunAndTestWasmApp(buildArgs, expectedExitCode: 42, host: host, id: id, extraXHarnessMonoArgs: $"--config-src=\"{configSrc}\""); } } diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs b/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs index 0ea7aaf7bfa8f2..3d30a5c8411527 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs @@ -70,7 +70,7 @@ public void IntermediateBitcodeToObjectFilesAreNotLLVMIR(BuildArgs buildArgs, st { string printFileTypeTarget = @" - diff --git a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs index 08488d487a6151..821fd528e22479 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs @@ -277,7 +277,7 @@ private async Task BrowserRunTwiceWithAndThenWithoutBuildAsync(string config, st .WithWorkingDirectory(workingDir); await using var runner = new BrowserRunner(_testOutput); - var page = await runner.RunAsync(runCommand, $"run --no-silent -c {config} --project {projectFile} --forward-console"); + var page = await runner.RunAsync(runCommand, $"run --no-silent -c {config} --project \"{projectFile}\" --forward-console"); await runner.WaitForExitMessageAsync(TimeSpan.FromMinutes(2)); Assert.Contains("Hello, Browser!", string.Join(Environment.NewLine, runner.OutputLines)); } @@ -287,7 +287,7 @@ private async Task BrowserRunTwiceWithAndThenWithoutBuildAsync(string config, st .WithWorkingDirectory(workingDir); await using var runner = new BrowserRunner(_testOutput); - var page = await runner.RunAsync(runCommand, $"run --no-silent -c {config} --no-build --project {projectFile} --forward-console"); + var page = await runner.RunAsync(runCommand, $"run --no-silent -c {config} --no-build --project \"{projectFile}\" --forward-console"); await runner.WaitForExitMessageAsync(TimeSpan.FromMinutes(2)); Assert.Contains("Hello, Browser!", string.Join(Environment.NewLine, runner.OutputLines)); } @@ -307,7 +307,7 @@ private Task ConsoleRunWithAndThenWithoutBuildAsync(string config, string extraP string workingDir = runOutsideProjectDirectory ? BuildEnvironment.TmpPath : _projectDir!; { - string runArgs = $"run --no-silent -c {config} --project {projectFile}"; + string runArgs = $"run --no-silent -c {config} --project \"{projectFile}\""; runArgs += " x y z"; using var cmd = new RunCommand(s_buildEnv, _testOutput, label: id) .WithWorkingDirectory(workingDir) @@ -323,7 +323,7 @@ private Task ConsoleRunWithAndThenWithoutBuildAsync(string config, string extraP { // Run with --no-build - string runArgs = $"run --no-silent -c {config} --project {projectFile} --no-build"; + string runArgs = $"run --no-silent -c {config} --project \"{projectFile}\" --no-build"; runArgs += " x y z"; using var cmd = new RunCommand(s_buildEnv, _testOutput, label: id) .WithWorkingDirectory(workingDir); diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index 73e5720abb01ed..52b2988f8dd3d3 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -415,7 +415,7 @@ - - - + + <_HasDotnetWasm Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.native.wasm'">true <_HasDotnetJsWorker Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.native.worker.js'">true @@ -415,7 +415,7 @@ Outputs="$(WasmAppDir)\.stamp" Condition="'$(WasmGenerateAppBundle)' == 'true'" DependsOnTargets="_WasmGenerateRuntimeConfig;_GetWasmGenerateAppBundleDependencies"> - + <_WasmAppIncludeThreadsWorker Condition="'$(WasmEnableThreads)' == 'true' or '$(MonoWasmBuildVariant)' == 'multithread'">true @@ -473,7 +473,7 @@ - + - + diff --git a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs index 9e52322770b04a..0a761b44a4c8f2 100644 --- a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs +++ b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs @@ -951,7 +951,7 @@ private PrecompileArguments GetPrecompileArgumentsFor(ITaskItem assemblyItem, st if (isDedup) { foreach (var aItem in _assembliesToCompile!) - processArgs.Add(aItem.ItemSpec); + processArgs.Add($"\"{aItem.ItemSpec}\""); } else { From 4cbd412768d46c3fe64421c5e3adc30b630f5308 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 09:58:21 -0500 Subject: [PATCH 700/783] Update dependencies from https://github.com/dotnet/source-build-externals build 20240416.1 (#101181) Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24175.3 -> To Version 8.0.0-alpha.1.24216.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 39a3c00c93f0c4..04d355fd7b9408 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -104,9 +104,9 @@ 79827eed138fd2575a8b24820b4f385ee4ffb6e6 - + https://github.com/dotnet/source-build-externals - 300e99190e6ae1983681694dbdd5f75f0c692081 + 908177a58a41532b3302c17f1e1a8cf1c1234545 From 82025822b6e74bd7f19c5d73ad04ba0e104e6b9a Mon Sep 17 00:00:00 2001 From: Parker Bibus Date: Wed, 17 Apr 2024 13:00:17 -0700 Subject: [PATCH 701/783] Update queues. (#101094) --- eng/testing/performance/performance-setup.ps1 | 14 +++++++------- eng/testing/performance/performance-setup.sh | 12 +++++++----- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/eng/testing/performance/performance-setup.ps1 b/eng/testing/performance/performance-setup.ps1 index c18445bff8aaec..2ce32b70c59b52 100644 --- a/eng/testing/performance/performance-setup.ps1 +++ b/eng/testing/performance/performance-setup.ps1 @@ -14,7 +14,7 @@ Param( [string] $Kind="micro", [switch] $LLVM, [switch] $MonoInterpreter, - [switch] $MonoAOT, + [switch] $MonoAOT, [switch] $Internal, [switch] $Compare, [string] $MonoDotnet="", @@ -47,14 +47,14 @@ $Queue = "" if ($Internal) { switch ($LogicalMachine) { - "perftiger" { $Queue = "Windows.10.Amd64.19H1.Tiger.Perf" } - "perftiger_crossgen" { $Queue = "Windows.10.Amd64.19H1.Tiger.Perf" } - "perfowl" { $Queue = "Windows.10.Amd64.20H2.Owl.Perf" } - "perfsurf" { $Queue = "Windows.10.Arm64.Perf.Surf" } + "perftiger" { $Queue = "Windows.11.Amd64.Tiger.Perf" } + "perftiger_crossgen" { $Queue = "Windows.11.Amd64.Tiger.Perf" } + "perfowl" { $Queue = "Windows.11.Amd64.Owl.Perf" } + "perfsurf" { $Queue = "Windows.11.Arm64.Surf.Perf" } "perfpixel4a" { $Queue = "Windows.11.Amd64.Pixel.Perf" } "perfampere" { $Queue = "Windows.Server.Arm64.Perf" } "cloudvm" { $Queue = "Windows.10.Amd64" } - Default { $Queue = "Windows.10.Amd64.19H1.Tiger.Perf" } + Default { $Queue = "Windows.11.Amd64.Tiger.Perf" } } $PerfLabArguments = "--upload-to-perflab-container" $ExtraBenchmarkDotNetArguments = "" @@ -124,7 +124,7 @@ if ($UseLocalCommitTime) { if ($RunFromPerformanceRepo) { $SetupArguments = "--perf-hash $CommitSha $CommonSetupArguments" - + robocopy $SourceDirectory $PerformanceDirectory /E /XD $PayloadDirectory $SourceDirectory\artifacts $SourceDirectory\.git } else { diff --git a/eng/testing/performance/performance-setup.sh b/eng/testing/performance/performance-setup.sh index 4853f0e6fb3bdb..eb49d3ea13d05e 100755 --- a/eng/testing/performance/performance-setup.sh +++ b/eng/testing/performance/performance-setup.sh @@ -264,7 +264,7 @@ benchmark_directory=$payload_directory/BenchmarkDotNet workitem_directory=$source_directory/workitem extra_benchmark_dotnet_arguments="--iterationCount 1 --warmupCount 0 --invocationCount 1 --unrollFactor 1 --strategy ColdStart --stopOnFirstError true" perflab_arguments= -queue=Ubuntu.1804.Amd64.Open +queue=Ubuntu.2204.Amd64.Open creator=$BUILD_DEFINITIONNAME helix_source_prefix="pr" @@ -277,14 +277,16 @@ if [[ "$internal" == true ]]; then if [[ "$logical_machine" == "perfiphone12mini" ]]; then queue=OSX.13.Amd64.Iphone.Perf elif [[ "$logical_machine" == "perfampere" ]]; then - queue=Ubuntu.2004.Arm64.Perf + queue=Ubuntu.2204.Arm64.Perf + elif [[ "$logical_machine" == "perfviper" ]]; then + queue=Ubuntu.2204.Amd64.Viper.Perf elif [[ "$logical_machine" == "cloudvm" ]]; then - queue=Ubuntu.1804.Amd64 + queue=Ubuntu.2204.Amd64 elif [[ "$architecture" == "arm64" ]]; then queue=Ubuntu.1804.Arm64.Perf else if [[ "$logical_machine" == "perfowl" ]]; then - queue=Ubuntu.1804.Amd64.Owl.Perf + queue=Ubuntu.2204.Amd64.Owl.Perf elif [[ "$logical_machine" == "perftiger_crossgen" ]]; then queue=Ubuntu.1804.Amd64.Tiger.Perf else @@ -299,7 +301,7 @@ else if [[ "$architecture" == "arm64" ]]; then queue=ubuntu.1804.armarch.open else - queue=Ubuntu.1804.Amd64.Open + queue=Ubuntu.2204.Amd64.Open fi if [[ "$alpine" == "true" ]]; then From d3da39dd703c6af8d700ad46beba3084302825ae Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 13:41:22 -0700 Subject: [PATCH 702/783] [release/8.0-staging] fix SendTo with SocketAsyncEventArgs (#99695) * fix SendTo with SocketAsyncEventArgs * feedback --------- Co-authored-by: wfurt --- .../src/System/Net/Sockets/Socket.Tasks.cs | 12 ++++- .../src/System/Net/Sockets/Socket.cs | 20 +++++--- .../Net/Sockets/SocketAsyncEventArgs.cs | 7 ++- .../tests/FunctionalTests/SendTo.cs | 29 ++++++++++++ .../SocketAsyncEventArgsTest.cs | 47 +++++++++++++++++++ 5 files changed, 106 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs index e1891bef916f4d..3ba24e90cf1019 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs @@ -677,7 +677,6 @@ public ValueTask SendToAsync(ReadOnlyMemory buffer, SocketFlags socke Debug.Assert(saea.BufferList == null); saea.SetBuffer(MemoryMarshal.AsMemory(buffer)); saea.SocketFlags = socketFlags; - saea._socketAddress = null; saea.RemoteEndPoint = remoteEP; saea.WrapExceptionsForNetworkStream = false; return saea.SendToAsync(this, cancellationToken); @@ -709,8 +708,17 @@ public ValueTask SendToAsync(ReadOnlyMemory buffer, SocketFlags socke saea.SetBuffer(MemoryMarshal.AsMemory(buffer)); saea.SocketFlags = socketFlags; saea._socketAddress = socketAddress; + saea.RemoteEndPoint = null; saea.WrapExceptionsForNetworkStream = false; - return saea.SendToAsync(this, cancellationToken); + try + { + return saea.SendToAsync(this, cancellationToken); + } + finally + { + // detach user provided SA so we do not accidentally stomp on it later. + saea._socketAddress = null; + } } /// diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index 414b0baa86e682..2a88a70f5941e1 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -3095,14 +3095,22 @@ private bool SendToAsync(SocketAsyncEventArgs e, CancellationToken cancellationT ArgumentNullException.ThrowIfNull(e); EndPoint? endPointSnapshot = e.RemoteEndPoint; - if (e._socketAddress == null) + + // RemoteEndPoint should be set unless somebody used SendTo with their own SA. + // In that case RemoteEndPoint will be null and we take provided SA as given. + if (endPointSnapshot == null && e._socketAddress == null) { - if (endPointSnapshot == null) - { - throw new ArgumentException(SR.Format(SR.InvalidNullArgument, "e.RemoteEndPoint"), nameof(e)); - } + throw new ArgumentException(SR.Format(SR.InvalidNullArgument, "e.RemoteEndPoint"), nameof(e)); + } - // Prepare SocketAddress + if (e._socketAddress != null && endPointSnapshot is IPEndPoint ipep && e._socketAddress.Family == endPointSnapshot?.AddressFamily) + { + // we have matching SocketAddress. Since this is only used internally, it is ok to overwrite it without + ipep.Serialize(e._socketAddress.Buffer.Span); + } + else if (endPointSnapshot != null) + { + // Prepare new SocketAddress e._socketAddress = Serialize(ref endPointSnapshot); } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs index e94d862571a0f8..78dd22e5eda7bf 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs @@ -923,7 +923,12 @@ internal void FinishOperationSyncSuccess(int bytesTransferred, SocketFlags flags case SocketAsyncOperation.ReceiveFrom: // Deal with incoming address. UpdateReceivedSocketAddress(_socketAddress!); - if (_remoteEndPoint != null && !SocketAddressExtensions.Equals(_socketAddress!, _remoteEndPoint)) + if (_remoteEndPoint == null) + { + // detach user provided SA as it was updated in place. + _socketAddress = null; + } + else if (!SocketAddressExtensions.Equals(_socketAddress!, _remoteEndPoint)) { try { diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendTo.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendTo.cs index bf0ad146588699..7a3c33b64bf796 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendTo.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendTo.cs @@ -173,6 +173,35 @@ public void SendToAsync_NullAsyncEventArgs_Throws_ArgumentNullException() public sealed class SendTo_Task : SendTo { public SendTo_Task(ITestOutputHelper output) : base(output) { } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task SendTo_DifferentEP_Success(bool ipv4) + { + IPAddress address = ipv4 ? IPAddress.Loopback : IPAddress.IPv6Loopback; + IPEndPoint remoteEp = new IPEndPoint(address, 0); + + using Socket receiver1 = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); + using Socket receiver2 = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); + using Socket sender = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); + + receiver1.BindToAnonymousPort(address); + receiver2.BindToAnonymousPort(address); + + byte[] sendBuffer = new byte[32]; + var receiveInternalBuffer = new byte[sendBuffer.Length]; + ArraySegment receiveBuffer = new ArraySegment(receiveInternalBuffer, 0, receiveInternalBuffer.Length); + + + await sender.SendToAsync(sendBuffer, SocketFlags.None, receiver1.LocalEndPoint); + SocketReceiveFromResult result = await ReceiveFromAsync(receiver1, receiveBuffer, remoteEp).WaitAsync(TestSettings.PassingTestTimeout); + Assert.Equal(sendBuffer.Length, result.ReceivedBytes); + + await sender.SendToAsync(sendBuffer, SocketFlags.None, receiver2.LocalEndPoint); + result = await ReceiveFromAsync(receiver2, receiveBuffer, remoteEp).WaitAsync(TestSettings.PassingTestTimeout); + Assert.Equal(sendBuffer.Length, result.ReceivedBytes); + } } public sealed class SendTo_CancellableTask : SendTo diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.cs index ded34276f322fa..3d865cb864570f 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.cs @@ -895,5 +895,52 @@ void CreateSocketAsyncEventArgs() // separated out so that JIT doesn't extend li return cwt.Count() == 0; // validate that the cwt becomes empty }, 30_000)); } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task SendTo_DifferentEP_Success(bool ipv4) + { + IPAddress address = ipv4 ? IPAddress.Loopback : IPAddress.IPv6Loopback; + IPEndPoint remoteEp = new IPEndPoint(address, 0); + + using Socket receiver1 = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); + using Socket receiver2 = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); + using Socket sender = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); + + receiver1.BindToAnonymousPort(address); + receiver2.BindToAnonymousPort(address); + + byte[] sendBuffer = new byte[32]; + var receiveInternalBuffer = new byte[sendBuffer.Length]; + ArraySegment receiveBuffer = new ArraySegment(receiveInternalBuffer, 0, receiveInternalBuffer.Length); + + using SocketAsyncEventArgs saea = new SocketAsyncEventArgs(); + ManualResetEventSlim mres = new ManualResetEventSlim(false); + + saea.SetBuffer(sendBuffer); + saea.RemoteEndPoint = receiver1.LocalEndPoint; + saea.Completed += delegate { mres.Set(); }; + if (sender.SendToAsync(saea)) + { + // did not finish synchronously. + mres.Wait(); + } + + SocketReceiveFromResult result = await receiver1.ReceiveFromAsync(receiveBuffer, remoteEp).WaitAsync(TestSettings.PassingTestTimeout); + Assert.Equal(sendBuffer.Length, result.ReceivedBytes); + mres.Reset(); + + + saea.RemoteEndPoint = receiver2.LocalEndPoint; + if (sender.SendToAsync(saea)) + { + // did not finish synchronously. + mres.Wait(); + } + + result = await receiver2.ReceiveFromAsync(receiveBuffer, remoteEp).WaitAsync(TestSettings.PassingTestTimeout); + Assert.Equal(sendBuffer.Length, result.ReceivedBytes); + } } } From 47afa791f1d8a8e9c380f1fa84dc7d94624bec1a Mon Sep 17 00:00:00 2001 From: Matous Kozak <55735845+matouskozak@users.noreply.github.com> Date: Thu, 18 Apr 2024 18:11:54 +0200 Subject: [PATCH 703/783] [release/8.0][mono][HybridGlobalization] Fix ShortDatePattern year format to be "yyyy" (#100810) * fix short date year format on apple hybrid glob. * add test for ShortDatePattern for iOS hybrid globalization --- .../DateTimeFormatInfoShortDatePattern.cs | 15 ++++++++++++++- .../src/System/Globalization/CalendarData.iOS.cs | 9 +++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoShortDatePattern.cs b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoShortDatePattern.cs index 815533bd1d8074..7d4b146b9decc0 100644 --- a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoShortDatePattern.cs +++ b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoShortDatePattern.cs @@ -8,6 +8,13 @@ namespace System.Globalization.Tests { public class DateTimeFormatInfoShortDatePattern { + public static IEnumerable ShortDatePattern_Get_TestData() + { + yield return new object[] { DateTimeFormatInfo.InvariantInfo, "MM/dd/yyyy", "invariant" }; + yield return new object[] { new CultureInfo("en-US").DateTimeFormat, "M/d/yyyy", "en-US" }; + yield return new object[] { new CultureInfo("fr-FR").DateTimeFormat, "dd/MM/yyyy", "fr-FR" }; + } + public static IEnumerable ShortDatePattern_Get_TestData_HybridGlobalization() { // see the comments on the right to check the non-Hybrid result, if it differs @@ -131,7 +138,6 @@ public static IEnumerable ShortDatePattern_Get_TestData_HybridGlobaliz yield return new object[] { new CultureInfo("en-ZA").DateTimeFormat, "yyyy/MM/dd" }; yield return new object[] { new CultureInfo("en-ZM").DateTimeFormat, "dd/MM/yyyy" }; yield return new object[] { new CultureInfo("en-ZW").DateTimeFormat, "d/M/yyyy" }; - yield return new object[] { new CultureInfo("en-US").DateTimeFormat, "M/d/yyyy" }; yield return new object[] { new CultureInfo("es-419").DateTimeFormat, "d/M/yyyy" }; yield return new object[] { new CultureInfo("es-ES").DateTimeFormat, "d/M/yyyy" }; yield return new object[] { new CultureInfo("es-MX").DateTimeFormat, "dd/MM/yyyy" }; @@ -200,6 +206,13 @@ public static IEnumerable ShortDatePattern_Get_TestData_HybridGlobaliz yield return new object[] { new CultureInfo("zh-TW").DateTimeFormat, "yyyy/M/d" }; } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnOSX))] + [MemberData(nameof(ShortDatePattern_Get_TestData))] + public void ShortDatePattern_Get_ReturnsExpected(DateTimeFormatInfo format, string expected, string cultureName) + { + Assert.True(expected == format.ShortDatePattern, $"Failed for culture: {cultureName}. Expected: {expected}, Actual: {format.ShortDatePattern}"); + } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))] [MemberData(nameof(ShortDatePattern_Get_TestData_HybridGlobalization))] public void ShortDatePattern_Get_ReturnsExpected_HybridGlobalization(DateTimeFormatInfo format, string expected) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.iOS.cs index 46bfb3d481ca2d..98925284412ade 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.iOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.iOS.cs @@ -18,6 +18,15 @@ private bool LoadCalendarDataFromNative(string localeName, CalendarId calendarId sNativeName = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.NativeName); sMonthDay = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.MonthDay); saShortDates = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.ShortDates).Split("||"); + // Handle ShortDatePattern to have "yyyy" year format + List shortDatePatternList = new List(saShortDates); + for (int i = 0; i < shortDatePatternList.Count; i++) + { + shortDatePatternList[i] = NormalizeDatePattern(shortDatePatternList[i]); + } + FixDefaultShortDatePattern(shortDatePatternList); + saShortDates = shortDatePatternList.ToArray(); + saLongDates = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.LongDates).Split("||"); saYearMonths = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.YearMonths).Split("||"); saDayNames = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.DayNames).Split("||"); From d597a37331b8b493129ebea628dbf1256b6c1770 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 09:59:38 -0700 Subject: [PATCH 704/783] [release/8.0-staging] Remove Win7 Helix queues (#100985) Co-authored-by: Jeremy Koritzinsky --- eng/pipelines/libraries/helix-queues-setup.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index be98c70f16130b..8acabe6ec38efc 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -152,7 +152,6 @@ jobs: - ${{ if notIn(parameters.jobParameters.framework, 'net48') }}: # mono outerloop - ${{ if and(eq(parameters.jobParameters.testScope, 'outerloop'), eq(parameters.jobParameters.runtimeFlavor, 'mono')) }}: - - Windows.7.Amd64.Open - Windows.11.Amd64.Client.Open # libraries on coreclr (outerloop and innerloop), or libraries on mono innerloop - ${{ if or(ne(parameters.jobParameters.testScope, 'outerloop'), ne(parameters.jobParameters.runtimeFlavor, 'mono')) }}: @@ -161,7 +160,6 @@ jobs: - Windows.Amd64.Server2022.Open - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - Windows.Amd64.Server2022.Open - - Windows.7.Amd64.Open # .NETFramework - ${{ if eq(parameters.jobParameters.framework, 'net48') }}: From 6c1f1c3e449df96024334adc8c67af2c14450924 Mon Sep 17 00:00:00 2001 From: Aman Khalid Date: Fri, 19 Apr 2024 18:38:00 +0000 Subject: [PATCH 705/783] Merge #91634 into release/8.0-staging (#100994) --- eng/empty.csproj | 17 ----------------- .../runtimes/send-to-helix-inner-step.yml | 19 ++----------------- .../templates/runtimes/send-to-helix-step.yml | 1 - eng/pipelines/coreclr/templates/build-job.yml | 17 ----------------- eng/pipelines/mono/templates/build-job.yml | 19 ------------------- 5 files changed, 2 insertions(+), 71 deletions(-) delete mode 100644 eng/empty.csproj diff --git a/eng/empty.csproj b/eng/empty.csproj deleted file mode 100644 index 55eefdef1ada48..00000000000000 --- a/eng/empty.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - $(NetCoreAppToolCurrent) - - - - - diff --git a/eng/pipelines/common/templates/runtimes/send-to-helix-inner-step.yml b/eng/pipelines/common/templates/runtimes/send-to-helix-inner-step.yml index bd147de7e77264..12e3f68baafb94 100644 --- a/eng/pipelines/common/templates/runtimes/send-to-helix-inner-step.yml +++ b/eng/pipelines/common/templates/runtimes/send-to-helix-inner-step.yml @@ -1,6 +1,5 @@ parameters: osGroup: '' - restoreParams: '' sendParams: '' condition: '' displayName: '' @@ -9,28 +8,14 @@ parameters: steps: - ${{ if eq(parameters.osGroup, 'windows') }}: - # TODO: Remove and consolidate this when we move to arcade via init-tools.cmd. - - powershell: $(Build.SourcesDirectory)\eng\common\build.ps1 -ci -warnaserror 0 ${{ parameters.restoreParams }} - displayName: Restore blob feed tasks (Windows) - condition: and(succeeded(), ${{ and(ne(parameters.condition, false), ne(parameters.restoreParams, '')) }}) - - - powershell: $(Build.SourcesDirectory)\eng\common\msbuild.ps1 -ci -warnaserror 0 ${{ parameters.sendParams }} + - powershell: $(Build.SourcesDirectory)\eng\common\msbuild.ps1 --restore -ci -warnaserror 0 ${{ parameters.sendParams }} displayName: ${{ parameters.displayName }} (Windows) condition: and(succeeded(), ${{ and(ne(parameters.condition, false), ne(parameters.sendParams, '')) }}) env: ${{ parameters.environment }} continueOnError: ${{ eq(parameters.shouldContinueOnError, true) }} - ${{ if ne(parameters.osGroup, 'windows') }}: - # TODO: Remove and consolidate this when we move to arcade via init-tools.sh. - - script: $(Build.SourcesDirectory)/eng/common/build.sh --ci --warnaserror false ${{ parameters.restoreParams }} - displayName: Restore blob feed tasks (Unix) - condition: and(succeeded(), ${{ and(ne(parameters.condition, false), ne(parameters.restoreParams, '')) }}) - ${{ if eq(parameters.osGroup, 'freebsd') }}: - env: - # Arcade uses this SDK instead of trying to restore one. - DotNetCoreSdkDir: /usr/local/dotnet - - - script: $(Build.SourcesDirectory)/eng/common/msbuild.sh --ci --warnaserror false ${{ parameters.sendParams }} + - script: $(Build.SourcesDirectory)/eng/common/msbuild.sh --restore --ci --warnaserror false ${{ parameters.sendParams }} displayName: ${{ parameters.displayName }} (Unix) condition: and(succeeded(), ${{ and(ne(parameters.condition, false), ne(parameters.sendParams, '')) }}) env: ${{ parameters.environment }} diff --git a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml index 37b455b19d8300..97d565b3a4e391 100644 --- a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml +++ b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml @@ -38,7 +38,6 @@ steps: - template: send-to-helix-inner-step.yml parameters: osGroup: ${{ parameters.osGroup }} - restoreParams: /p:DotNetPublishToBlobFeed=true -restore -projects $(Build.SourcesDirectory)$(dir)eng$(dir)empty.csproj sendParams: ${{ parameters.helixProjectArguments }} ${{ parameters.msbuildParallelism }} /bl:$(Build.SourcesDirectory)/artifacts/log/SendToHelix.binlog /p:TargetArchitecture=${{ parameters.archType }} /p:TargetOS=${{ parameters.osGroup }} /p:TargetOSSubgroup=${{ parameters.osSubgroup }} /p:Configuration=${{ parameters.buildConfig }} condition: and(succeeded(), ${{ parameters.condition }}) shouldContinueOnError: ${{ parameters.shouldContinueOnError }} diff --git a/eng/pipelines/coreclr/templates/build-job.yml b/eng/pipelines/coreclr/templates/build-job.yml index 365c1432aa41a1..2e128ea54e1287 100644 --- a/eng/pipelines/coreclr/templates/build-job.yml +++ b/eng/pipelines/coreclr/templates/build-job.yml @@ -70,15 +70,6 @@ jobs: value: '' - name: publishLogsArtifactPrefix value: 'BuildLogs_CoreCLR' - - ${{ if and(ne(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}: - # Variables used to publish packages to blob feed - - name: dotnetfeedUrl - value: https://dotnetfeed.blob.core.windows.net/dotnet-coreclr/index.json - - name: dotnetfeedPAT - value: $(dotnetfeed-storage-access-key-1) - # Variables used by arcade to gather asset manifests - - name: _DotNetPublishToBlobFeed - value: true - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - group: AzureDevOps-Artifact-Feeds-Pats - name: officialBuildIdArg @@ -298,14 +289,6 @@ jobs: artifactName: $(nativeTestArtifactName) displayName: 'native test components' - # Get key vault secrets for publishing - - ${{ if and(ne(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}: - - task: AzureKeyVault@1 - inputs: - azureSubscription: 'DotNet-Engineering-Services_KeyVault' - KeyVaultName: EngKeyVault - SecretsFilter: 'dotnetfeed-storage-access-key-1,microsoft-symbol-server-pat,symweb-symbol-server-pat' - # Save packages using the prepare-signed-artifacts format. - ${{ if and(eq(parameters.isOfficialBuild, true), eq(parameters.pgoType, '')) }}: - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml diff --git a/eng/pipelines/mono/templates/build-job.yml b/eng/pipelines/mono/templates/build-job.yml index b1ac9c1cc6554e..845078804fbc7f 100644 --- a/eng/pipelines/mono/templates/build-job.yml +++ b/eng/pipelines/mono/templates/build-job.yml @@ -171,25 +171,6 @@ jobs: - script: build$(scriptExt) -subset mono+clr.hosts -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(aotCrossParameter) $(llvmParameter) -pack $(OutputRidArg) displayName: Build nupkg - # Publish official build - - ${{ if eq(parameters.publishToBlobFeed, 'true') }}: - - ${{ if ne(parameters.osGroup, 'windows') }}: - - script: $(Build.SourcesDirectory)/eng/common/build.sh --ci --restore --publish --configuration $(_BuildConfig) /p:DotNetPublishUsingPipelines=true /p:DotNetPublishToBlobFeed=true /p:DotNetPublishBlobFeedUrl=$(dotnetfeedUrl) /p:DotNetPublishBlobFeedKey=$(dotnetfeedPAT) /p:Configuration=$(_BuildConfig) /p:TargetArchitecture=$(archType) /p:TargetOS=$(osGroup) /p:OSIdentifier=$(osGroup)$(osSubgroup) /bl:"$(Build.SourcesDirectory)/artifacts/log/publish-pkgs.binlog" --projects $(Build.SourcesDirectory)/eng/empty.csproj - displayName: Publish packages to blob feed - env: - # TODO: remove NUGET_PACKAGES once https://github.com/dotnet/arcade/issues/1578 is fixed - NUGET_PACKAGES: $(Build.SourcesDirectory)/.packages - ${{ if eq(parameters.osGroup, 'freebsd') }}: - # Arcade uses this SDK instead of trying to restore one. - DotNetCoreSdkDir: /usr/local/dotnet - - ${{ if eq(parameters.osGroup, 'windows') }}: - # TODO: pass publish feed url and access token in from the internal pipeline - - powershell: eng\common\build.ps1 -ci -restore -publish -configuration $(_BuildConfig) /p:DotNetPublishUsingPipelines=true /p:DotNetPublishToBlobFeed=true /p:DotNetPublishBlobFeedUrl=$(dotnetfeedUrl) /p:DotNetPublishBlobFeedKey=$(dotnetfeedPAT) /p:Configuration=$(_BuildConfig) /p:TargetArchitecture=$(archType) /p:TargetOS=$(osGroup) /p:OSIdentifier=$(osGroup)$(osSubgroup) /bl:"$(Build.SourcesDirectory)\artifacts\log\publish-pkgs.binlog" -projects $(Build.SourcesDirectory)\eng\empty.csproj - displayName: Publish packages to blob feed - env: - # TODO: remove NUGET_PACKAGES once https://github.com/dotnet/arcade/issues/1578 is fixed - NUGET_PACKAGES: $(Build.SourcesDirectory)\.packages - # Publish Logs - task: PublishPipelineArtifact@1 displayName: Publish Logs From 0b84eae7fb5b2d577cdcec32446a9799de562494 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:29:52 +0200 Subject: [PATCH 706/783] [release/8.0] Avoid rooting X509Certificate2 in SslSessionCache (#101144) * Avoid rooting X509Certificate2 in SslSessionCache * Update src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs Co-authored-by: campersau --------- Co-authored-by: Radek Zikmund Co-authored-by: Radek Zikmund <32671551+rzikm@users.noreply.github.com> Co-authored-by: campersau --- .../Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs | 3 +-- .../src/System/Net/CertificateValidationPal.Windows.cs | 2 +- .../src/System/Net/Security/SslStreamPal.Windows.cs | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/libraries/Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs b/src/libraries/Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs index 91952869883769..272232f414ac92 100644 --- a/src/libraries/Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs +++ b/src/libraries/Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs @@ -312,13 +312,12 @@ internal sealed class SafeFreeCredential_SECURITY : SafeFreeCredentials { #pragma warning disable 0649 // This is used only by SslStream but it is included elsewhere - public X509Certificate? LocalCertificate; + public bool HasLocalCertificate; #pragma warning restore 0649 public SafeFreeCredential_SECURITY() : base() { } protected override bool ReleaseHandle() { - LocalCertificate?.Dispose(); return Interop.SspiCli.FreeCredentialsHandle(ref _handle) == 0; } } diff --git a/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Windows.cs index f0e58802dbda52..083c661661093e 100644 --- a/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Windows.cs @@ -105,7 +105,7 @@ internal static bool IsLocalCertificateUsed(SafeFreeCredentials? _credentialsHan // This is TLS Resumed session. Windows can fail to query the local cert bellow. // Instead, we will determine the usage form used credentials. SafeFreeCredential_SECURITY creds = (SafeFreeCredential_SECURITY)_credentialsHandle!; - return creds.LocalCertificate != null; + return creds.HasLocalCertificate; } SafeFreeCertContext? localContext = null; diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs index 45e77f49b6ecda..3ee2c8ac5612b8 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs @@ -231,8 +231,7 @@ public static SafeFreeCredentials AcquireCredentialsHandle(SslAuthenticationOpti if (newCredentialsRequested && sslAuthenticationOptions.CertificateContext != null) { SafeFreeCredential_SECURITY handle = (SafeFreeCredential_SECURITY)cred; - // We need to create copy to avoid Disposal issue. - handle.LocalCertificate = new X509Certificate2(sslAuthenticationOptions.CertificateContext.TargetCertificate); + handle.HasLocalCertificate = true; } return cred; From 535dd08e372abebbc3c92c892af0939c1aa63676 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 09:43:29 -0700 Subject: [PATCH 707/783] crashinfo.cpp/crasinfounix.cpp: use off_t instead of off64_t (#101272) Co-authored-by: Antoine Martin --- src/coreclr/debug/createdump/crashinfo.cpp | 2 +- src/coreclr/debug/createdump/crashinfounix.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/debug/createdump/crashinfo.cpp b/src/coreclr/debug/createdump/crashinfo.cpp index 996f3a81935d0f..d1d1b0ea0218b8 100644 --- a/src/coreclr/debug/createdump/crashinfo.cpp +++ b/src/coreclr/debug/createdump/crashinfo.cpp @@ -803,7 +803,7 @@ CrashInfo::PageMappedToPhysicalMemory(uint64_t start) } uint64_t pagemapOffset = (start / PAGE_SIZE) * sizeof(uint64_t); - uint64_t seekResult = lseek64(m_fdPagemap, (off64_t) pagemapOffset, SEEK_SET); + uint64_t seekResult = lseek(m_fdPagemap, (off_t) pagemapOffset, SEEK_SET); if (seekResult != pagemapOffset) { int seekErrno = errno; diff --git a/src/coreclr/debug/createdump/crashinfounix.cpp b/src/coreclr/debug/createdump/crashinfounix.cpp index 24b975e3d65559..2f4ea079de3b58 100644 --- a/src/coreclr/debug/createdump/crashinfounix.cpp +++ b/src/coreclr/debug/createdump/crashinfounix.cpp @@ -516,7 +516,7 @@ CrashInfo::ReadProcessMemory(void* address, void* buffer, size_t size, size_t* r // performance optimization. m_canUseProcVmReadSyscall = false; assert(m_fdMem != -1); - *read = pread64(m_fdMem, buffer, size, (off64_t)address); + *read = pread(m_fdMem, buffer, size, (off_t)address); } if (*read == (size_t)-1) From def0e85f3c050cc150f2261bdd9d82518362bc00 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Tue, 23 Apr 2024 14:03:38 -0500 Subject: [PATCH 708/783] TypeDescriptor threading fixes (#101305) --- .../System/ComponentModel/TypeDescriptor.cs | 62 +++-- .../tests/TypeDescriptorTests.cs | 247 ++++++++++++++++++ 2 files changed, 286 insertions(+), 23 deletions(-) diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs index 2efd53e6223ae7..948e3f4b386f35 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs @@ -28,7 +28,12 @@ public sealed class TypeDescriptor // class load anyway. private static readonly WeakHashtable s_providerTable = new WeakHashtable(); // mapping of type or object hash to a provider list private static readonly Hashtable s_providerTypeTable = new Hashtable(); // A direct mapping from type to provider. - private static readonly Hashtable s_defaultProviders = new Hashtable(); // A table of type -> default provider to track DefaultTypeDescriptionProviderAttributes. + + private static readonly Hashtable s_defaultProviderInitialized = new Hashtable(); // A table of type -> object to track DefaultTypeDescriptionProviderAttributes. + // A value of `null` indicates initialization is in progress. + // A value of s_initializedDefaultProvider indicates the provider is initialized. + private static readonly object s_initializedDefaultProvider = new object(); + private static WeakHashtable? s_associationTable; private static int s_metadataVersion; // a version stamp for our metadata. Used by property descriptors to know when to rebuild attributes. @@ -75,8 +80,6 @@ public sealed class TypeDescriptor Guid.NewGuid() // events }; - private static readonly object s_internalSyncObject = new object(); - private TypeDescriptor() { } @@ -262,32 +265,43 @@ public static void AddProviderTransparent(TypeDescriptionProvider provider, obje /// private static void CheckDefaultProvider(Type type) { - if (s_defaultProviders.ContainsKey(type)) + if (s_defaultProviderInitialized[type] == s_initializedDefaultProvider) { return; } - lock (s_internalSyncObject) + // Lock on s_providerTable even though s_providerTable is not modified here. + // Using a single lock prevents deadlocks since other methods that call into or are called + // by this method also lock on s_providerTable and the ordering of the locks may be different. + lock (s_providerTable) { - if (s_defaultProviders.ContainsKey(type)) - { - return; - } + AddDefaultProvider(type); + } + } - // Immediately clear this. If we find a default provider - // and it starts messing around with type information, - // this could infinitely recurse. - s_defaultProviders[type] = null; + /// + /// Add the default provider, if it exists. + /// For threading, this is always called under a 'lock (s_providerTable)'. + /// + private static void AddDefaultProvider(Type type) + { + bool providerAdded = false; + + if (s_defaultProviderInitialized.ContainsKey(type)) + { + // Either another thread finished initializing for this type, or we are recursing on the same thread. + return; } - // Always use core reflection when checking for - // the default provider attribute. If there is a - // provider, we probably don't want to build up our - // own cache state against the type. There shouldn't be - // more than one of these, but walk anyway. Walk in - // reverse order so that the most derived takes precidence. + // Immediately set this to null to indicate we are in progress setting the default provider for a type. + // This prevents re-entrance to this method. + s_defaultProviderInitialized[type] = null; + + // Always use core reflection when checking for the default provider attribute. + // If there is a provider, we probably don't want to build up our own cache state against the type. + // There shouldn't be more than one of these, but walk anyway. + // Walk in reverse order so that the most derived takes precedence. object[] attrs = type.GetCustomAttributes(typeof(TypeDescriptionProviderAttribute), false); - bool providerAdded = false; for (int idx = attrs.Length - 1; idx >= 0; idx--) { TypeDescriptionProviderAttribute pa = (TypeDescriptionProviderAttribute)attrs[idx]; @@ -306,17 +320,19 @@ private static void CheckDefaultProvider(Type type) Type? baseType = type.BaseType; if (baseType != null && baseType != type) { - CheckDefaultProvider(baseType); + AddDefaultProvider(baseType); } } + + s_defaultProviderInitialized[type] = s_initializedDefaultProvider; } /// - /// The CreateAssocation method creates an association between two objects. + /// The CreateAssociation method creates an association between two objects. /// Once an association is created, a designer or other filtering mechanism /// can add properties that route to either object into the primary object's /// property set. When a property invocation is made against the primary - /// object, GetAssocation will be called to resolve the actual object + /// object, GetAssociation will be called to resolve the actual object /// instance that is related to its type parameter. /// [EditorBrowsable(EditorBrowsableState.Advanced)] diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptorTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptorTests.cs index 299d73cfe31502..c8d85842d86d0b 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptorTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptorTests.cs @@ -5,6 +5,10 @@ using System.Collections.Generic; using System.ComponentModel.Design; using System.Globalization; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.DotNet.RemoteExecutor; using Moq; using Xunit; @@ -1231,5 +1235,248 @@ protected DerivedCultureInfo() : base("hello") class TwiceDerivedCultureInfo : DerivedCultureInfo { } + + private long _concurrentError = 0; + private bool ConcurrentError + { + get => Interlocked.Read(ref _concurrentError) == 1; + set => Interlocked.Exchange(ref _concurrentError, value ? 1 : 0); + } + + private void ConcurrentTest(TypeWithProperty instance) + { + var properties = TypeDescriptor.GetProperties(instance); + Thread.Sleep(10); + if (properties.Count > 0) + { + ConcurrentError = true; + } + } + + [SkipOnPlatform(TestPlatforms.Browser, "Thread.Start is not supported on browsers.")] + [Fact] + public void ConcurrentGetProperties_ReturnsExpected() + { + const int Timeout = 60000; + int concurrentCount = Environment.ProcessorCount * 2; + + using var finished = new CountdownEvent(concurrentCount); + + var instances = new TypeWithProperty[concurrentCount]; + for (int i = 0; i < concurrentCount; i++) + { + instances[i] = new TypeWithProperty(); + } + + for (int i = 0; i < concurrentCount; i++) + { + int i2 = i; + new Thread(() => + { + ConcurrentTest(instances[i2]); + finished.Signal(); + }).Start(); + } + + finished.Wait(Timeout); + + if (finished.CurrentCount != 0) + { + Assert.Fail("Timeout. Possible deadlock."); + } + else + { + Assert.False(ConcurrentError, "Fallback type descriptor is used. Possible race condition."); + } + } + + [SkipOnPlatform(TestPlatforms.Browser, "Thread.Start is not supported on browsers.")] + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public static void ConcurrentAddProviderAndGetProvider() + { + // Use a timeout value lower than RemoteExecutor in order to get a nice Fail message. + const int Timeout = 50000; + + RemoteInvokeOptions options = new() + { + TimeOut = 60000 + }; + + RemoteExecutor.Invoke(() => + { + using var finished = new CountdownEvent(2); + Thread t1 = new Thread(() => + { + ConcurrentAddProvider(); + finished.Signal(); + }); + Thread t2 = new Thread(() => + { + ConcurrentGetProvider(); + finished.Signal(); + }); + t1.Start(); + t2.Start(); + finished.Wait(Timeout); + if (finished.CurrentCount != 0) + { + Assert.Fail("Timeout. Possible deadlock."); + } + }, options).Dispose(); + + static void ConcurrentAddProvider() + { + var provider = new EmptyPropertiesTypeProvider(); + TypeDescriptor.AddProvider(provider, typeof(MyClass)); + + // This test primarily verifies no deadlock, but verify the values anyway. + Assert.True(TypeDescriptor.GetProvider(typeof(MyClass)).IsSupportedType(typeof(MyClass))); + } + + static void ConcurrentGetProvider() + { + TypeDescriptionProvider provider = TypeDescriptor.GetProvider(typeof(TypeWithProperty)); + + // This test primarily verifies no deadlock, but verify the values anyway. + Assert.True(provider.IsSupportedType(typeof(TypeWithProperty))); + } + } + + public sealed class EmptyPropertiesTypeProvider : TypeDescriptionProvider + { + private sealed class EmptyPropertyListDescriptor : ICustomTypeDescriptor + { + public AttributeCollection GetAttributes() => AttributeCollection.Empty; + + public string? GetClassName() => null; + + public string? GetComponentName() => null; + + public TypeConverter? GetConverter() => new TypeConverter(); + + public EventDescriptor? GetDefaultEvent() => null; + + public PropertyDescriptor? GetDefaultProperty() => null; + + public object? GetEditor(Type editorBaseType) => null; + + public EventDescriptorCollection GetEvents() => EventDescriptorCollection.Empty; + + public EventDescriptorCollection GetEvents(Attribute[]? attributes) => GetEvents(); + + public PropertyDescriptorCollection GetProperties() => PropertyDescriptorCollection.Empty; + + public PropertyDescriptorCollection GetProperties(Attribute[]? attributes) => GetProperties(); + + public object? GetPropertyOwner(PropertyDescriptor? pd) => null; + } + public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object? instance) + { + return new EmptyPropertyListDescriptor(); + } + } + + [TypeDescriptionProvider(typeof(EmptyPropertiesTypeProvider))] + public sealed class TypeWithProperty + { + public int OneProperty { get; set; } + } + + public static IEnumerable GetConverter_ByMultithread_ReturnsExpected_TestData() + { + yield return new object[] { typeof(MyClass), typeof(MyTypeConverter) }; + yield return new object[] { typeof(MyInheritedClassWithCustomTypeDescriptionProvider), typeof(MyInheritedClassWithCustomTypeDescriptionProviderConverter) }; + yield return new object[] { typeof(MyInheritedClassWithInheritedTypeDescriptionProvider), typeof(MyTypeConverter) }; + } + + [Theory] + [MemberData(nameof(GetConverter_ByMultithread_ReturnsExpected_TestData))] + public async void GetConverter_ByMultithread_ReturnsExpected(Type typeForGetConverter, Type expectedConverterType) + { + TypeConverter[] actualConverters = await Task.WhenAll( + Enumerable.Range(0, 100).Select(_ => + Task.Run(() => TypeDescriptor.GetConverter(typeForGetConverter)))); + Assert.All(actualConverters, + currentConverter => Assert.IsType(expectedConverterType, currentConverter)); + } + + public static IEnumerable GetConverterWithAddProvider_ByMultithread_Success_TestData() + { + foreach (object[] currentTestCase in GetConverter_ByMultithread_ReturnsExpected_TestData()) + { + yield return currentTestCase; + } + } + + [Theory] + [MemberData(nameof(GetConverterWithAddProvider_ByMultithread_Success_TestData))] + public async void GetConverterWithAddProvider_ByMultithread_Success(Type typeForGetConverter, Type expectedConverterType) + { + TypeConverter[] actualConverters = await Task.WhenAll( + Enumerable.Range(0, 200).Select(_ => + Task.Run(() => + { + var mockProvider = new Mock(MockBehavior.Strict); + var someInstance = new object(); + TypeDescriptor.AddProvider(mockProvider.Object, someInstance); + return TypeDescriptor.GetConverter(typeForGetConverter); + }))); + Assert.All(actualConverters, + currentConverter => Assert.IsType(expectedConverterType, currentConverter)); + } + + [TypeDescriptionProvider(typeof(MyClassTypeDescriptionProvider))] + public class MyClass + { + } + + [TypeDescriptionProvider(typeof(MyInheritedClassWithCustomTypeDescriptionProviderTypeDescriptionProvider))] + public class MyInheritedClassWithCustomTypeDescriptionProvider : MyClass + { + } + + public class MyInheritedClassWithInheritedTypeDescriptionProvider : MyClass + { + } + + public class MyClassTypeDescriptionProvider : TypeDescriptionProvider + { + public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) + { + return new MyClassTypeDescriptor(); + } + } + + public class MyInheritedClassWithCustomTypeDescriptionProviderTypeDescriptionProvider : TypeDescriptionProvider + { + public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) + { + return new MyInheritedClassWithCustomTypeDescriptionProviderTypeDescriptor(); + } + } + + public class MyClassTypeDescriptor : CustomTypeDescriptor + { + public override TypeConverter GetConverter() + { + return new MyTypeConverter(); + } + } + + public class MyInheritedClassWithCustomTypeDescriptionProviderTypeDescriptor : CustomTypeDescriptor + { + public override TypeConverter GetConverter() + { + return new MyInheritedClassWithCustomTypeDescriptionProviderConverter(); + } + } + + public class MyTypeConverter : TypeConverter + { + } + + public class MyInheritedClassWithCustomTypeDescriptionProviderConverter : TypeConverter + { + } } } From 11c5492e450eaa810bd78a2f9020215b29d63638 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Wed, 24 Apr 2024 08:54:23 -0700 Subject: [PATCH 709/783] Update EOL versions in release/8.0-staging (#101073) * Update EOL OS versions * Revert missing images * Revert missing images --- .../templates/pipeline-with-resources.yml | 6 ++-- .../coreclr/templates/helix-queues-setup.yml | 14 ++++---- .../libraries/helix-queues-setup.yml | 36 +++++++++---------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/eng/pipelines/common/templates/pipeline-with-resources.yml b/eng/pipelines/common/templates/pipeline-with-resources.yml index 02242394fba671..edba5767b612c5 100644 --- a/eng/pipelines/common/templates/pipeline-with-resources.yml +++ b/eng/pipelines/common/templates/pipeline-with-resources.yml @@ -55,9 +55,9 @@ resources: - container: linux_x64_dev_innerloop image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04 - # We use a CentOS Stream 8 image here to test building from source on CentOS Stream 8. + # We use a CentOS Stream 9 image here to test building from source on CentOS Stream 9. - container: SourceBuild_centos_x64 - image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8 + image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9 # AlmaLinux 8 is a RHEL 8 rebuild, so we use it to test building from source on RHEL 8. - container: SourceBuild_linux_x64 @@ -82,7 +82,7 @@ resources: image: mcr.microsoft.com/dotnet-buildtools/prereqs:debian-12-gcc13-amd64 - container: linux_x64_llvmaot - image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8 + image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9 - container: browser_wasm image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly-20230913040940-1edc1c6 diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml index 9a57f32f5e60d2..378396bc323a37 100644 --- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml +++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml @@ -52,7 +52,7 @@ jobs: # Browser wasm - ${{ if eq(parameters.platform, 'browser_wasm') }}: - - (Ubuntu.1804.Amd64)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-webassembly + - (Ubuntu.1804.Amd64)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-webassembly # iOS devices - ${{ if in(parameters.platform, 'ios_arm64') }}: @@ -65,16 +65,16 @@ jobs: # Linux arm - ${{ if eq(parameters.platform, 'linux_arm') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - (Ubuntu.1804.Arm32.Open)Ubuntu.1804.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm32v7 + - (Ubuntu.1804.Arm32.Open)Ubuntu.2204.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm32v7 - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - (Ubuntu.1804.Arm32)Ubuntu.1804.Armarch@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm32v7 + - (Ubuntu.1804.Arm32)Ubuntu.2204.Armarch@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm32v7 # Linux arm64 - ${{ if eq(parameters.platform, 'linux_arm64') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - (Ubuntu.1804.Arm64.Open)Ubuntu.1804.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm64v8 + - (Ubuntu.2204.Arm64.Open)Ubuntu.2204.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-helix-arm64v8 - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - (Ubuntu.1804.Arm64)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm64v8 + - (Ubuntu.1804.Arm64)Ubuntu.2204.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm64v8 # Linux musl x64 - ${{ if eq(parameters.platform, 'linux_musl_x64') }}: @@ -100,9 +100,9 @@ jobs: # Linux x64 - ${{ if eq(parameters.platform, 'linux_x64') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - Ubuntu.1804.Amd64.Open + - Ubuntu.2004.Amd64.Open - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - Ubuntu.1804.Amd64 + - Ubuntu.2004.Amd64 # OSX arm64 - ${{ if eq(parameters.platform, 'osx_arm64') }}: diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 8acabe6ec38efc..d3d7e7b2e64f8e 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -28,21 +28,21 @@ jobs: # Linux arm - ${{ if eq(parameters.platform, 'linux_arm') }}: - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - - (Debian.11.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-arm32v7 + - (Debian.11.Arm32.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-arm32v7 # Linux armv6 - ${{ if eq(parameters.platform, 'linux_armv6') }}: # - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}: - - (Raspbian.10.Armv6.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:raspbian-10-helix-arm32v6 + - (Raspbian.10.Armv6.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:raspbian-10-helix-arm32v6 # Linux arm64 - ${{ if eq(parameters.platform, 'linux_arm64') }}: - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - - (Ubuntu.2204.Arm64.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-helix-arm64v8 + - (Ubuntu.2204.Arm64.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-helix-arm64v8 - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - - (Ubuntu.1804.Arm64.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm64v8 + - (Ubuntu.1804.Arm64.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm64v8 - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - - (Debian.11.Arm64.Open)Ubuntu.1804.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-arm64v8 + - (Debian.11.Arm64.Open)Ubuntu.2204.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-arm64v8 # Linux musl x64 - ${{ if eq(parameters.platform, 'linux_musl_x64') }}: @@ -61,25 +61,25 @@ jobs: - ${{ if and(eq(parameters.jobParameters.interpreter, ''), ne(parameters.jobParameters.isSingleFile, true)) }}: - ${{ if and(eq(parameters.jobParameters.testScope, 'outerloop'), eq(parameters.jobParameters.runtimeFlavor, 'mono')) }}: - SLES.15.Amd64.Open - - (Centos.8.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8-helix - - (Fedora.38.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-38-helix - - (Ubuntu.2204.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-helix-amd64 + - (Centos.9.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9-helix + - (Fedora.39.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-39-helix + - (Ubuntu.2204.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-helix-amd64 - (Debian.11.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64 - ${{ if or(ne(parameters.jobParameters.testScope, 'outerloop'), ne(parameters.jobParameters.runtimeFlavor, 'mono')) }}: - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - SLES.15.Amd64.Open - - (Fedora.38.Amd64.Open)ubuntu.1804.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-38-helix + - (Fedora.39.Amd64.Open)Ubuntu.2204.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-39-helix - Ubuntu.2204.Amd64.Open - - (Debian.11.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64 - - (Mariner.2.0.Amd64.Open)ubuntu.1804.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-helix-amd64 - - (openSUSE.15.2.Amd64.Open)ubuntu.1804.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:opensuse-15.2-helix-amd64 + - (Debian.11.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64 + - (Mariner.2.0.Amd64.Open)Ubuntu.2204.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-helix-amd64 + - (openSUSE.15.2.Amd64.Open)Ubuntu.2204.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:opensuse-15.2-helix-amd64 - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - - (Centos.8.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8-helix - - (Debian.11.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64 + - (Centos.9.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9-helix + - (Debian.11.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64 - Ubuntu.1804.Amd64.Open - ${{ if or(eq(parameters.jobParameters.interpreter, 'true'), eq(parameters.jobParameters.isSingleFile, true)) }}: # Limiting interp runs as we don't need as much coverage. - - (Debian.11.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64 + - (Debian.11.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64 # Linux s390x - ${{ if eq(parameters.platform, 'linux_s390x') }}: @@ -171,15 +171,15 @@ jobs: # WASI - ${{ if eq(parameters.platform, 'wasi_wasm') }}: - - (Ubuntu.2004.Amd64)Ubuntu.2004.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-helix-wasm-amd64 + - (Ubuntu.2004.Amd64)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-helix-wasm-amd64 # Browser WebAssembly - ${{ if eq(parameters.platform, 'browser_wasm') }}: - - (Ubuntu.1804.Amd64)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-webassembly + - (Ubuntu.1804.Amd64)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-webassembly # Browser WebAssembly Firefox - ${{ if eq(parameters.platform, 'browser_wasm_firefox') }}: - - (Ubuntu.1804.Amd64)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-webassembly + - (Ubuntu.1804.Amd64)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-webassembly # Browser WebAssembly windows - ${{ if in(parameters.platform, 'browser_wasm_win', 'wasi_wasm_win') }}: From 845cd4f6526b529a323c3e91fda37ba2768f6e42 Mon Sep 17 00:00:00 2001 From: Eduardo Velarde <32459232+eduardo-vp@users.noreply.github.com> Date: Thu, 25 Apr 2024 11:36:59 -0700 Subject: [PATCH 710/783] Merge #91646 and #91708 into release/8.0-staging (#101313) * Move CoreCLR community platforms to build with the global build template (#91646) * Try to disable VSIX update service and collect VS update logs (#91708) * Tweak invocations, disable service updates, detect vswhere missing * Try disabling update early in build * Only collect logs on official build on exit --------- Co-authored-by: Jeremy Koritzinsky Co-authored-by: Juan Hoyos <19413848+hoyosjs@users.noreply.github.com> --- eng/build.sh | 2 +- eng/collect_vsinfo.ps1 | 65 +++++++++++++++++++ eng/disable_vsupdate.ps1 | 23 +++++++ eng/native/init-vs-env.cmd | 6 ++ eng/pipelines/common/global-build-job.yml | 5 ++ eng/pipelines/common/platform-matrix.yml | 2 +- eng/pipelines/coreclr/templates/build-job.yml | 28 +++----- eng/pipelines/installer/jobs/build-job.yml | 6 ++ eng/pipelines/mono/templates/build-job.yml | 4 ++ eng/pipelines/runtime.yml | 44 ++++++++++++- 10 files changed, 163 insertions(+), 22 deletions(-) create mode 100644 eng/collect_vsinfo.ps1 create mode 100644 eng/disable_vsupdate.ps1 diff --git a/eng/build.sh b/eng/build.sh index 772d7ac8be82cb..4d0d17a220447d 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -32,7 +32,7 @@ usage() echo " [Default: Debug]" echo " --os Target operating system: windows, linux, freebsd, osx, maccatalyst, tvos," echo " tvossimulator, ios, iossimulator, android, browser, wasi, netbsd, illumos, solaris" - echo " linux-musl, linux-bionic or haiku." + echo " linux-musl, linux-bionic, tizen, or haiku." echo " [Default: Your machine's OS.]" echo " --outputrid Optional argument that overrides the target rid name." echo " --projects Project or solution file(s) to build." diff --git a/eng/collect_vsinfo.ps1 b/eng/collect_vsinfo.ps1 new file mode 100644 index 00000000000000..e2178fe4b24f8f --- /dev/null +++ b/eng/collect_vsinfo.ps1 @@ -0,0 +1,65 @@ +<# +.PARAMETER ArchiveRunName +Name of the run for vs logs + +.NOTES +Returns 0 if succeeds, 1 otherwise +#> +[CmdletBinding(PositionalBinding=$false)] +Param ( + [Parameter(Mandatory=$True)] + [string] $ArchiveRunName +) + +. $PSScriptRoot/common/tools.ps1 + +$ProgressPreference = "SilentlyContinue" +$LogDir = Join-Path $LogDir $ArchiveRunName +mkdir $LogDir + +$vscollect_uri="http://aka.ms/vscollect.exe" +$vscollect="$env:TEMP\vscollect.exe" + +if (-not (Test-Path $vscollect)) { + Retry({ + Write-Host "GET $vscollect_uri" + Invoke-WebRequest $vscollect_uri -OutFile $vscollect -UseBasicParsing + }) + + if (-not (Test-Path $vscollect)) { + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Unable to download vscollect." + exit 1 + } +} + +&"$vscollect" +Move-Item $env:TEMP\vslogs.zip "$LogDir" + +$vswhere = "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" +if (-not (Test-Path -Path "$vswhere" -PathType Leaf)) +{ + Write-Error "Couldn't locate vswhere at $vswhere" + exit 1 +} + +&"$vswhere" -all -prerelease -products * | Tee-Object -FilePath "$LogDir\vs_where.log" + +$vsdir = &"$vswhere" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath + +if (-not (Test-Path $vsdir)) +{ + $procDumpDir = Join-Path $ToolsDir "procdump" + $procDumpToolPath = Join-Path $procDumpDir "procdump.exe" + $procdump_uri = "https://download.sysinternals.com/files/Procdump.zip" + + if (-not (Test-Path $procDumpToolPath)) { + Retry({ + Write-Host "GET $procdump_uri" + Invoke-WebRequest $procdump_uri -OutFile "$TempDir\Procdump.zip" -UseBasicParsing + }) + + Expand-Archive -Path "$TempDir\Procdump.zip" $procDumpDir + } + + &"$procDumpToolPath" -ma -accepteula VSIXAutoUpdate.exe "$LogDir" +} diff --git a/eng/disable_vsupdate.ps1 b/eng/disable_vsupdate.ps1 new file mode 100644 index 00000000000000..d8d365f0577103 --- /dev/null +++ b/eng/disable_vsupdate.ps1 @@ -0,0 +1,23 @@ +schtasks /change /tn "\Microsoft\VisualStudio\VSIX Auto Update" /disable + +$vswhere = "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" +if (-not (Test-Path -Path "$vswhere" -PathType Leaf)) +{ + Write-Error "Couldn't locate vswhere at $vswhere" + exit 1 +} + +$vsdir = &"$vswhere" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath +$vsregedit = "$vsdir\Common7\IDE\VsRegEdit.exe" + +if (-not (Test-Path -Path "$vsregedit" )) +{ + Write-Error "VSWhere returned path: $vsdir, but regedit $vsregedit doesn't exist." + exit 1 +} + +Write-Output "VSWhere returned path: $vsdir, using regedit $vsregedit" +Write-Output "Disabling updates through VS Registry:" + +&"$vsdir\Common7\IDE\VsRegEdit.exe" set local HKCU ExtensionManager AutomaticallyCheckForUpdates2Override dword 0 +&"$vsdir\Common7\IDE\VsRegEdit.exe" read local HKCU ExtensionManager AutomaticallyCheckForUpdates2Override dword diff --git a/eng/native/init-vs-env.cmd b/eng/native/init-vs-env.cmd index 273f49b3392c2d..befe98ab407f72 100644 --- a/eng/native/init-vs-env.cmd +++ b/eng/native/init-vs-env.cmd @@ -26,6 +26,8 @@ if defined VisualStudioVersion goto :VSDetected set "__VSWhere=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" set "__VSCOMNTOOLS=" +if not exist "%__VSWhere%" goto :VSWhereMissing + if exist "%__VSWhere%" ( for /f "tokens=*" %%p in ( '"%__VSWhere%" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath' @@ -56,6 +58,10 @@ echo %__MsgPrefix%Error: Visual Studio 2022 with C++ tools required. ^ Please see https://github.com/dotnet/runtime/blob/main/docs/workflow/requirements/windows-requirements.md for build requirements. exit /b 1 +:VSWhereMissing +echo %__MsgPrefix%Error: vswhere couldn not be found in Visual Studio Installer directory at "%__VSWhere%" +exit /b 1 + :SetVCEnvironment if "%__VCBuildArch%"=="" exit /b 0 diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index 39e7d9b5c53ced..0d2ceac932d721 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -254,6 +254,11 @@ jobs: shouldContinueOnError: ${{ parameters.shouldContinueOnError }} ${{ insert }}: ${{ parameters.extraStepsParameters }} + - ${{ if and(eq(parameters.isOfficialBuild, true), eq(parameters.osGroup, 'windows')) }}: + - powershell: ./eng/collect_vsinfo.ps1 -ArchiveRunName postbuild_log + displayName: Collect vslogs on exit + condition: always() + - task: PublishBuildArtifacts@1 displayName: Publish Logs inputs: diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index 8399c82ecd7695..c2f754d6ee2385 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -883,7 +883,7 @@ jobs: jobTemplate: ${{ parameters.jobTemplate }} helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }} variables: ${{ parameters.variables }} - osGroup: tizen + osGroup: linux # Our build scripts don't support Tizen and have always used Linux as the OS parameter. archType: armel targetRid: tizen-armel platform: tizen_armel diff --git a/eng/pipelines/coreclr/templates/build-job.yml b/eng/pipelines/coreclr/templates/build-job.yml index 2e128ea54e1287..01d12e6452b4cf 100644 --- a/eng/pipelines/coreclr/templates/build-job.yml +++ b/eng/pipelines/coreclr/templates/build-job.yml @@ -95,9 +95,6 @@ jobs: - ${{ if ne(parameters.testGroup, 'innerloop') }}: - name: clrRuntimeComponentsBuildArg value: '-component runtime -component alljits -component paltests -component nativeaot -component spmi ' - - ${{ if and(eq(parameters.osGroup, 'linux'), eq(parameters.archType, 'x86')) }}: - - name: clrRuntimeComponentsBuildArg - value: '-component runtime -component jit -component iltools -component spmi ' - name: pgoInstrumentArg value: '' @@ -108,12 +105,6 @@ jobs: - name: SignType value: $[ coalesce(variables.OfficialSignType, 'real') ] - - name: clrRuntimePortableBuildArg - value: '' - - ${{ if eq(parameters.osGroup, 'tizen') }}: - - name: clrRuntimePortableBuildArg - value: '-portablebuild=false' - # Set a default empty argument for the pgo path. # This will be set during the 'native prerequisites' step if PGO optimization is enabled. - name: CoreClrPgoDataArg @@ -128,7 +119,6 @@ jobs: - ${{ parameters.variables }} steps: - # Install native dependencies # Linux builds use docker images with dependencies preinstalled, # and FreeBSD builds use a build agent with dependencies @@ -185,14 +175,14 @@ jobs: # Build CoreCLR Runtime - ${{ if ne(parameters.osGroup, 'windows') }}: - - script: $(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) $(archType) $(crossArg) $(osArg) -ci $(compilerArg) $(clrRuntimeComponentsBuildArg) $(pgoInstrumentArg) $(officialBuildIdArg) $(clrInterpreterBuildArg) $(clrRuntimePortableBuildArg) $(CoreClrPgoDataArg) $(nativeSymbols) + - script: $(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) $(archType) $(crossArg) $(osArg) -ci $(compilerArg) $(clrRuntimeComponentsBuildArg) $(pgoInstrumentArg) $(officialBuildIdArg) $(clrInterpreterBuildArg) $(CoreClrPgoDataArg) $(nativeSymbols) displayName: Build CoreCLR Runtime - ${{ if eq(parameters.osGroup, 'windows') }}: - script: $(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) $(archType) -ci $(enforcePgoArg) $(pgoInstrumentArg) $(officialBuildIdArg) $(clrInterpreterBuildArg) $(CoreClrPgoDataArg) displayName: Build CoreCLR Runtime - ${{ if or(eq(parameters.crossBuild, 'true'), ne(parameters.archType, 'x64')) }}: - - script: $(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) $(archType) -hostarch x64 $(osArg) -ci $(compilerArg) -component crosscomponents -cmakeargs "-DCLR_CROSS_COMPONENTS_BUILD=1" $(officialBuildIdArg) $(clrRuntimePortableBuildArg) + - script: $(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) $(archType) -hostarch x64 $(osArg) -ci $(compilerArg) -component crosscomponents -cmakeargs "-DCLR_CROSS_COMPONENTS_BUILD=1" $(officialBuildIdArg) displayName: Build CoreCLR Cross-Arch Tools (Tools that run on x64 targeting x86) - ${{ if in(parameters.osGroup, 'osx', 'ios', 'tvos') }}: @@ -202,12 +192,8 @@ jobs: displayName: Disk Usage after Build # Build CoreCLR Managed Components - - ${{ if or(ne(parameters.osGroup, 'linux'), ne(parameters.archType, 'x86')) }}: - - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.corelib+clr.nativecorelib+clr.nativeaotlibs+clr.tools+clr.packages+clr.paltestlist $(crossArg) $(compilerArg) -arch $(archType) $(osArg) -c $(buildConfig) $(pgoInstrumentArg) $(officialBuildIdArg) -ci - displayName: Build managed product components and packages - - ${{ if and(eq(parameters.osGroup, 'linux'), eq(parameters.archType, 'x86')) }}: - - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.corelib $(crossArg) -arch $(archType) $(osArg) -c $(buildConfig) $(pgoInstrumentArg) $(officialBuildIdArg) -ci - displayName: Build managed product components and packages + - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.corelib+clr.nativecorelib+clr.nativeaotlibs+clr.tools+clr.packages+clr.paltestlist $(crossArg) $(compilerArg) -arch $(archType) $(osArg) -c $(buildConfig) $(pgoInstrumentArg) $(officialBuildIdArg) -ci + displayName: Build managed product components and packages # Build native test components - ${{ if and(ne(parameters.isOfficialBuild, true), ne(parameters.disableClrTest, true)) }}: @@ -295,6 +281,12 @@ jobs: parameters: name: ${{ parameters.platform }} + - ${{ if and(eq(parameters.isOfficialBuild, true), eq(parameters.osGroup, 'windows')) }}: + - powershell: ./eng/collect_vsinfo.ps1 -ArchiveRunName postbuild_log + displayName: Collect vslogs on exit + condition: always() + + # Publish Logs - task: PublishPipelineArtifact@1 displayName: Publish Logs diff --git a/eng/pipelines/installer/jobs/build-job.yml b/eng/pipelines/installer/jobs/build-job.yml index 1d89cfad70eb20..3e18fb3d96392a 100644 --- a/eng/pipelines/installer/jobs/build-job.yml +++ b/eng/pipelines/installer/jobs/build-job.yml @@ -370,6 +370,12 @@ jobs: displayName: Build and Package continueOnError: ${{ and(eq(variables.SkipTests, false), eq(parameters.shouldContinueOnError, true)) }} + - ${{ if and(eq(parameters.isOfficialBuild, true), eq(parameters.osGroup, 'windows')) }}: + - powershell: ./eng/collect_vsinfo.ps1 -ArchiveRunName postbuild_log + displayName: Collect vslogs on exit + condition: always() + + - ${{ if in(parameters.osGroup, 'osx', 'ios', 'tvos') }}: - script: | du -sh $(Build.SourcesDirectory)/* diff --git a/eng/pipelines/mono/templates/build-job.yml b/eng/pipelines/mono/templates/build-job.yml index 845078804fbc7f..0c823e8d573710 100644 --- a/eng/pipelines/mono/templates/build-job.yml +++ b/eng/pipelines/mono/templates/build-job.yml @@ -171,6 +171,10 @@ jobs: - script: build$(scriptExt) -subset mono+clr.hosts -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(aotCrossParameter) $(llvmParameter) -pack $(OutputRidArg) displayName: Build nupkg + - ${{ if and(eq(parameters.isOfficialBuild, true), eq(parameters.osGroup, 'windows')) }}: + - powershell: ./eng/collect_vsinfo.ps1 -ArchiveRunName postbuild_log + displayName: Collect vslogs on exit + condition: always() # Publish Logs - task: PublishPipelineArtifact@1 displayName: Publish Logs diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 3aa0b6504819a7..f2657982aee552 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -70,7 +70,6 @@ extends: jobTemplate: /eng/pipelines/coreclr/templates/build-job.yml buildConfig: checked platforms: - - linux_x86 - linux_x64 - linux_arm - linux_arm64 @@ -79,7 +78,6 @@ extends: - linux_musl_arm64 - linux_musl_x64 - osx_arm64 - - tizen_armel - windows_x86 - windows_x64 - windows_arm64 @@ -188,6 +186,48 @@ extends: eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr_jit.containsChange'], true), eq(variables['isRollingBuild'], true))) + # + # Build CoreCLR with no R2R + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: checked + runtimeFlavor: coreclr + platforms: + - linux_x86 + jobParameters: + testScope: innerloop + nameSuffix: CoreCLR_NoR2R + buildArgs: -s clr.runtime+clr.jit+clr.iltools+clr.spmi+clr.corelib -c $(_BuildConfig) + timeoutInMinutes: 120 + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), + eq(variables['isRollingBuild'], true)) + + # + # Build CoreCLR as a non-portable build + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: checked + runtimeFlavor: coreclr + platforms: + - tizen_armel + jobParameters: + testScope: innerloop + nameSuffix: CoreCLR_NonPortable + buildArgs: -s clr.native+clr.tools+clr.corelib+clr.nativecorelib+clr.aot+clr.packages -c $(_BuildConfig) /p:PortableBuild=false + timeoutInMinutes: 120 + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), + eq(variables['isRollingBuild'], true)) + # # CoreCLR NativeAOT debug build and smoke tests # Only when CoreCLR is changed From b86ccd0c240dc19aafff43387e461ac568c71276 Mon Sep 17 00:00:00 2001 From: Eduardo Velarde <32459232+eduardo-vp@users.noreply.github.com> Date: Sun, 28 Apr 2024 15:05:42 -0700 Subject: [PATCH 711/783] Backport #89953, #91658 and #91643 to release/8.0-staging (#101579) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Stop skipping tests in installer pipeline on linux_x64 (#89953) - Run tests in in installer pipeline on Linux_x64 even though it is cross-build. - Fix uploading of binaries/symbols on failure * Append job attempt number to log artifact names (#91658) Avoids errors like "Artifact Installer-Logs-coreclr--windows_arm64-Debug already exists for build 1636423." when retrying jobs. * Separate running PAL tests out to their own jobs/steps. (#91643) * Separate running PAL tests out to their own jobs/steps. * Remove PAL tests running infra from the CoreCLR build job and the runtime tests templates. * !drop Strip out all jobs from runtime.yml and replace with the new PAL tests job to make it easier to test * Remove dependency on EvaluatePaths * Reparent job parameters correctly. * Add back EvaluatePaths step for simplicity * Set missing properties * Capitalize build config * Make a tarball to preserve permission bits. * Make the output path directory before trying to use it * Double timeout * Double timeout again. Looks like Mac needs it. * Fix metadata name and put back to 10 minutes. * Move changes to the correct pipeline and revert changes to runtime.yml * Remove reference to deleted target --------- Co-authored-by: Elinor Fung Co-authored-by: Alexander Köplinger Co-authored-by: Jeremy Koritzinsky --- eng/pipelines/common/global-build-job.yml | 4 +- .../templates/runtimes/build-test-job.yml | 2 +- .../templates/runtimes/run-test-job.yml | 6 +-- .../templates/runtimes/send-to-helix-step.yml | 2 - eng/pipelines/coreclr/ci.yml | 20 ++++++++ .../coreclr/templates/build-jit-job.yml | 2 +- eng/pipelines/coreclr/templates/build-job.yml | 6 +-- .../coreclr/templates/crossdac-pack.yml | 2 +- .../coreclr/templates/run-paltests-step.yml | 23 +++++++++ eng/pipelines/installer/jobs/build-job.yml | 13 ++++- .../jobs/steps/upload-job-artifacts.yml | 2 +- eng/pipelines/mono/templates/build-job.yml | 2 +- .../mono/templates/generate-offsets.yml | 2 +- .../mono/templates/workloads-build.yml | 2 +- src/coreclr/scripts/paltests.proj | 44 ++++++++++++++++ .../RidAssetResolution.cs | 50 +++++++++++++------ src/tests/Common/helixpublishwitharcade.proj | 15 ------ 17 files changed, 147 insertions(+), 50 deletions(-) create mode 100644 eng/pipelines/coreclr/templates/run-paltests-step.yml create mode 100644 src/coreclr/scripts/paltests.proj diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index 0d2ceac932d721..6491bb536856cc 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -265,8 +265,8 @@ jobs: PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/' PublishLocation: Container ${{ if notin(parameters.osGroup, 'browser', 'wasi') }}: - ArtifactName: Logs_Build_${{ parameters.osGroup }}_${{ parameters.osSubGroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}_${{ parameters.nameSuffix }} + ArtifactName: Logs_Build_Attempt$(System.JobAttempt)_${{ parameters.osGroup }}_${{ parameters.osSubGroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}_${{ parameters.nameSuffix }} ${{ if in(parameters.osGroup, 'browser', 'wasi') }}: - ArtifactName: Logs_Build_${{ parameters.osGroup }}_${{ parameters.archType }}_${{ parameters.hostedOs }}_${{ parameters.buildConfig }}_${{ parameters.nameSuffix }} + ArtifactName: Logs_Build_Attempt$(System.JobAttempt)_${{ parameters.osGroup }}_${{ parameters.archType }}_${{ parameters.hostedOs }}_${{ parameters.buildConfig }}_${{ parameters.nameSuffix }} continueOnError: true condition: always() diff --git a/eng/pipelines/common/templates/runtimes/build-test-job.yml b/eng/pipelines/common/templates/runtimes/build-test-job.yml index 2b9871f183f766..8def518f8c7409 100644 --- a/eng/pipelines/common/templates/runtimes/build-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/build-test-job.yml @@ -149,6 +149,6 @@ jobs: displayName: Publish Logs inputs: targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: '${{ parameters.runtimeFlavor }}_Common_Runtime_TestBuildLogs_AnyOS_AnyCPU_$(buildConfig)_${{ parameters.testGroup }}' + artifactName: '${{ parameters.runtimeFlavor }}_Common_Runtime_TestBuildLogs_Attempt$(System.JobAttempt)_AnyOS_AnyCPU_$(buildConfig)_${{ parameters.testGroup }}' continueOnError: true condition: always() diff --git a/eng/pipelines/common/templates/runtimes/run-test-job.yml b/eng/pipelines/common/templates/runtimes/run-test-job.yml index a137b7c796e6b2..759011b02e3d10 100644 --- a/eng/pipelines/common/templates/runtimes/run-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/run-test-job.yml @@ -341,11 +341,7 @@ jobs: timeoutPerTestInMinutes: $(timeoutPerTestInMinutes) timeoutPerTestCollectionInMinutes: $(timeoutPerTestCollectionInMinutes) - runCrossGen2: ${{ eq(parameters.readyToRun, true) }} - ${{ if and(ne(parameters.testGroup, 'innerloop'), eq(parameters.runtimeFlavor, 'coreclr')) }}: - runPALTestsDir: '$(coreClrProductRootFolderPath)/paltests' - compositeBuildMode: ${{ parameters.compositeBuildMode }} runInUnloadableContext: ${{ parameters.runInUnloadableContext }} tieringTest: ${{ parameters.tieringTest }} @@ -603,7 +599,7 @@ jobs: displayName: Publish Logs inputs: targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: '${{ parameters.runtimeFlavor }}_${{ parameters.runtimeVariant }}_$(LogNamePrefix)_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)_${{ parameters.testGroup }}' + artifactName: '${{ parameters.runtimeFlavor }}_${{ parameters.runtimeVariant }}_$(LogNamePrefix)_Attempt$(System.JobAttempt)_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)_${{ parameters.testGroup }}' continueOnError: true condition: always() diff --git a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml index 97d565b3a4e391..4be1378ab3c455 100644 --- a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml +++ b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml @@ -17,7 +17,6 @@ parameters: timeoutPerTestCollectionInMinutes: '' timeoutPerTestInMinutes: '' runCrossGen2: '' - runPALTestsDir: '' compositeBuildMode: false helixProjectArguments: '' runInUnloadableContext: '' @@ -58,7 +57,6 @@ steps: _LongRunningGcTests: ${{ parameters.longRunningGcTests }} _GcSimulatorTests: ${{ parameters.gcSimulatorTests }} _Scenarios: ${{ join(',', parameters.scenarios) }} - _PALTestsDir: ${{ parameters.runPALTestsDir }} _TimeoutPerTestCollectionInMinutes: ${{ parameters.timeoutPerTestCollectionInMinutes }} _TimeoutPerTestInMinutes: ${{ parameters.timeoutPerTestInMinutes }} RuntimeFlavor: ${{ parameters.runtimeFlavor }} diff --git a/eng/pipelines/coreclr/ci.yml b/eng/pipelines/coreclr/ci.yml index adf052b014f455..17806e944070c2 100644 --- a/eng/pipelines/coreclr/ci.yml +++ b/eng/pipelines/coreclr/ci.yml @@ -155,3 +155,23 @@ extends: readyToRun: true displayNameArgs: R2R_CG2 liveLibrariesBuildConfig: Release + + # + # PAL Tests + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: Debug + platforms: + - linux_x64 + - linux_musl_x64 + - linux_arm64 + - linux_musl_arm64 + - osx_x64 + - osx_arm64 + jobParameters: + buildArgs: -s clr.paltests+clr.paltestlist + nameSuffix: PALTests + extraStepsTemplate: /eng/pipelines/coreclr/templates/run-paltests-step.yml diff --git a/eng/pipelines/coreclr/templates/build-jit-job.yml b/eng/pipelines/coreclr/templates/build-jit-job.yml index 5566f228b2f0e8..2f78d87bf81633 100644 --- a/eng/pipelines/coreclr/templates/build-jit-job.yml +++ b/eng/pipelines/coreclr/templates/build-jit-job.yml @@ -132,6 +132,6 @@ jobs: displayName: Publish Logs inputs: targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: '$(publishLogsArtifactPrefix)_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + artifactName: '$(publishLogsArtifactPrefix)_Attempt$(System.JobAttempt)_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' continueOnError: true condition: always() diff --git a/eng/pipelines/coreclr/templates/build-job.yml b/eng/pipelines/coreclr/templates/build-job.yml index 01d12e6452b4cf..ed8945f6975790 100644 --- a/eng/pipelines/coreclr/templates/build-job.yml +++ b/eng/pipelines/coreclr/templates/build-job.yml @@ -94,7 +94,7 @@ jobs: value: '' - ${{ if ne(parameters.testGroup, 'innerloop') }}: - name: clrRuntimeComponentsBuildArg - value: '-component runtime -component alljits -component paltests -component nativeaot -component spmi ' + value: '-component runtime -component alljits -component nativeaot -component spmi ' - name: pgoInstrumentArg value: '' @@ -192,7 +192,7 @@ jobs: displayName: Disk Usage after Build # Build CoreCLR Managed Components - - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.corelib+clr.nativecorelib+clr.nativeaotlibs+clr.tools+clr.packages+clr.paltestlist $(crossArg) $(compilerArg) -arch $(archType) $(osArg) -c $(buildConfig) $(pgoInstrumentArg) $(officialBuildIdArg) -ci + - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.corelib+clr.nativecorelib+clr.nativeaotlibs+clr.tools+clr.packages $(crossArg) $(compilerArg) -arch $(archType) $(osArg) -c $(buildConfig) $(pgoInstrumentArg) $(officialBuildIdArg) -ci displayName: Build managed product components and packages # Build native test components @@ -292,6 +292,6 @@ jobs: displayName: Publish Logs inputs: targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: '$(publishLogsArtifactPrefix)${{ parameters.pgoType }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + artifactName: '$(publishLogsArtifactPrefix)_Attempt$(System.JobAttempt)_${{ parameters.pgoType }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' continueOnError: true condition: always() diff --git a/eng/pipelines/coreclr/templates/crossdac-pack.yml b/eng/pipelines/coreclr/templates/crossdac-pack.yml index 7489ceeedad056..520eb65fb337e6 100644 --- a/eng/pipelines/coreclr/templates/crossdac-pack.yml +++ b/eng/pipelines/coreclr/templates/crossdac-pack.yml @@ -70,6 +70,6 @@ jobs: displayName: Publish Logs inputs: targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: 'CrossDacPackagingLogs' + artifactName: 'CrossDacPackagingLogs_Attempt$(System.JobAttempt)' continueOnError: true condition: always() diff --git a/eng/pipelines/coreclr/templates/run-paltests-step.yml b/eng/pipelines/coreclr/templates/run-paltests-step.yml new file mode 100644 index 00000000000000..3b3881986f7d15 --- /dev/null +++ b/eng/pipelines/coreclr/templates/run-paltests-step.yml @@ -0,0 +1,23 @@ +parameters: + continueOnError: 'false' # optional -- determines whether to continue the build if the step errors + helixQueues: '' # required -- Helix queues + buildConfig: '' # required -- build configuration + archType: '' # required -- targeting CPU architecture + osGroup: '' # required -- operating system for the job + osSubgroup: '' # optional -- operating system subgroup + dependOnEvaluatePaths: false + +steps: + - template: /eng/pipelines/common/templates/runtimes/send-to-helix-step.yml + parameters: + displayName: 'Send job to Helix' + helixBuild: $(Build.BuildNumber) + helixSource: $(_HelixSource) + helixType: 'build/tests/' + helixQueues: ${{ parameters.helixQueues }} + creator: dotnet-bot + helixProjectArguments: '$(Build.SourcesDirectory)/src/coreclr/scripts/paltests.proj' + BuildConfig: ${{ parameters.buildConfig }} + osGroup: ${{ parameters.osGroup }} + archType: ${{ parameters.archType }} + shouldContinueOnError: ${{ parameters.continueOnError }} diff --git a/eng/pipelines/installer/jobs/build-job.yml b/eng/pipelines/installer/jobs/build-job.yml index 3e18fb3d96392a..f10fc47a50694d 100644 --- a/eng/pipelines/installer/jobs/build-job.yml +++ b/eng/pipelines/installer/jobs/build-job.yml @@ -86,18 +86,26 @@ jobs: - name: OfficialBuildArg value: '' + # Explicitly enable tests for linux even though it is a cross build using mariner + # They still work in this configuration and until they run on Helix, it is our only + # linux test coverage in the installer pipeline - name: SkipTests value: ${{ or( not(in(parameters.archType, 'x64', 'x86')), eq(parameters.runtimeFlavor, 'mono'), eq(parameters.isOfficialBuild, true), - eq(parameters.crossBuild, true), + and( + eq(parameters.crossBuild, true), + not(and( + eq(parameters.osGroup, 'linux'), + eq(parameters.osSubgroup, '')) + )), eq(parameters.pgoType, 'PGO')) }} - name: BuildAction value: -test - - ${{ if eq(or(not(in(parameters.archType, 'x64', 'x86')), eq(parameters.runtimeFlavor, 'mono'), eq(parameters.isOfficialBuild, true), eq(parameters.crossBuild, true), eq(parameters.pgoType, 'PGO')), true) }}: + - ${{ if eq(or(not(in(parameters.archType, 'x64', 'x86')), eq(parameters.runtimeFlavor, 'mono'), eq(parameters.isOfficialBuild, true), and(eq(parameters.crossBuild, true), not(and(eq(parameters.osGroup, 'linux'), eq(parameters.osSubgroup, '')))), eq(parameters.pgoType, 'PGO')), true) }}: - name: BuildAction value: '' @@ -405,6 +413,7 @@ jobs: runtimeVariant: ${{ parameters.runtimeVariant }} isOfficialBuild: ${{ eq(parameters.isOfficialBuild, true) }} pgoType: ${{ parameters.pgoType }} + skipTests: ${{ eq(variables.SkipTests, true) }} - ${{ if ne(parameters.osGroup, 'windows') }}: - script: set -x && df -h diff --git a/eng/pipelines/installer/jobs/steps/upload-job-artifacts.yml b/eng/pipelines/installer/jobs/steps/upload-job-artifacts.yml index 6029ba00571977..b3fd5328bc41a9 100644 --- a/eng/pipelines/installer/jobs/steps/upload-job-artifacts.yml +++ b/eng/pipelines/installer/jobs/steps/upload-job-artifacts.yml @@ -71,6 +71,6 @@ steps: displayName: Publish BuildLogs inputs: targetPath: '$(Build.StagingDirectory)/BuildLogs' - artifactName: Installer-Logs-${{parameters.pgoType }}${{ parameters.runtimeFlavor }}-${{ parameters.runtimeVariant }}-${{ parameters.name }}-$(_BuildConfig) + artifactName: Installer-Logs_Attempt$(System.JobAttempt)-${{parameters.pgoType }}${{ parameters.runtimeFlavor }}-${{ parameters.runtimeVariant }}-${{ parameters.name }}-$(_BuildConfig) continueOnError: true condition: always() diff --git a/eng/pipelines/mono/templates/build-job.yml b/eng/pipelines/mono/templates/build-job.yml index 0c823e8d573710..aa9662183301a5 100644 --- a/eng/pipelines/mono/templates/build-job.yml +++ b/eng/pipelines/mono/templates/build-job.yml @@ -180,6 +180,6 @@ jobs: displayName: Publish Logs inputs: targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: 'BuildLogs_Mono_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + artifactName: 'BuildLogs_Attempt$(System.JobAttempt)_Mono_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' continueOnError: true condition: always() diff --git a/eng/pipelines/mono/templates/generate-offsets.yml b/eng/pipelines/mono/templates/generate-offsets.yml index ddc67f0cc0b7b8..c68adfe67a9e6b 100644 --- a/eng/pipelines/mono/templates/generate-offsets.yml +++ b/eng/pipelines/mono/templates/generate-offsets.yml @@ -87,6 +87,6 @@ jobs: displayName: Publish Logs inputs: targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: 'BuildLogs_Mono_Offsets_$(osGroup)$(osSubGroup)' + artifactName: 'BuildLogs_Attempt$(System.JobAttempt)_Mono_Offsets_$(osGroup)$(osSubGroup)' continueOnError: true condition: always() diff --git a/eng/pipelines/mono/templates/workloads-build.yml b/eng/pipelines/mono/templates/workloads-build.yml index b962dcb65d178a..4a50ed665e24ee 100644 --- a/eng/pipelines/mono/templates/workloads-build.yml +++ b/eng/pipelines/mono/templates/workloads-build.yml @@ -96,7 +96,7 @@ jobs: displayName: Publish Logs inputs: targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: 'WorkloadLogs' + artifactName: 'WorkloadLogs_Attempt$(System.JobAttempt)' continueOnError: true condition: always() diff --git a/src/coreclr/scripts/paltests.proj b/src/coreclr/scripts/paltests.proj new file mode 100644 index 00000000000000..167208f4ecb087 --- /dev/null +++ b/src/coreclr/scripts/paltests.proj @@ -0,0 +1,44 @@ + + + true + $(_Creator) + $(_HelixAccessToken) + $(_HelixBuild) + $(_HelixSource) + $(_HelixTargetQueues) + $(_HelixType) + + + + + + + + + + + + + + + + + @(PalTestArchive) + ./runpaltestshelix.sh + 0:10 + + + + diff --git a/src/installer/tests/HostActivation.Tests/DependencyResolution/RidAssetResolution.cs b/src/installer/tests/HostActivation.Tests/DependencyResolution/RidAssetResolution.cs index cb924267ca2548..afbf30a0ba4fa1 100644 --- a/src/installer/tests/HostActivation.Tests/DependencyResolution/RidAssetResolution.cs +++ b/src/installer/tests/HostActivation.Tests/DependencyResolution/RidAssetResolution.cs @@ -29,7 +29,23 @@ public class TestSetup // Expected behaviour of the test based on above settings public bool ShouldUseRidGraph => UseRidGraph == true; - public bool ShouldUseFallbackRid => ShouldUseRidGraph && (Rid == UnknownRid || !HasRidGraph); + + public bool? ShouldUseFallbackRid + { + get + { + if (!ShouldUseRidGraph) + return false; + + if (Rid == UnknownRid || !HasRidGraph) + return true; + + // We use the product RID graph for testing (for cases with a RID graph). If the test is running + // on a platform that isn't in that RID graph, we may end up with the fallback even when the RID + // graph is used and RID is not unknown. Value of null indicates this state. + return null; + } + } public override string ToString() => $""" {nameof(Rid)}: {(Rid ?? "")} @@ -623,18 +639,20 @@ protected override void RunTest( UpdateAppConfigForTest(app, setup, copyOnUpdate: false); - dotnet.Exec(app.AppDll) + var result = dotnet.Exec(app.AppDll) .EnableTracingAndCaptureOutputs() .RuntimeId(setup.Rid) - .Execute() - .Should().Pass() + .Execute(); + result.Should().Pass() .And.HaveResolvedAssembly(expected.IncludedAssemblyPaths, app) .And.NotHaveResolvedAssembly(expected.ExcludedAssemblyPaths, app) .And.HaveResolvedNativeLibraryPath(expected.IncludedNativeLibraryPaths, app) .And.NotHaveResolvedNativeLibraryPath(expected.ExcludedNativeLibraryPaths, app) .And.HaveReadRidGraph(setup.ShouldUseRidGraph) - .And.HaveUsedFallbackRid(setup.ShouldUseFallbackRid) .And.HaveUsedFrameworkProbe(dotnet.GreatestVersionSharedFxPath, level: 1); + + if (setup.ShouldUseFallbackRid.HasValue) + result.Should().HaveUsedFallbackRid(setup.ShouldUseFallbackRid.Value); } } } @@ -674,17 +692,19 @@ protected override void RunTest( TestApp app = UpdateAppConfigForTest(SharedState.FrameworkReferenceApp, setup, copyOnUpdate: true); - SharedState.RunComponentResolutionTest(component.AppDll, app, dotnet.GreatestVersionHostFxrPath, command => command - .RuntimeId(setup.Rid)) - .Should().Pass() + var result = SharedState.RunComponentResolutionTest(component.AppDll, app, dotnet.GreatestVersionHostFxrPath, command => command + .RuntimeId(setup.Rid)); + result.Should().Pass() .And.HaveSuccessfullyResolvedComponentDependencies() .And.HaveResolvedComponentDependencyAssembly(expected.IncludedAssemblyPaths, component) .And.NotHaveResolvedComponentDependencyAssembly(expected.ExcludedAssemblyPaths, component) .And.HaveResolvedComponentDependencyNativeLibraryPath(expected.IncludedNativeLibraryPaths, component) .And.NotHaveResolvedComponentDependencyNativeLibraryPath(expected.ExcludedNativeLibraryPaths, component) .And.HaveReadRidGraph(setup.ShouldUseRidGraph) - .And.HaveUsedFallbackRid(setup.ShouldUseFallbackRid) .And.NotHaveUsedFrameworkProbe(dotnet.GreatestVersionSharedFxPath); + + if (setup.ShouldUseFallbackRid.HasValue) + result.Should().HaveUsedFallbackRid(setup.ShouldUseFallbackRid.Value); } } @@ -723,16 +743,18 @@ protected override void RunTest( app = UpdateAppConfigForTest(app, setup, copyOnUpdate: true); - SharedState.RunComponentResolutionTest(component.AppDll, app, app.Location, command => command - .RuntimeId(setup.Rid)) - .Should().Pass() + var result = SharedState.RunComponentResolutionTest(component.AppDll, app, app.Location, command => command + .RuntimeId(setup.Rid)); + result.Should().Pass() .And.HaveSuccessfullyResolvedComponentDependencies() .And.HaveResolvedComponentDependencyAssembly(expected.IncludedAssemblyPaths, component) .And.NotHaveResolvedComponentDependencyAssembly(expected.ExcludedAssemblyPaths, component) .And.HaveResolvedComponentDependencyNativeLibraryPath(expected.IncludedNativeLibraryPaths, component) .And.NotHaveResolvedComponentDependencyNativeLibraryPath(expected.ExcludedNativeLibraryPaths, component) - .And.HaveReadRidGraph(setup.ShouldUseRidGraph) - .And.HaveUsedFallbackRid(setup.ShouldUseFallbackRid); + .And.HaveReadRidGraph(setup.ShouldUseRidGraph); + + if (setup.ShouldUseFallbackRid.HasValue) + result.Should().HaveUsedFallbackRid(setup.ShouldUseFallbackRid.Value); } public class ComponentSharedTestState : ComponentSharedTestStateBase diff --git a/src/tests/Common/helixpublishwitharcade.proj b/src/tests/Common/helixpublishwitharcade.proj index db4ce658d6c767..a439693adf2136 100644 --- a/src/tests/Common/helixpublishwitharcade.proj +++ b/src/tests/Common/helixpublishwitharcade.proj @@ -46,7 +46,6 @@ <_RuntimeVariant> BundledNETCoreAppPackageVersion - <_PALTestsDir> <_SuperPmiCollect>false @@ -105,7 +104,6 @@ RuntimeVariant=$(_RuntimeVariant); BundledNETCoreAppPackageVersion=$(BundledNETCoreAppPackageVersion); HelixRuntimeRid=$(HelixRuntimeRid); - PALTestsDir=$(_PALTestsDir); SuperPmiCollect=$(_SuperPmiCollect) @@ -132,7 +130,6 @@ - <_Scenarios Include="$(_Scenarios.Split(','))" /> @@ -324,12 +321,6 @@ - - - - @@ -929,12 +920,6 @@ $(AppleTestTarget) $([System.TimeSpan]::FromMinutes($(TimeoutPerTestCollectionInMinutes))) - - - $(LegacyPayloadsRootDirectory)paltests.tar.gz - $(_WorkaroundForNuGetMigrationsForPrepending) ./runpaltestshelix.sh - $([System.TimeSpan]::FromMinutes($(TimeoutPerTestCollectionInMinutes))) - From 6eced1c4810a53e6c50e660298f31189bce2e3d0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 14:58:14 -0700 Subject: [PATCH 712/783] Update dependencies from https://github.com/dotnet/hotreload-utils build 20240429.2 (#101688) Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.24210.1 -> To Version 8.0.0-alpha.0.24229.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 04d355fd7b9408..be70162daab100 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -354,9 +354,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 67613417f5e1af250e6ddfba79f8f2885d8e90fb - + https://github.com/dotnet/hotreload-utils - 85d6e21ac1d4e0977dfd1321131be0c912d70d80 + 61f137aacabdbd8f279415287a2dd70e150f5eb1 https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index 3bf003d4987e7e..34850e6ce95c5d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -186,7 +186,7 @@ 8.0.0-prerelease.24208.4 8.0.0-prerelease.24208.4 8.0.0-prerelease.24208.4 - 8.0.0-alpha.0.24210.1 + 8.0.0-alpha.0.24229.2 2.4.2 1.0.0 2.4.5 From 8ff4dd429a6d099ded84aebcf660649233e167fe Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Tue, 30 Apr 2024 10:57:23 +0200 Subject: [PATCH 713/783] Extend mono_gsharedvt_constrained_call for static calls and handle nullable value types (#101491) This PR extends mono_gsharedvt_constrained_call to handle static MONO_GSHAREDVT_CONSTRAINT_CALL_TYPE_REF calls. If the cmethod is a static method, this_arg should be NULL. Also, it skips dereferencing sharedvt ref arguments if they are nullable value types. --- src/mono/mono/mini/jit-icalls.c | 3 +- src/mono/mono/mini/method-to-ir.c | 7 +-- .../JitBlue/Runtime_94467/Runtime_94467.cs | 44 +++++++++++++++++++ .../Runtime_94467/Runtime_94467.csproj | 8 ++++ 4 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.csproj diff --git a/src/mono/mono/mini/jit-icalls.c b/src/mono/mono/mini/jit-icalls.c index 24ec1b65dcf566..be43a91fdba755 100644 --- a/src/mono/mono/mini/jit-icalls.c +++ b/src/mono/mono/mini/jit-icalls.c @@ -1450,7 +1450,8 @@ mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *kl break; case MONO_GSHAREDVT_CONSTRAINT_CALL_TYPE_REF: /* Calling a ref method with a ref receiver */ - this_arg = *(gpointer*)mp; + /* Static calls don't have this arg */ + this_arg = m_method_is_static (cmethod) ? NULL : *(gpointer*)mp; m = info->method; break; default: diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index eb0ab5f4e296c9..2dbb57653f3020 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -3884,13 +3884,8 @@ handle_constrained_gsharedvt_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMe int addr_reg; if (mini_is_gsharedvt_type (fsig->params [i])) { - MonoInst *is_deref; - int deref_arg_reg; ins = mini_emit_get_gsharedvt_info_klass (cfg, mono_class_from_mono_type_internal (fsig->params [i]), MONO_RGCTX_INFO_CLASS_BOX_TYPE); - deref_arg_reg = alloc_preg (cfg); - /* deref_arg = BOX_TYPE != MONO_GSHAREDVT_BOX_TYPE_VTYPE */ - EMIT_NEW_BIALU_IMM (cfg, is_deref, OP_ISUB_IMM, deref_arg_reg, ins->dreg, 1); - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, is_gsharedvt_ins->dreg, i, is_deref->dreg); + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, is_gsharedvt_ins->dreg, i, ins->dreg); } else if (has_gsharedvt) { MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI1_MEMBASE_IMM, is_gsharedvt_ins->dreg, i, 0); } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.cs b/src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.cs new file mode 100644 index 00000000000000..85aa6e62655d2f --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Xunit; + +public static class Runtime_94467 +{ + public interface ITypeChecker + { + static abstract bool Test(T value); + } + + public interface IHandler + { + bool Test(T value); + } + + public struct TypeChecker : ITypeChecker + { + public static bool Test(T value) => true; + } + + public class Handler : IHandler where TChecker : ITypeChecker + { + public bool Test(T value) => TChecker.Test(value); + } + + public static IHandler GetHandler() => new Handler(); + + [Fact] + public static int Test() + { + try { + var handler = GetHandler(); + if (handler.Test(true) && handler.Test(true)) + return 100; + else + return 101; + } catch (Exception) { + return -1; + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From 190798472c7741b4487243c837cf6d76e935ded1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 08:35:52 -0700 Subject: [PATCH 714/783] [release/8.0-staging] Revert "FileConfigurationProvider.Dispose should dispose FileProvider when it owns it" (#101610) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revert "FileConfigurationProvider.Dispose should dispose FileProvider when it…" This reverts commit 63fad3c36fdf36e31ab0dd4c7e32732750390c4a. * Add test to ensure the bug does not come back * Enable servicing Microsoft.Extensions.Configuration.FileExtensions * Update Microsoft.Extensions.Configuration.FileExtensions.csproj --------- Co-authored-by: Adam Sitnik Co-authored-by: Eric StJohn --- .../src/FileConfigurationExtensions.cs | 10 +-- .../src/FileConfigurationProvider.cs | 5 -- .../src/FileConfigurationSource.cs | 11 ---- ...nsions.Configuration.FileExtensions.csproj | 2 + .../tests/JsonConfigurationTest.cs | 48 +++------------ .../tests/XmlConfigurationTest.cs | 61 ------------------- 6 files changed, 17 insertions(+), 120 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationExtensions.cs index 77ac387d096077..f84c5c10eea771 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationExtensions.cs @@ -29,9 +29,6 @@ public static IConfigurationBuilder SetFileProvider(this IConfigurationBuilder b return builder; } - internal static IFileProvider? GetUserDefinedFileProvider(this IConfigurationBuilder builder) - => builder.Properties.TryGetValue(FileProviderKey, out object? provider) ? (IFileProvider)provider : null; - /// /// Gets the default to be used for file-based providers. /// @@ -41,7 +38,12 @@ public static IFileProvider GetFileProvider(this IConfigurationBuilder builder) { ThrowHelper.ThrowIfNull(builder); - return GetUserDefinedFileProvider(builder) ?? new PhysicalFileProvider(AppContext.BaseDirectory ?? string.Empty); + if (builder.Properties.TryGetValue(FileProviderKey, out object? provider)) + { + return (IFileProvider)provider; + } + + return new PhysicalFileProvider(AppContext.BaseDirectory ?? string.Empty); } /// diff --git a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationProvider.cs b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationProvider.cs index c0d8c9f341278a..d226051b1ab838 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationProvider.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationProvider.cs @@ -162,11 +162,6 @@ private void HandleException(ExceptionDispatchInfo info) protected virtual void Dispose(bool disposing) { _changeTokenRegistration?.Dispose(); - - if (Source.OwnsFileProvider) - { - (Source.FileProvider as IDisposable)?.Dispose(); - } } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationSource.cs b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationSource.cs index 60555b2c672558..d58c265f406a9a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationSource.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationSource.cs @@ -18,11 +18,6 @@ public abstract class FileConfigurationSource : IConfigurationSource /// public IFileProvider? FileProvider { get; set; } - /// - /// Set to true when was not provided by user and can be safely disposed. - /// - internal bool OwnsFileProvider { get; private set; } - /// /// The path to the file. /// @@ -63,11 +58,6 @@ public abstract class FileConfigurationSource : IConfigurationSource /// The . public void EnsureDefaults(IConfigurationBuilder builder) { - if (FileProvider is null && builder.GetUserDefinedFileProvider() is null) - { - OwnsFileProvider = true; - } - FileProvider ??= builder.GetFileProvider(); OnLoadException ??= builder.GetFileLoadExceptionHandler(); } @@ -91,7 +81,6 @@ public void ResolveFileProvider() } if (Directory.Exists(directory)) { - OwnsFileProvider = true; FileProvider = new PhysicalFileProvider(directory); Path = pathToFile; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/Microsoft.Extensions.Configuration.FileExtensions.csproj b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/Microsoft.Extensions.Configuration.FileExtensions.csproj index 124b99b6338bc5..1a60e9897515aa 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/Microsoft.Extensions.Configuration.FileExtensions.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/Microsoft.Extensions.Configuration.FileExtensions.csproj @@ -4,6 +4,8 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true true + true + 1 Provides a base class for file-based configuration providers used with Microsoft.Extensions.Configuration and extension methods for configuring them. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Json/tests/JsonConfigurationTest.cs b/src/libraries/Microsoft.Extensions.Configuration.Json/tests/JsonConfigurationTest.cs index 4b08c918fb8981..08d59e30ea6ebc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Json/tests/JsonConfigurationTest.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Json/tests/JsonConfigurationTest.cs @@ -222,56 +222,26 @@ public void ThrowFormatExceptionWhenFileIsEmpty() Assert.Contains("Could not parse the JSON file.", exception.Message); } - [Theory] - [InlineData(true)] - [InlineData(false)] - public void AddJsonFile_FileProvider_Gets_Disposed_When_It_Was_Not_Created_By_The_User(bool disposeConfigRoot) + [Fact] + public void AddJsonFile_FileProvider_Is_Not_Disposed_When_SourcesGetReloaded() { - string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddJsonFile_FileProvider_Gets_Disposed_When_It_Was_Not_Created_By_The_User)}.json"); + string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddJsonFile_FileProvider_Is_Not_Disposed_When_SourcesGetReloaded)}.json"); File.WriteAllText(filePath, @"{ ""some"": ""value"" }"); - IConfigurationRoot config = new ConfigurationBuilder().AddJsonFile(filePath, optional: false).Build(); - JsonConfigurationProvider jsonConfigurationProvider = config.Providers.OfType().Single(); - - Assert.NotNull(jsonConfigurationProvider.Source.FileProvider); - PhysicalFileProvider fileProvider = (PhysicalFileProvider)jsonConfigurationProvider.Source.FileProvider; - Assert.False(GetIsDisposed(fileProvider)); - - if (disposeConfigRoot) - { - (config as IDisposable).Dispose(); // disposing ConfigurationRoot - } - else - { - jsonConfigurationProvider.Dispose(); // disposing JsonConfigurationProvider - } - - Assert.True(GetIsDisposed(fileProvider)); - } + IConfigurationBuilder builder = new ConfigurationManager(); - [Fact] - public void AddJsonFile_FileProvider_Is_Not_Disposed_When_It_Is_Owned_By_The_User() - { - string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddJsonFile_FileProvider_Is_Not_Disposed_When_It_Is_Owned_By_The_User)}.json"); - File.WriteAllText(filePath, @"{ ""some"": ""value"" }"); + builder.AddJsonFile(filePath, optional: false); - PhysicalFileProvider fileProvider = new(Path.GetDirectoryName(filePath)); - JsonConfigurationProvider configurationProvider = new(new JsonConfigurationSource() - { - Path = filePath, - FileProvider = fileProvider - }); - IConfigurationRoot config = new ConfigurationBuilder().AddJsonFile(configurationProvider.Source.FileProvider, filePath, optional: true, reloadOnChange: false).Build(); + FileConfigurationSource fileConfigurationSource = (FileConfigurationSource)builder.Sources.Last(); + PhysicalFileProvider fileProvider = (PhysicalFileProvider)fileConfigurationSource.FileProvider; Assert.False(GetIsDisposed(fileProvider)); - (config as IDisposable).Dispose(); // disposing ConfigurationRoot that does not own the provider - Assert.False(GetIsDisposed(fileProvider)); + builder.Properties.Add("simplest", "repro"); - configurationProvider.Dispose(); // disposing JsonConfigurationProvider that does not own the provider Assert.False(GetIsDisposed(fileProvider)); - fileProvider.Dispose(); // disposing PhysicalFileProvider itself + fileProvider.Dispose(); Assert.True(GetIsDisposed(fileProvider)); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/XmlConfigurationTest.cs b/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/XmlConfigurationTest.cs index d248d96d9d464f..4012d775afa5f2 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/XmlConfigurationTest.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/XmlConfigurationTest.cs @@ -3,13 +3,11 @@ using System; using System.IO; -using System.Linq; using System.Security.Cryptography; using System.Security.Cryptography.Xml; using System.Tests; using System.Xml; using Microsoft.Extensions.Configuration.Test; -using Microsoft.Extensions.FileProviders; using Xunit; namespace Microsoft.Extensions.Configuration.Xml.Test @@ -781,64 +779,5 @@ public void LoadKeyValuePairsFromValidEncryptedXml() Assert.Equal("AnotherTestConnectionString", xmlConfigSrc.Get("data.setting:inventory:connectionstring")); Assert.Equal("MySql", xmlConfigSrc.Get("Data.setting:Inventory:Provider")); } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void AddXmlFile_FileProvider_Gets_Disposed_When_It_Was_Not_Created_By_The_User(bool disposeConfigRoot) - { - string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddXmlFile_FileProvider_Gets_Disposed_When_It_Was_Not_Created_By_The_User)}.xml"); - File.WriteAllText(filePath, @"Settings"); - - IConfigurationRoot config = new ConfigurationBuilder().AddXmlFile(filePath, optional: false).Build(); - XmlConfigurationProvider xmlConfigurationProvider = config.Providers.OfType().Single(); - - Assert.NotNull(xmlConfigurationProvider.Source.FileProvider); - PhysicalFileProvider fileProvider = (PhysicalFileProvider)xmlConfigurationProvider.Source.FileProvider; - Assert.False(GetIsDisposed(fileProvider)); - - if (disposeConfigRoot) - { - (config as IDisposable).Dispose(); // disposing ConfigurationRoot - } - else - { - xmlConfigurationProvider.Dispose(); // disposing XmlConfigurationProvider - } - - Assert.True(GetIsDisposed(fileProvider)); - } - - [Fact] - public void AddXmlFile_FileProvider_Is_Not_Disposed_When_It_Is_Owned_By_The_User() - { - string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddXmlFile_FileProvider_Is_Not_Disposed_When_It_Is_Owned_By_The_User)}.xml"); - File.WriteAllText(filePath, @"Settings"); - - PhysicalFileProvider fileProvider = new(Path.GetDirectoryName(filePath)); - XmlConfigurationProvider configurationProvider = new(new XmlConfigurationSource() - { - Path = filePath, - FileProvider = fileProvider - }); - IConfigurationRoot config = new ConfigurationBuilder().AddXmlFile(configurationProvider.Source.FileProvider, filePath, optional: true, reloadOnChange: false).Build(); - - Assert.False(GetIsDisposed(fileProvider)); - - (config as IDisposable).Dispose(); // disposing ConfigurationRoot that does not own the provider - Assert.False(GetIsDisposed(fileProvider)); - - configurationProvider.Dispose(); // disposing XmlConfigurationProvider - Assert.False(GetIsDisposed(fileProvider)); - - fileProvider.Dispose(); // disposing PhysicalFileProvider itself - Assert.True(GetIsDisposed(fileProvider)); - } - - private static bool GetIsDisposed(PhysicalFileProvider fileProvider) - { - System.Reflection.FieldInfo isDisposedField = typeof(PhysicalFileProvider).GetField("_disposed", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); - return (bool)isDisposedField.GetValue(fileProvider); - } } } From c67a2e4216e156f4129638d71ea99a6a731106ed Mon Sep 17 00:00:00 2001 From: Nikola Milosavljevic Date: Tue, 30 Apr 2024 08:55:10 -0700 Subject: [PATCH 715/783] Enable repackaging of NETStandard 2.1 Targeting Pack (#101518) * Initial changes * Enable building in 8.0.6 release --- eng/Subsets.props | 1 + eng/Versions.props | 8 +++ src/installer/pkg/sfx/installers.proj | 4 ++ .../pkg/sfx/installers/netstandard2.1.proj | 60 +++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 src/installer/pkg/sfx/installers/netstandard2.1.proj diff --git a/eng/Subsets.props b/eng/Subsets.props index eb4151f3a185d6..bf0d6ca368cb90 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -507,6 +507,7 @@ + diff --git a/eng/Versions.props b/eng/Versions.props index d53eb6c7fd68a7..e071b668317fa3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -260,4 +260,12 @@ 8.0.101 $(MicrosoftDotnetSdkInternalVersion) + + + true + diff --git a/src/installer/pkg/sfx/installers.proj b/src/installer/pkg/sfx/installers.proj index 7f4ce6b9c1c409..2f947e6d9e291e 100644 --- a/src/installer/pkg/sfx/installers.proj +++ b/src/installer/pkg/sfx/installers.proj @@ -22,6 +22,10 @@ + + + + + + true + true + netstandard-targeting-pack-2.1 + NETStandard.Library.Ref + NETStandard.Library.Ref 2.1.0 + false + ToolPack + true + netstandard-targeting-pack-2.1.0-x64.rpm + https://dotnetcli.blob.core.windows.net/dotnet/Runtime/3.1.0/$(OriginalNETStandard21PkgFilename) + $([MSBuild]::NormalizeDirectory('$(BaseIntermediateOutputPath)', 'download')) + $(NETStandard21TempDir)$(OriginalNETStandard21PkgFilename) + $(NETStandard21TempDir)netstandard21.semaphore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From ec346c0d36a8dffafffe7d6f541ec7afbfc6784b Mon Sep 17 00:00:00 2001 From: Eduardo Velarde <32459232+eduardo-vp@users.noreply.github.com> Date: Tue, 30 Apr 2024 08:58:03 -0700 Subject: [PATCH 716/783] Build the PGO build legs through the global build job template (#92296) (#101627) * Build the PGO build legs through the global build job template. * Remove pgoType parameters and plumbing from all jobs and use the -pgoinstrument flag instead of setting the property manually. * Limit subsets to build to limit packages and don't build crossgen2 sfxproj for internal optimization pipelines (we don't use it). * Fix job dependencies now that the non-global jobs don't have PGO type in the name * Change back to the triple-underscore name * Fix Mono artifacts to not have an extra underscore for PGO scenarios. * There's an extra underscore for the CoreCLR artifacts because there's no runtime variant. Co-authored-by: Jeremy Koritzinsky --- eng/Subsets.props | 2 +- eng/pipelines/common/global-build-job.yml | 3 -- .../templates/runtimes/build-test-job.yml | 1 - eng/pipelines/coreclr/templates/build-job.yml | 36 ++++++---------- .../superpmi-asmdiffs-checked-release-job.yml | 2 +- .../coreclr/templates/superpmi-diffs-job.yml | 2 +- .../coreclr/templates/xplat-pipeline-job.yml | 7 ++-- eng/pipelines/installer/jobs/build-job.yml | 29 ++++--------- .../jobs/steps/upload-job-artifacts.yml | 5 +-- eng/pipelines/libraries/base-job.yml | 3 +- eng/pipelines/mono/templates/build-job.yml | 1 - .../mono/templates/xplat-pipeline-job.yml | 8 ++-- eng/pipelines/runtime-official.yml | 41 ++++++------------- .../runtimelab-post-build-steps.yml | 3 +- 14 files changed, 48 insertions(+), 95 deletions(-) diff --git a/eng/Subsets.props b/eng/Subsets.props index bf0d6ca368cb90..00ae8a31c58cf1 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -504,7 +504,7 @@ - + diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index 6491bb536856cc..a13548956ff600 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -14,7 +14,6 @@ parameters: dependsOn: [] pool: '' platform: '' - pgoType: '' condition: true useContinueOnErrorDuringBuild: false shouldContinueOnError: false @@ -134,7 +133,6 @@ jobs: targetRid: ${{ parameters.targetRid }} nameSuffix: ${{ parameters.nameSuffix }} platform: ${{ parameters.platform }} - pgoType: ${{ parameters.pgoType }} shouldContinueOnError: ${{ parameters.shouldContinueOnError }} ${{ if ne(variableTemplate.forwardedParameters, '') }}: ${{ each parameter in variableTemplate.forwardedParameters }}: @@ -250,7 +248,6 @@ jobs: targetRid: ${{ parameters.targetRid }} nameSuffix: ${{ parameters.nameSuffix }} platform: ${{ parameters.platform }} - pgoType: ${{ parameters.pgoType }} shouldContinueOnError: ${{ parameters.shouldContinueOnError }} ${{ insert }}: ${{ parameters.extraStepsParameters }} diff --git a/eng/pipelines/common/templates/runtimes/build-test-job.yml b/eng/pipelines/common/templates/runtimes/build-test-job.yml index 8def518f8c7409..e249e8ac922a7f 100644 --- a/eng/pipelines/common/templates/runtimes/build-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/build-test-job.yml @@ -14,7 +14,6 @@ parameters: dependsOn: [] dependOnEvaluatePaths: false crossBuild: false - pgoType: '' ### Build managed test components (native components are getting built as part ### of the product build job). diff --git a/eng/pipelines/coreclr/templates/build-job.yml b/eng/pipelines/coreclr/templates/build-job.yml index ed8945f6975790..e995e626a56991 100644 --- a/eng/pipelines/coreclr/templates/build-job.yml +++ b/eng/pipelines/coreclr/templates/build-job.yml @@ -17,7 +17,6 @@ parameters: testGroup: '' timeoutInMinutes: '' variables: {} - pgoType: '' ### Product build jobs: @@ -36,21 +35,18 @@ jobs: dependOnEvaluatePaths: ${{ parameters.dependOnEvaluatePaths }} disableComponentGovernance: ${{ parameters.disableComponentGovernance }} disableClrTest: ${{ parameters.disableClrTest }} - pgoType: ${{ parameters.pgoType }} # Compute job name from template parameters - name: ${{ format('coreclr_{0}_product_build_{1}{2}_{3}_{4}{5}', + name: ${{ format('coreclr_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, - parameters.buildConfig, - parameters.pgoType) }} - displayName: ${{ format('CoreCLR {0} Product Build {1}{2} {3} {4} {5}', + parameters.buildConfig) }} + displayName: ${{ format('CoreCLR {0} Product Build {1}{2} {3} {4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, - parameters.buildConfig, - parameters.pgoType) }} + parameters.buildConfig) }} # Run all steps in the container. # Note that the containers are defined in platform-matrix.yml @@ -80,7 +76,7 @@ jobs: - name: enforcePgoArg value: '' # The EnforcePGO script is only supported on Windows and is not supported on arm64. - - ${{ if and(eq(parameters.buildConfig, 'Release'), and(eq(parameters.osGroup, 'windows'), ne(parameters.archType, 'arm64')), ne(parameters.pgoType, 'pgo')) }}: + - ${{ if and(eq(parameters.buildConfig, 'Release'), and(eq(parameters.osGroup, 'windows'), ne(parameters.archType, 'arm64'))) }}: - name: enforcePgoArg value: '-enforcepgo' @@ -96,12 +92,6 @@ jobs: - name: clrRuntimeComponentsBuildArg value: '-component runtime -component alljits -component nativeaot -component spmi ' - - name: pgoInstrumentArg - value: '' - - ${{ if eq(parameters.pgoType, 'PGO' )}}: - - name: pgoInstrumentArg - value: '-pgoinstrument ' - - name: SignType value: $[ coalesce(variables.OfficialSignType, 'real') ] @@ -175,10 +165,10 @@ jobs: # Build CoreCLR Runtime - ${{ if ne(parameters.osGroup, 'windows') }}: - - script: $(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) $(archType) $(crossArg) $(osArg) -ci $(compilerArg) $(clrRuntimeComponentsBuildArg) $(pgoInstrumentArg) $(officialBuildIdArg) $(clrInterpreterBuildArg) $(CoreClrPgoDataArg) $(nativeSymbols) + - script: $(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) $(archType) $(crossArg) $(osArg) -ci $(compilerArg) $(clrRuntimeComponentsBuildArg) $(officialBuildIdArg) $(clrInterpreterBuildArg) $(CoreClrPgoDataArg) $(nativeSymbols) displayName: Build CoreCLR Runtime - ${{ if eq(parameters.osGroup, 'windows') }}: - - script: $(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) $(archType) -ci $(enforcePgoArg) $(pgoInstrumentArg) $(officialBuildIdArg) $(clrInterpreterBuildArg) $(CoreClrPgoDataArg) + - script: $(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) $(archType) -ci $(enforcePgoArg) $(officialBuildIdArg) $(clrInterpreterBuildArg) $(CoreClrPgoDataArg) displayName: Build CoreCLR Runtime - ${{ if or(eq(parameters.crossBuild, 'true'), ne(parameters.archType, 'x64')) }}: @@ -192,7 +182,7 @@ jobs: displayName: Disk Usage after Build # Build CoreCLR Managed Components - - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.corelib+clr.nativecorelib+clr.nativeaotlibs+clr.tools+clr.packages $(crossArg) $(compilerArg) -arch $(archType) $(osArg) -c $(buildConfig) $(pgoInstrumentArg) $(officialBuildIdArg) -ci + - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.corelib+clr.nativecorelib+clr.nativeaotlibs+clr.tools+clr.packages $(crossArg) $(compilerArg) -arch $(archType) $(osArg) -c $(buildConfig) $(officialBuildIdArg) -ci displayName: Build managed product components and packages # Build native test components @@ -241,7 +231,7 @@ jobs: artifactName: $(buildProductArtifactName) displayName: 'product build' - - ${{ if and(in(parameters.osGroup, 'windows', 'linux'), ne(parameters.archType, 'x86'), eq(parameters.pgoType, '')) }}: + - ${{ if and(in(parameters.osGroup, 'windows', 'linux'), ne(parameters.archType, 'x86')) }}: - template: /eng/pipelines/coreclr/templates/crossdac-build.yml parameters: archType: ${{ parameters.archType }} @@ -253,7 +243,7 @@ jobs: ${{ else }}: hostArchType: x64 - - ${{ if and(in(parameters.osGroup, 'windows'), eq(parameters.archType, 'x86'), eq(parameters.pgoType, '')) }}: + - ${{ if and(in(parameters.osGroup, 'windows'), eq(parameters.archType, 'x86')) }}: - template: /eng/pipelines/coreclr/templates/crossdac-build.yml parameters: archType: arm @@ -264,7 +254,7 @@ jobs: - ${{ if and(ne(parameters.testGroup, ''), ne(parameters.disableClrTest, true)) }}: # Publish test native components for consumption by test execution. - - ${{ if and(ne(parameters.isOfficialBuild, true), eq(parameters.pgoType, '')) }}: + - ${{ if ne(parameters.isOfficialBuild, true) }}: - template: /eng/pipelines/common/upload-artifact-step.yml parameters: rootFolder: $(nativeTestArtifactRootFolderPath) @@ -276,7 +266,7 @@ jobs: displayName: 'native test components' # Save packages using the prepare-signed-artifacts format. - - ${{ if and(eq(parameters.isOfficialBuild, true), eq(parameters.pgoType, '')) }}: + - ${{ if eq(parameters.isOfficialBuild, true) }}: - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml parameters: name: ${{ parameters.platform }} @@ -292,6 +282,6 @@ jobs: displayName: Publish Logs inputs: targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: '$(publishLogsArtifactPrefix)_Attempt$(System.JobAttempt)_${{ parameters.pgoType }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + artifactName: '$(publishLogsArtifactPrefix)_Attempt$(System.JobAttempt)_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' continueOnError: true condition: always() diff --git a/eng/pipelines/coreclr/templates/superpmi-asmdiffs-checked-release-job.yml b/eng/pipelines/coreclr/templates/superpmi-asmdiffs-checked-release-job.yml index 396fe5077f5988..659483c9bc302b 100644 --- a/eng/pipelines/coreclr/templates/superpmi-asmdiffs-checked-release-job.yml +++ b/eng/pipelines/coreclr/templates/superpmi-asmdiffs-checked-release-job.yml @@ -34,7 +34,7 @@ jobs: - name: releaseProductRootFolderPath value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).Release' - name: releaseProductArtifactName - value: 'CoreCLRProduct_${{ parameters.pgoType }}_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_release' + value: 'CoreCLRProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_release' steps: diff --git a/eng/pipelines/coreclr/templates/superpmi-diffs-job.yml b/eng/pipelines/coreclr/templates/superpmi-diffs-job.yml index aace201eb96613..9c2290c43a3d37 100644 --- a/eng/pipelines/coreclr/templates/superpmi-diffs-job.yml +++ b/eng/pipelines/coreclr/templates/superpmi-diffs-job.yml @@ -49,7 +49,7 @@ jobs: - name: releaseProductRootFolderPath value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).Release' - name: releaseProductArtifactName - value: 'CoreCLRProduct_${{ parameters.pgoType }}_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_release' + value: 'CoreCLRProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_release' steps: diff --git a/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml b/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml index 83347d78b8b1cc..162f5e9f0ed1c8 100644 --- a/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml +++ b/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml @@ -38,7 +38,6 @@ jobs: crossBuild: ${{ parameters.crossBuild }} strategy: ${{ parameters.strategy }} pool: ${{ parameters.pool }} - pgoType: ${{ parameters.pgoType }} # arcade-specific parameters condition: and(succeeded(), ${{ parameters.condition }}) @@ -65,7 +64,7 @@ jobs: # Build product defines what we are trying to build, either coreclr or mono - name: buildProductArtifactName - value: 'CoreCLRProduct_${{ parameters.pgoType }}_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + value: 'CoreCLRProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' - name: buildProductRootFolderPath value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(buildConfigUpper)' @@ -78,13 +77,13 @@ jobs: # We need this because both mono and coreclr build currently depends on CoreClr - name: coreClrProductArtifactName - value: 'CoreCLRProduct_${{ parameters.pgoType }}_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + value: 'CoreCLRProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' - name: coreClrProductRootFolderPath value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(buildConfigUpper)' - name: corelibProductArtifactName - value: 'CoreLib_${{ parameters.pgoType }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + value: 'CoreLib_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' - name: managedGenericTestArtifactName value: 'CoreCLRManagedTestArtifacts_AnyOS_AnyCPU_$(buildConfig)' diff --git a/eng/pipelines/installer/jobs/build-job.yml b/eng/pipelines/installer/jobs/build-job.yml index f10fc47a50694d..1c45b437c8013f 100644 --- a/eng/pipelines/installer/jobs/build-job.yml +++ b/eng/pipelines/installer/jobs/build-job.yml @@ -19,7 +19,6 @@ parameters: displayName: '' runtimeVariant: '' pool: '' - pgoType: '' runOnlyIfDependenciesSucceeded: false # The target names here should match container names in the resources section in our pipelines, like runtime.yml @@ -59,11 +58,10 @@ jobs: dependOnEvaluatePaths: ${{ parameters.dependOnEvaluatePaths }} disableClrTest: ${{ parameters.disableClrTest }} - pgoType: ${{ parameters.pgoType }} # Compute job name from template parameters - name: ${{ format('installer_{0}_{1}_{2}_{3}_{4}_', parameters.pgoType, parameters.runtimeFlavor, parameters.runtimeVariant, coalesce(parameters.name, parameters.platform), parameters.buildConfig) }} - displayName: ${{ format('{0} Installer Build and Test {1} {2} {3} {4}', parameters.pgoType, parameters.runtimeFlavor, parameters.runtimeVariant, coalesce(parameters.name, parameters.platform), parameters.buildConfig) }} + name: ${{ format('installer_{0}_{1}_{2}_{3}_', parameters.runtimeFlavor, parameters.runtimeVariant, coalesce(parameters.name, parameters.platform), parameters.buildConfig) }} + displayName: ${{ format('Installer Build and Test {0} {1} {2} {3}', parameters.runtimeFlavor, parameters.runtimeVariant, coalesce(parameters.name, parameters.platform), parameters.buildConfig) }} # Run all steps in the container. # Note that the containers are defined in platform-matrix.yml @@ -99,25 +97,18 @@ jobs: not(and( eq(parameters.osGroup, 'linux'), eq(parameters.osSubgroup, '')) - )), - eq(parameters.pgoType, 'PGO')) }} + ))) }} - name: BuildAction value: -test - - ${{ if eq(or(not(in(parameters.archType, 'x64', 'x86')), eq(parameters.runtimeFlavor, 'mono'), eq(parameters.isOfficialBuild, true), and(eq(parameters.crossBuild, true), not(and(eq(parameters.osGroup, 'linux'), eq(parameters.osSubgroup, '')))), eq(parameters.pgoType, 'PGO')), true) }}: + - ${{ if eq(or(not(in(parameters.archType, 'x64', 'x86')), eq(parameters.runtimeFlavor, 'mono'), eq(parameters.isOfficialBuild, true), and(eq(parameters.crossBuild, true), not(and(eq(parameters.osGroup, 'linux'), eq(parameters.osSubgroup, ''))))), true) }}: - name: BuildAction value: '' - name: SignType value: test - - name: pgoInstrumentArg - value: '' - - ${{ if eq(parameters.pgoType, 'PGO' )}}: - - name: pgoInstrumentArg - value: '-pgoinstrument ' - # Set up non-PR build from internal project - ${{ if eq(parameters.isOfficialBuild, true) }}: - name: SignType @@ -153,7 +144,6 @@ jobs: build.cmd -subset host+packs -ci $(BuildAction) -configuration $(_BuildConfig) - $(pgoInstrumentArg) $(LiveOverridePathArgs) $(CommonMSBuildArgs) $(MsbuildSigningArguments) @@ -225,7 +215,6 @@ jobs: /p:CrossBuild=${{ parameters.crossBuild }} /p:PortableBuild=$(_PortableBuild) /p:SkipTests=$(SkipTests) - $(pgoInstrumentArg) $(LiveOverridePathArgs) $(CommonMSBuildArgs) @@ -265,7 +254,7 @@ jobs: /p:RuntimeArtifactsPath=$(buildCommandSourcesDirectory)$(RuntimeDownloadPath) /p:RuntimeConfiguration=${{ parameters.liveRuntimeBuildConfig }} - name: RuntimeArtifactName - value: $(runtimeFlavorName)Product_${{ parameters.pgoType }}_${{ parameters.runtimeVariant }}_$(liveRuntimeLegName) + value: $(runtimeFlavorName)Product_${{ parameters.runtimeVariant }}_$(liveRuntimeLegName) - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}: - name: liveLibrariesLegName @@ -286,14 +275,13 @@ jobs: - evaluate_paths - ${{ parameters.dependsOn }} - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}: - - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}{6}', + - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, - parameters.liveRuntimeBuildConfig, - parameters.pgoType) }} + parameters.liveRuntimeBuildConfig) }} - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}: - libraries_build_${{ format('{0}{1}_{2}_{3}', parameters.osGroup, @@ -391,7 +379,7 @@ jobs: displayName: Disk Usage after Build # Only in glibc leg, we produce RPMs and Debs - - ${{ if and(eq(parameters.runtimeFlavor, 'coreclr'), or(eq(parameters.platform, 'linux_x64'), eq(parameters.platform, 'linux_arm64')), eq(parameters.osSubgroup, ''), eq(parameters.pgoType, ''))}}: + - ${{ if and(eq(parameters.runtimeFlavor, 'coreclr'), or(eq(parameters.platform, 'linux_x64'), eq(parameters.platform, 'linux_arm64')), eq(parameters.osSubgroup, ''))}}: - ${{ each packageBuild in parameters.packageDistroList }}: # This leg's RID matches the build image. Build its distro-dependent packages, as well as # the distro-independent installers. (There's no particular reason to build the distro- @@ -412,7 +400,6 @@ jobs: runtimeFlavor: ${{ parameters.runtimeFlavor }} runtimeVariant: ${{ parameters.runtimeVariant }} isOfficialBuild: ${{ eq(parameters.isOfficialBuild, true) }} - pgoType: ${{ parameters.pgoType }} skipTests: ${{ eq(variables.SkipTests, true) }} - ${{ if ne(parameters.osGroup, 'windows') }}: diff --git a/eng/pipelines/installer/jobs/steps/upload-job-artifacts.yml b/eng/pipelines/installer/jobs/steps/upload-job-artifacts.yml index b3fd5328bc41a9..4012b9a4fa34cb 100644 --- a/eng/pipelines/installer/jobs/steps/upload-job-artifacts.yml +++ b/eng/pipelines/installer/jobs/steps/upload-job-artifacts.yml @@ -3,7 +3,6 @@ parameters: runtimeFlavor: 'coreclr' runtimeVariant: '' isOfficialBuild: false - pgoType: '' steps: # Upload build artifacts (packages) to pipeline only if official, to save storage space. @@ -51,7 +50,7 @@ steps: displayName: Publish binaries inputs: pathtoPublish: '$(Build.StagingDirectory)/corehost-bin-${{ parameters.name }}-$(_BuildConfig)$(archiveExtension)' - artifactName: Installer-Binaries-${{parameters.pgoType }}${{ parameters.runtimeFlavor }}-${{ parameters.runtimeVariant }}-${{ parameters.name }}-$(_BuildConfig) + artifactName: Installer-Binaries-${{ parameters.runtimeFlavor }}-${{ parameters.runtimeVariant }}-${{ parameters.name }}-$(_BuildConfig) continueOnError: true condition: failed() @@ -71,6 +70,6 @@ steps: displayName: Publish BuildLogs inputs: targetPath: '$(Build.StagingDirectory)/BuildLogs' - artifactName: Installer-Logs_Attempt$(System.JobAttempt)-${{parameters.pgoType }}${{ parameters.runtimeFlavor }}-${{ parameters.runtimeVariant }}-${{ parameters.name }}-$(_BuildConfig) + artifactName: Installer-Logs_Attempt$(System.JobAttempt)-${{ parameters.runtimeFlavor }}-${{ parameters.runtimeVariant }}-${{ parameters.name }}-$(_BuildConfig) continueOnError: true condition: always() diff --git a/eng/pipelines/libraries/base-job.yml b/eng/pipelines/libraries/base-job.yml index 2448124a7bc62d..54fe98e7d85bbf 100644 --- a/eng/pipelines/libraries/base-job.yml +++ b/eng/pipelines/libraries/base-job.yml @@ -23,7 +23,6 @@ parameters: testScope: '' pool: '' runTests: false - pgoType: '' jobs: - template: /eng/common/templates/job/job.yml @@ -98,7 +97,7 @@ jobs: - _runtimeDownloadPath: '$(Build.SourcesDirectory)/artifacts/transport/${{ parameters.runtimeFlavor }}' - _runtimeConfigurationArg: -rc ${{ parameters.liveRuntimeBuildConfig }} - ${{ if eq(parameters.runTests, true) }}: - - _runtimeArtifactName: '$(runtimeFlavorName)Product_${{ parameters.pgoType }}_${{ parameters.runtimeVariant}}_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.liveRuntimeBuildConfig }}' + - _runtimeArtifactName: '$(runtimeFlavorName)Product_${{ parameters.runtimeVariant}}_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.liveRuntimeBuildConfig }}' - _runtimeArtifactsPathArg: ' /p:RuntimeArtifactsPath=$(_runtimeDownloadPath)' - ${{ if eq(parameters.testDisplayName, '') }}: - _testRunNamePrefixSuffix: $(runtimeFlavorName)_${{ parameters.liveRuntimeBuildConfig }} diff --git a/eng/pipelines/mono/templates/build-job.yml b/eng/pipelines/mono/templates/build-job.yml index aa9662183301a5..86e0813c7c7e5c 100644 --- a/eng/pipelines/mono/templates/build-job.yml +++ b/eng/pipelines/mono/templates/build-job.yml @@ -15,7 +15,6 @@ parameters: dependsOn: [] monoCrossAOTTargetOS: [] dependOnEvaluatePaths: false - pgoType: '' ### Product build jobs: diff --git a/eng/pipelines/mono/templates/xplat-pipeline-job.yml b/eng/pipelines/mono/templates/xplat-pipeline-job.yml index 2c369f71f30bb6..1ca84d9caac1bb 100644 --- a/eng/pipelines/mono/templates/xplat-pipeline-job.yml +++ b/eng/pipelines/mono/templates/xplat-pipeline-job.yml @@ -52,22 +52,22 @@ jobs: variables: - name: coreClrProductArtifactName - value: 'CoreCLRProduct___$(osGroup)$(osSubgroup)_$(archType)_${{ parameters.liveRuntimeBuildConfig }}' + value: 'CoreCLRProduct__$(osGroup)$(osSubgroup)_$(archType)_${{ parameters.liveRuntimeBuildConfig }}' - name: coreClrProductRootFolderPath value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(liveRuntimeBuildConfigUpper)' - name: buildProductArtifactName - value: 'MonoProduct__${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + value: 'MonoProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' # minijit and monointerpreter do not use separate product builds. - ${{ if or(eq(parameters.runtimeVariant, 'minijit'), eq(parameters.runtimeVariant, 'monointerpreter')) }}: - name : buildProductArtifactName - value : 'MonoProduct___$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + value : 'MonoProduct__$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' - ${{ if eq(parameters.runtimeVariant, 'llvmfullaot') }}: - name : buildProductArtifactName - value : 'MonoProduct__llvmaot_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + value : 'MonoProduct_llvmaot_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' - name: binTestsPath value: '$(Build.SourcesDirectory)/artifacts/tests/coreclr' diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index 3a9fd8d89ac4b0..34658018fca406 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -425,12 +425,13 @@ extends: - windows_arm64 # - # Build PGO CoreCLR release + # Build PGO Instrumented CoreCLR Release # - template: /eng/pipelines/common/platform-matrix.yml parameters: - jobTemplate: /eng/pipelines/coreclr/templates/build-job.yml - buildConfig: release + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: Release + helixQueueGroup: ci platforms: - windows_x64 - windows_x86 @@ -438,29 +439,13 @@ extends: - windows_arm64 - linux_arm64 jobParameters: + buildArgs: -s clr.native+clr.corelib+clr.tools+clr.nativecorelib+libs+host+packs -c $(_BuildConfig) -pgoinstrument isOfficialBuild: ${{ variables.isOfficialBuild }} - signBinaries: false - testGroup: innerloop - pgoType: 'PGO' - - # - # PGO Build - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/installer/jobs/build-job.yml - buildConfig: Release - jobParameters: - isOfficialBuild: ${{ variables.isOfficialBuild }} - liveRuntimeBuildConfig: release - liveLibrariesBuildConfig: Release - pgoType: 'PGO' - platforms: - - windows_x64 - - windows_x86 - - linux_x64 - - windows_arm64 - - linux_arm64 + nameSuffix: PGO + extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + extraStepsParameters: + name: PGO + timeoutInMinutes: 95 # # Build Workloads @@ -490,9 +475,9 @@ extends: - Build_tvossimulator_arm64_release_AllSubsets_Mono - Build_tvossimulator_x64_release_AllSubsets_Mono - Build_windows_x64_release_CrossAOT_Mono - - installer__coreclr__windows_x64_Release_ - - installer__coreclr__windows_x86_Release_ - - installer__coreclr__windows_arm64_Release_ + - installer_coreclr__windows_x64_Release_ + - installer_coreclr__windows_x86_Release_ + - installer_coreclr__windows_arm64_Release_ - ${{ if eq(variables.isOfficialBuild, true) }}: - template: /eng/pipelines/official/stages/publish.yml diff --git a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml index a6187638cd3461..97c007ba4b3074 100644 --- a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml +++ b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml @@ -5,7 +5,6 @@ parameters: osSubgroup: '' nameSuffix: '' platform: '' - pgoType: '' runtimeVariant: '' librariesBinArtifactName: '' isOfficialBuild: false @@ -32,7 +31,7 @@ steps: tarCompression: $(tarCompression) includeRootFolder: false archiveExtension: $(archiveExtension) - artifactName: CoreCLRProduct_${{ parameters.pgoType }}_${{ parameters.runtimeVariant }}_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }} + artifactName: CoreCLRProduct_${{ parameters.runtimeVariant }}_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }} displayName: 'CoreCLR product build' # Zip Test Build From 8acc1b574817f9d9c6cd79ac5ab9a6348c4004d7 Mon Sep 17 00:00:00 2001 From: Jeff Handley Date: Tue, 30 Apr 2024 11:55:14 -0700 Subject: [PATCH 717/783] [release/8.0-staging] Fix #91958: use mach_timebase_info to determine process time coefficient on macOS (#100122) * Fix #91958: use mach_timebase_info to determine process time coefficient on macOS * (#91958) Process.OSX: fallback for non-zero exit code from mach_timebase_info * (#91958) Process: move OSX-specific tests to a separate file * (#91958) Process.OSX: calculate times lazily * (#91958) Process: include string resources properly in tests * (#91958) Process: more overflow-safe logic * (#91958) Minimize diff * Process.OSX: fix thread safety (#100260) Without this fix, it was possible for another thread to see an incorrect (zero) value of s_timeBase_numer because of a race condition. --------- Co-authored-by: Friedrich von Never --- .../src/Interop/OSX/Interop.Libraries.cs | 1 + .../src/Interop/OSX/Interop.libSystem.cs | 22 +++++++++++ .../src/System.Diagnostics.Process.csproj | 2 + .../src/System/Diagnostics/Process.OSX.cs | 37 +++++++++++++++++-- .../tests/ProcessTests.Unix.cs | 33 +++++++++++++++++ .../tests/Resources/Strings.resx | 6 +++ .../System.Diagnostics.Process.Tests.csproj | 6 +++ 7 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 src/libraries/Common/src/Interop/OSX/Interop.libSystem.cs diff --git a/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs b/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs index 36cdea9e1bd9a4..40423ae3d2083b 100644 --- a/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs +++ b/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs @@ -11,6 +11,7 @@ internal static partial class Libraries internal const string libobjc = "/usr/lib/libobjc.dylib"; internal const string libproc = "/usr/lib/libproc.dylib"; internal const string Odbc32 = "libodbc.2.dylib"; + internal const string libSystem = "libSystem.dylib"; internal const string OpenLdap = "libldap.dylib"; internal const string SystemConfigurationLibrary = "/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration"; internal const string AppleCryptoNative = "libSystem.Security.Cryptography.Native.Apple"; diff --git a/src/libraries/Common/src/Interop/OSX/Interop.libSystem.cs b/src/libraries/Common/src/Interop/OSX/Interop.libSystem.cs new file mode 100644 index 00000000000000..e8662da28e709d --- /dev/null +++ b/src/libraries/Common/src/Interop/OSX/Interop.libSystem.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class libSystem + { + [LibraryImport(Interop.Libraries.libSystem)] + public static unsafe partial int mach_timebase_info(mach_timebase_info_data_t* info); + public struct mach_timebase_info_data_t + { + public uint numer; + public uint denom; + } + } +} diff --git a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj index e82e069ffd3ed5..ddd518ff333e09 100644 --- a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj +++ b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj @@ -317,6 +317,8 @@ Link="Common\Interop\OSX\Interop.libproc.cs" /> + diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.OSX.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.OSX.cs index da44fc1ed3426f..07f55780d82de9 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.OSX.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.OSX.cs @@ -10,6 +10,7 @@ namespace System.Diagnostics public partial class Process { private const int NanosecondsTo100NanosecondsFactor = 100; + private static volatile uint s_timeBase_numer, s_timeBase_denom; private const int MicrosecondsToSecondsFactor = 1_000_000; @@ -23,7 +24,7 @@ public TimeSpan PrivilegedProcessorTime { EnsureState(State.HaveNonExitedId); Interop.libproc.rusage_info_v3 info = Interop.libproc.proc_pid_rusage(_processId); - return new TimeSpan(Convert.ToInt64(info.ri_system_time / NanosecondsTo100NanosecondsFactor)); + return MapTime(info.ri_system_time); } } @@ -65,7 +66,7 @@ public TimeSpan TotalProcessorTime { EnsureState(State.HaveNonExitedId); Interop.libproc.rusage_info_v3 info = Interop.libproc.proc_pid_rusage(_processId); - return new TimeSpan(Convert.ToInt64((info.ri_system_time + info.ri_user_time) / NanosecondsTo100NanosecondsFactor)); + return MapTime(info.ri_system_time + info.ri_user_time); } } @@ -82,7 +83,7 @@ public TimeSpan UserProcessorTime { EnsureState(State.HaveNonExitedId); Interop.libproc.rusage_info_v3 info = Interop.libproc.proc_pid_rusage(_processId); - return new TimeSpan(Convert.ToInt64(info.ri_user_time / NanosecondsTo100NanosecondsFactor)); + return MapTime(info.ri_user_time); } } @@ -109,5 +110,35 @@ private static Interop.libproc.rusage_info_v3 GetCurrentProcessRUsage() { return Interop.libproc.proc_pid_rusage(Environment.ProcessId); } + + private static TimeSpan MapTime(ulong sysTime) + { + uint denom = s_timeBase_denom; + if (denom == default) + { + Interop.libSystem.mach_timebase_info_data_t timeBase = GetTimeBase(); + s_timeBase_numer = timeBase.numer; + s_timeBase_denom = denom = timeBase.denom; + } + uint numer = s_timeBase_numer; + + // By dividing by NanosecondsTo100NanosecondsFactor first, we lose some precision, but increase the range + // where no overflow will happen. + return new TimeSpan(Convert.ToInt64(sysTime / NanosecondsTo100NanosecondsFactor * numer / denom)); + } + + private static unsafe Interop.libSystem.mach_timebase_info_data_t GetTimeBase() + { + Interop.libSystem.mach_timebase_info_data_t timeBase = default; + var returnCode = Interop.libSystem.mach_timebase_info(&timeBase); + Debug.Assert(returnCode == 0, $"Non-zero exit code from mach_timebase_info: {returnCode}"); + if (returnCode != 0) + { + // Fallback: let's assume that the time values are in nanoseconds, + // i.e. the time base is 1/1. + timeBase.numer = timeBase.denom = 1; + } + return timeBase; + } } } diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs index 2085fddbb5d202..79ad7ec01f0a13 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs @@ -851,6 +851,39 @@ static void ExecuteChildProcess(string filename, string flags) } } + [Fact] + [PlatformSpecific(TestPlatforms.OSX)] + public unsafe void TestTotalProcessorTimeMacOs() + { + var rUsage = Interop.libproc.proc_pid_rusage(Environment.ProcessId); + var timeBase = new Interop.libSystem.mach_timebase_info_data_t(); + Interop.libSystem.mach_timebase_info(&timeBase); + + var nativeUserUs = rUsage.ri_user_time / 1000 * timeBase.numer / timeBase.denom; + var nativeSystemUs = rUsage.ri_system_time / 1000 * timeBase.numer / timeBase.denom; + var nativeTotalUs = nativeSystemUs + nativeUserUs; + + var nativeUserTime = TimeSpan.FromMicroseconds(nativeUserUs); + var nativeSystemTime = TimeSpan.FromMicroseconds(nativeSystemUs); + var nativeTotalTime = TimeSpan.FromMicroseconds(nativeTotalUs); + + var process = Process.GetCurrentProcess(); + var managedUserTime = process.UserProcessorTime; + var managedSystemTime = process.PrivilegedProcessorTime; + var managedTotalTime = process.TotalProcessorTime; + + AssertTime(managedUserTime, nativeUserTime, "user"); + AssertTime(managedSystemTime, nativeSystemTime, "system"); + AssertTime(managedTotalTime, nativeTotalTime, "total"); + + void AssertTime(TimeSpan managed, TimeSpan native, string label) + { + Assert.True( + managed >= native, + $"Time '{label}' returned by managed API ({managed}) should be greated or equal to the time returned by native API ({native})."); + } + } + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(true)] [InlineData(false)] diff --git a/src/libraries/System.Diagnostics.Process/tests/Resources/Strings.resx b/src/libraries/System.Diagnostics.Process/tests/Resources/Strings.resx index 4fd9192b919e10..d443842f56cbc6 100644 --- a/src/libraries/System.Diagnostics.Process/tests/Resources/Strings.resx +++ b/src/libraries/System.Diagnostics.Process/tests/Resources/Strings.resx @@ -120,4 +120,10 @@ The argv[0] argument cannot include a double quote. + + Could not get all running Process IDs. + + + Failed to set or retrieve rusage information. See the error code for OS-specific error information. + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj b/src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj index c3f01adc3bc673..889e34344048ac 100644 --- a/src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj +++ b/src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj @@ -63,6 +63,12 @@ + + + From 47f25fbcd4a1e7b29d8ec7f672bdade9a34d7cfd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 16:52:40 -0700 Subject: [PATCH 718/783] [release/8.0-staging] Prefer most derived member in Configuration Binder source generator (#101686) * Prefer most derived member in Configuration Binder source generator * Skip overridden properties in config source generator - include only definitions * Enable shipping Microsoft.Extensions.Configuration.Binder --------- Co-authored-by: Eric StJohn --- .../ConfigurationBindingGenerator.Parser.cs | 6 ++ ...oft.Extensions.Configuration.Binder.csproj | 4 +- .../ConfigurationBinderTests.TestClasses.cs | 59 ++++++++++++++++++ .../tests/Common/ConfigurationBinderTests.cs | 62 +++++++++++++++++++ 4 files changed, 129 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs index 2f6a221de90927..9522eeb83983dc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs @@ -654,6 +654,12 @@ private ObjectSpec CreateObjectSpec(TypeParseInfo typeParseInfo) if (member is IPropertySymbol { IsIndexer: false, IsImplicitlyDeclared: false } property && !IsUnsupportedType(property.Type)) { string propertyName = property.Name; + + if (property.IsOverride || properties?.ContainsKey(propertyName) is true) + { + continue; + } + TypeRef propertyTypeRef = EnqueueTransitiveType(typeParseInfo, property.Type, DiagnosticDescriptors.PropertyNotSupported, propertyName); AttributeData? attributeData = property.GetAttributes().FirstOrDefault(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, _typeSymbols.ConfigurationKeyNameAttribute)); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj index 4d20115e2f710d..8ac03929b07402 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj @@ -4,8 +4,8 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true true - false - 1 + true + 2 Provides the functionality to bind an object to data in configuration providers for Microsoft.Extensions.Configuration. This package enables you to represent the configuration data as strongly-typed classes defined in the application code. To bind a configuration, use the Microsoft.Extensions.Configuration.ConfigurationBinder.Get extension method on the IConfiguration object. To use this package, you also need to install a package for the configuration provider, for example, Microsoft.Extensions.Configuration.Json for the JSON provider. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs index 9aad9566463aff..02f3a74f317b1a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs @@ -930,5 +930,64 @@ public class SimplePoco public string B { get; set; } } + public class BaseForHiddenMembers + { + public string A { get; set; } + public string B { get; set; } + public TestSettingsEnum E {get; set;} + + public virtual string C { get => CBase; set => CBase = value; } + + public string CBase; + + public virtual string D { get; } + + public virtual string F { get => FBase; set => FBase = value; } + public string FBase; + + + public virtual int X { get => XBase; set => XBase = value; } + public int XBase; + } + + public enum TestSettingsEnum2 + { + // Note - the reflection binder will try to bind to every member + Option1 = TestSettingsEnum.Option1, + Option2 = TestSettingsEnum.Option2, + } + + public class IntermediateDerivedClass : BaseForHiddenMembers + { + public new virtual string D { get => DBase; set => DBase = value; } + public string DBase; + + public override string F { get => "IF"; } + + } + + public class DerivedClassWithHiddenMembers : IntermediateDerivedClass + { + public new string A { get; } = "ADerived"; + public new int B { get; set; } + public new TestSettingsEnum2 E + { + get => (TestSettingsEnum2)base.E; + set => base.E = (TestSettingsEnum)value; + } + + // only override get + public override string C { get => "DC"; } + + // override new only get + public override string D { get => "DD"; } + + // two overrides of only get + public override string F { get => "DF"; } + + // override only set + public override int X { set => base.X = value + 1; } + } + } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs index 2103749861348d..c45ce4d836bec3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs @@ -2486,5 +2486,67 @@ public MockConfigurationRoot(IList providers) : base(pro IConfigurationSection IConfiguration.GetSection(string key) => this[key] is null ? null : new ConfigurationSection(this, key); } + + [Fact] + public void CanBindToClassWithNewProperties() + { + /// the source generator will bind to the most derived property only. + /// the reflection binder will bind the same data to all properties (including hidden). + + var config = TestHelpers.GetConfigurationFromJsonString(""" + { + "A": "AVal", + "B": "5", + "C": "CVal", + "D": "DVal", + "E": "Option2", + "F": "FVal", + "X": "52" + } + """); + var obj = new DerivedClassWithHiddenMembers(); + + config.Bind(obj); + + BaseForHiddenMembers baseObj = obj; + IntermediateDerivedClass intermediateObj = obj; + + Assert.Equal("ADerived", obj.A); +#if BUILDING_SOURCE_GENERATOR_TESTS + // source generator will not set hidden property + Assert.Null(baseObj.A); +#else + // reflection binder will set hidden property + Assert.Equal("AVal", baseObj.A); +#endif + + Assert.Equal(5, obj.B); +#if BUILDING_SOURCE_GENERATOR_TESTS + // source generator will not set hidden property + Assert.Null(baseObj.B); +#else + // reflection binder will set hidden property + Assert.Equal("5", baseObj.B); +#endif + + Assert.Equal(TestSettingsEnum2.Option2, obj.E); + Assert.Equal(TestSettingsEnum.Option2, baseObj.E); + + Assert.Equal("DC", obj.C); + // The setter should still be called, even when only getter is overridden. + Assert.Equal("CVal", obj.CBase); + + // can hide a readonly property with r/w property + Assert.Null(baseObj.D); + Assert.Equal("DD", obj.D); + // The setter should still be called, even when only getter is overridden. + Assert.Equal("DVal", obj.DBase); + + Assert.Equal("DF", obj.F); + Assert.Equal("FVal", obj.FBase); + + Assert.Equal(53, obj.X); + Assert.Equal(53, obj.XBase); + } } } From 97bc9c4a26514021347b0d5173319d7cf18dcda1 Mon Sep 17 00:00:00 2001 From: vseanreesermsft <78103370+vseanreesermsft@users.noreply.github.com> Date: Wed, 1 May 2024 17:33:53 -0700 Subject: [PATCH 719/783] Update branding to 8.0.6 (#101779) --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index f012e409095090..bb6bc30992a14f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,11 +1,11 @@ - 8.0.5 + 8.0.6 8 0 - 5 + 6 8.0.100 7.0.$([MSBuild]::Add($(PatchVersion),14)) 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) From a0411dfeffcd3c12325290e88eb22828af3f3c63 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 11:08:26 +0200 Subject: [PATCH 720/783] [mono][interp] Resolve virtual method on delegates created by compiled code (#101290) Creating a delegate would normally end up calling into the runtime via ves_icall_mono_delegate_ctor. However, jit/aot backand have a fastpath where the delegate is not fully initialized (relying on the delegate trampoline to resolve the actual method to be called when the delegate is first called). Interp delegate initialization therefore doesn't take place. If this is the case and the delegate method is virtual, we would need to resolve it based on the target object. Co-authored-by: Vlad Brezae --- src/mono/mono/mini/interp/interp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index c7d47719714de1..620dc135d50f27 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -4016,6 +4016,8 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause // Not created from interpreted code g_assert (del->method); del_imethod = mono_interp_get_imethod (del->method); + if (del->target && m_method_is_virtual (del->method)) + del_imethod = get_virtual_method (del_imethod, del->target->vtable); del->interp_method = del_imethod; del->interp_invoke_impl = del_imethod; } else { From 37a6d07247d3b69051f6d0997cd42afa30cc129e Mon Sep 17 00:00:00 2001 From: Eduardo Velarde <32459232+eduardo-vp@users.noreply.github.com> Date: Thu, 2 May 2024 10:35:15 -0700 Subject: [PATCH 721/783] Backport #92375 and #93082 to release/8.0-staging (#101744) * Allow multiple post-build steps and allow templated pre and post-build steps (#92375) * Convert AllConfigurations and NETFX jobs to use the global build templates (#93082) --------- Co-authored-by: Jeremy Koritzinsky --- eng/pipelines/common/global-build-job.yml | 64 ++++-- .../templates/browser-wasm-build-tests.yml | 15 +- .../templates/simple-wasm-build-tests.yml | 15 +- .../common/templates/wasm-build-only.yml | 9 +- .../common/templates/wasm-debugger-tests.yml | 15 +- .../common/templates/wasm-library-tests.yml | 13 +- .../common/templates/wasm-runtime-tests.yml | 9 +- eng/pipelines/coreclr/ci.yml | 3 +- eng/pipelines/coreclr/perf-non-wasm-jobs.yml | 102 ++++----- eng/pipelines/coreclr/perf-wasm-jobs.yml | 14 +- eng/pipelines/coreclr/perf_slow.yml | 19 +- .../runtime-extra-platforms-android.yml | 18 +- ...untime-extra-platforms-androidemulator.yml | 27 +-- .../runtime-extra-platforms-ioslike.yml | 50 ++--- ...ntime-extra-platforms-ioslikesimulator.yml | 39 ++-- .../runtime-extra-platforms-linuxbionic.yml | 9 +- .../runtime-extra-platforms-maccatalyst.yml | 20 +- .../runtime-extra-platforms-other.yml | 30 +-- eng/pipelines/libraries/outerloop-mono.yml | 26 +-- eng/pipelines/libraries/outerloop.yml | 33 +-- .../runtime-android-grpc-client-tests.yml | 11 +- eng/pipelines/runtime-community.yml | 28 +-- eng/pipelines/runtime-linker-tests.yml | 10 +- eng/pipelines/runtime-official.yml | 70 ++++--- eng/pipelines/runtime-sanitized.yml | 39 ++-- eng/pipelines/runtime.yml | 195 ++++++++++-------- eng/pipelines/runtimelab.yml | 27 +-- 27 files changed, 509 insertions(+), 401 deletions(-) diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index a13548956ff600..cdda8c99dc519c 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -26,8 +26,7 @@ parameters: helixQueues: '' enablePublishTestResults: false testResultsFormat: '' - extraStepsTemplate: '' - extraStepsParameters: {} + postBuildSteps: [] extraVariablesTemplates: [] isManualCodeQLBuild: false preBuildSteps: [] @@ -209,7 +208,28 @@ jobs: - ${{ if ne(parameters.preBuildSteps,'') }}: - ${{ each preBuildStep in parameters.preBuildSteps }}: - - ${{ preBuildStep }} + - ${{ if ne(preBuildStep.template, '') }}: + - template: ${{ preBuildStep.template }} + parameters: + osGroup: ${{ parameters.osGroup }} + osSubgroup: ${{ parameters.osSubgroup }} + archType: ${{ parameters.archType }} + buildConfig: ${{ parameters.buildConfig }} + runtimeFlavor: ${{ parameters.runtimeFlavor }} + runtimeVariant: ${{ parameters.runtimeVariant }} + helixQueues: ${{ parameters.helixQueues }} + targetRid: ${{ parameters.targetRid }} + nameSuffix: ${{ parameters.nameSuffix }} + platform: ${{ parameters.platform }} + pgoType: ${{ parameters.pgoType }} + shouldContinueOnError: ${{ parameters.shouldContinueOnError }} + ${{ if ne(preBuildStep.forwardedParameters, '') }}: + ${{ each parameter in preBuildStep.forwardedParameters }}: + ${{ parameter }}: ${{ parameters[parameter] }} + ${{ if ne(preBuildStep.parameters, '') }}: + ${{ insert }}: ${{ preBuildStep.parameters }} + - ${{ else }}: + - ${{ preBuildStep }} # Build - ${{ if eq(parameters.isSourceBuild, false) }}: @@ -235,21 +255,29 @@ jobs: condition: always() # If intended to send extra steps after regular build add them here. - - ${{ if ne(parameters.extraStepsTemplate, '') }}: - - template: ${{ parameters.extraStepsTemplate }} - parameters: - osGroup: ${{ parameters.osGroup }} - osSubgroup: ${{ parameters.osSubgroup }} - archType: ${{ parameters.archType }} - buildConfig: ${{ parameters.buildConfig }} - runtimeFlavor: ${{ parameters.runtimeFlavor }} - runtimeVariant: ${{ parameters.runtimeVariant }} - helixQueues: ${{ parameters.helixQueues }} - targetRid: ${{ parameters.targetRid }} - nameSuffix: ${{ parameters.nameSuffix }} - platform: ${{ parameters.platform }} - shouldContinueOnError: ${{ parameters.shouldContinueOnError }} - ${{ insert }}: ${{ parameters.extraStepsParameters }} + - ${{ if ne(parameters.postBuildSteps,'') }}: + - ${{ each postBuildStep in parameters.postBuildSteps }}: + - ${{ if ne(postBuildStep.template, '') }}: + - template: ${{ postBuildStep.template }} + parameters: + osGroup: ${{ parameters.osGroup }} + osSubgroup: ${{ parameters.osSubgroup }} + archType: ${{ parameters.archType }} + buildConfig: ${{ parameters.buildConfig }} + runtimeFlavor: ${{ parameters.runtimeFlavor }} + runtimeVariant: ${{ parameters.runtimeVariant }} + helixQueues: ${{ parameters.helixQueues }} + targetRid: ${{ parameters.targetRid }} + nameSuffix: ${{ parameters.nameSuffix }} + platform: ${{ parameters.platform }} + shouldContinueOnError: ${{ parameters.shouldContinueOnError }} + ${{ if ne(postBuildStep.forwardedParameters, '') }}: + ${{ each parameter in postBuildStep.forwardedParameters }}: + ${{ parameter }}: ${{ parameters[parameter] }} + ${{ if ne(postBuildStep.parameters, '') }}: + ${{ insert }}: ${{ postBuildStep.parameters }} + - ${{ else }}: + - ${{ postBuildStep }} - ${{ if and(eq(parameters.isOfficialBuild, true), eq(parameters.osGroup, 'windows')) }}: - powershell: ./eng/collect_vsinfo.ps1 -ArchiveRunName postbuild_log diff --git a/eng/pipelines/common/templates/browser-wasm-build-tests.yml b/eng/pipelines/common/templates/browser-wasm-build-tests.yml index 742ad88de1c80a..29a3f854724738 100644 --- a/eng/pipelines/common/templates/browser-wasm-build-tests.yml +++ b/eng/pipelines/common/templates/browser-wasm-build-tests.yml @@ -117,10 +117,11 @@ jobs: eq(variables['isDefaultPipeline'], variables['shouldRunWasmBuildTestsOnDefaultPipeline'])) # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig)_$(_hostedOs) - extraHelixArguments: /p:BrowserHost=$(_hostedOs) - scenarios: - - buildwasmapps + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig)_$(_hostedOs) + extraHelixArguments: /p:BrowserHost=$(_hostedOs) + scenarios: + - buildwasmapps diff --git a/eng/pipelines/common/templates/simple-wasm-build-tests.yml b/eng/pipelines/common/templates/simple-wasm-build-tests.yml index dcba5522f441b4..7a593f4f9be203 100644 --- a/eng/pipelines/common/templates/simple-wasm-build-tests.yml +++ b/eng/pipelines/common/templates/simple-wasm-build-tests.yml @@ -41,11 +41,12 @@ jobs: eq(variables['alwaysRunVar'], true), eq(variables['isDefaultPipeline'], variables['shouldRunWasmBuildTestsOnDefaultPipeline'])) # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig)_$(_hostedOs) - extraHelixArguments: /p:BrowserHost=$(_hostedOs) - scenarios: - - buildwasmapps + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig)_$(_hostedOs) + extraHelixArguments: /p:BrowserHost=$(_hostedOs) + scenarios: + - buildwasmapps diff --git a/eng/pipelines/common/templates/wasm-build-only.yml b/eng/pipelines/common/templates/wasm-build-only.yml index 9e9b0cb332c8fa..4f2588e4985698 100644 --- a/eng/pipelines/common/templates/wasm-build-only.yml +++ b/eng/pipelines/common/templates/wasm-build-only.yml @@ -38,7 +38,8 @@ jobs: buildArgs: -s mono+libs+packs+libs.tests$(workloadSubsetArg) -c $(_BuildConfig) /p:BrowserHost=$(_hostedOs) ${{ parameters.extraBuildArgs }} /p:TestAssemblies=false $(extraBuildArgs) timeoutInMinutes: 120 condition: ${{ parameters.condition }} - extraStepsTemplate: /eng/pipelines/common/wasm-post-build-steps.yml - extraStepsParameters: - publishArtifactsForWorkload: ${{ parameters.publishArtifactsForWorkload }} - publishWBT: ${{ parameters.publishWBT }} + postBuildSteps: + - template: /eng/pipelines/common/wasm-post-build-steps.yml + parameters: + publishArtifactsForWorkload: ${{ parameters.publishArtifactsForWorkload }} + publishWBT: ${{ parameters.publishWBT }} diff --git a/eng/pipelines/common/templates/wasm-debugger-tests.yml b/eng/pipelines/common/templates/wasm-debugger-tests.yml index fd19fe5385cbb9..17c0f415cf1b44 100644 --- a/eng/pipelines/common/templates/wasm-debugger-tests.yml +++ b/eng/pipelines/common/templates/wasm-debugger-tests.yml @@ -52,10 +52,11 @@ jobs: and( eq(variables['isDefaultPipeline'], variables['shouldRunOnDefaultPipelines']), eq(${{ parameters.isWasmOnlyBuild }}, ${{ parameters.runOnlyOnWasmOnlyPipelines }}))) - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_${{ parameters.browser }}_$(_BuildConfig) - extraHelixArguments: /p:BrowserHost=$(_hostedOs) /p:_DebuggerHosts=${{ parameters.browser }} - scenarios: - - wasmdebuggertests + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_${{ parameters.browser }}_$(_BuildConfig) + extraHelixArguments: /p:BrowserHost=$(_hostedOs) /p:_DebuggerHosts=${{ parameters.browser }} + scenarios: + - wasmdebuggertests diff --git a/eng/pipelines/common/templates/wasm-library-tests.yml b/eng/pipelines/common/templates/wasm-library-tests.yml index a848e25e1a28a9..4260e56ba2cb41 100644 --- a/eng/pipelines/common/templates/wasm-library-tests.yml +++ b/eng/pipelines/common/templates/wasm-library-tests.yml @@ -62,9 +62,10 @@ jobs: eq(variables['alwaysRunVar'], true), eq(variables['isDefaultPipeline'], variables['shouldRunOnDefaultPipelines'])) # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) - extraHelixArguments: /p:BrowserHost=$(_hostedOs) $(_wasmRunSmokeTestsOnlyArg) ${{ parameters.extraHelixArgs }} - scenarios: ${{ parameters.scenarios }} + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + extraHelixArguments: /p:BrowserHost=$(_hostedOs) $(_wasmRunSmokeTestsOnlyArg) ${{ parameters.extraHelixArgs }} + scenarios: ${{ parameters.scenarios }} diff --git a/eng/pipelines/common/templates/wasm-runtime-tests.yml b/eng/pipelines/common/templates/wasm-runtime-tests.yml index 43671a546ba001..2b006bb2db3ccd 100644 --- a/eng/pipelines/common/templates/wasm-runtime-tests.yml +++ b/eng/pipelines/common/templates/wasm-runtime-tests.yml @@ -42,9 +42,10 @@ jobs: or( eq(variables['alwaysRunVar'], true), eq(variables['isDefaultPipeline'], variables['shouldRunOnDefaultPipelines'])) - extraStepsTemplate: //eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml diff --git a/eng/pipelines/coreclr/ci.yml b/eng/pipelines/coreclr/ci.yml index 17806e944070c2..afff0abf00b5d8 100644 --- a/eng/pipelines/coreclr/ci.yml +++ b/eng/pipelines/coreclr/ci.yml @@ -174,4 +174,5 @@ extends: jobParameters: buildArgs: -s clr.paltests+clr.paltestlist nameSuffix: PALTests - extraStepsTemplate: /eng/pipelines/coreclr/templates/run-paltests-step.yml + postBuildSteps: + - template: /eng/pipelines/coreclr/templates/run-paltests-step.yml diff --git a/eng/pipelines/coreclr/perf-non-wasm-jobs.yml b/eng/pipelines/coreclr/perf-non-wasm-jobs.yml index b7f87d7cf89d97..3e28bb7bcae69c 100644 --- a/eng/pipelines/coreclr/perf-non-wasm-jobs.yml +++ b/eng/pipelines/coreclr/perf-non-wasm-jobs.yml @@ -48,15 +48,16 @@ jobs: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:BuildMonoAOTCrossCompiler=true /p:MonoLibClang="/usr/local/lib/libclang.so.16" /p:AotHostArchitecture=x64 /p:AotHostOS=linux nameSuffix: AOT isOfficialBuild: false - extraStepsTemplate: /eng/pipelines/common/upload-artifact-step.yml - extraStepsParameters: - rootFolder: '$(Build.SourcesDirectory)/artifacts/' - includeRootFolder: true - displayName: AOT Mono Artifacts - artifactName: LinuxMonoAOTx64 - archiveExtension: '.tar.gz' - archiveType: tar - tarCompression: gz + postBuildSteps: + - template: /eng/pipelines/common/upload-artifact-step.yml + parameters: + rootFolder: '$(Build.SourcesDirectory)/artifacts/' + includeRootFolder: true + displayName: AOT Mono Artifacts + artifactName: LinuxMonoAOTx64 + archiveExtension: '.tar.gz' + archiveType: tar + tarCompression: gz # build mono Android scenarios - template: /eng/pipelines/common/platform-matrix.yml @@ -70,15 +71,16 @@ jobs: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) nameSuffix: AndroidMono isOfficialBuild: false - extraStepsTemplate: /eng/pipelines/coreclr/templates/build-perf-sample-apps.yml - extraStepsParameters: - rootFolder: '$(Build.SourcesDirectory)/artifacts/' - includeRootFolder: true - displayName: Android Mono Artifacts - artifactName: AndroidMonoarm64 - archiveExtension: '.tar.gz' - archiveType: tar - tarCompression: gz + postBuildSteps: + - template: /eng/pipelines/coreclr/templates/build-perf-sample-apps.yml + parameters: + rootFolder: '$(Build.SourcesDirectory)/artifacts/' + includeRootFolder: true + displayName: Android Mono Artifacts + artifactName: AndroidMonoarm64 + archiveExtension: '.tar.gz' + archiveType: tar + tarCompression: gz # build mono iOS scenarios - template: /eng/pipelines/common/platform-matrix.yml @@ -92,15 +94,16 @@ jobs: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) nameSuffix: iOSMono isOfficialBuild: false - extraStepsTemplate: /eng/pipelines/coreclr/templates/build-perf-sample-apps.yml - extraStepsParameters: - rootFolder: '$(Build.SourcesDirectory)/artifacts/' - includeRootFolder: true - displayName: iOS Mono Artifacts - artifactName: iOSMonoarm64 - archiveExtension: '.tar.gz' - archiveType: tar - tarCompression: gz + postBuildSteps: + - template: /eng/pipelines/coreclr/templates/build-perf-sample-apps.yml + parameters: + rootFolder: '$(Build.SourcesDirectory)/artifacts/' + includeRootFolder: true + displayName: iOS Mono Artifacts + artifactName: iOSMonoarm64 + archiveExtension: '.tar.gz' + archiveType: tar + tarCompression: gz # build NativeAOT iOS scenarios - template: /eng/pipelines/common/platform-matrix.yml @@ -114,15 +117,16 @@ jobs: buildArgs: --cross -s clr.alljits+clr.tools+clr.nativeaotruntime+clr.nativeaotlibs+libs -c $(_BuildConfig) nameSuffix: iOSNativeAOT isOfficialBuild: false - extraStepsTemplate: /eng/pipelines/coreclr/templates/build-perf-sample-apps.yml - extraStepsParameters: - rootFolder: '$(Build.SourcesDirectory)/artifacts/' - includeRootFolder: true - displayName: iOS NativeAOT Artifacts - artifactName: iOSNativeAOTarm64 - archiveExtension: '.tar.gz' - archiveType: tar - tarCompression: gz + postBuildSteps: + - template: /eng/pipelines/coreclr/templates/build-perf-sample-apps.yml + parameters: + rootFolder: '$(Build.SourcesDirectory)/artifacts/' + includeRootFolder: true + displayName: iOS NativeAOT Artifacts + artifactName: iOSNativeAOTarm64 + archiveExtension: '.tar.gz' + archiveType: tar + tarCompression: gz # build mono - template: /eng/pipelines/common/platform-matrix.yml @@ -409,9 +413,10 @@ jobs: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) nameSuffix: Mono_Packs isOfficialBuild: false - extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - extraStepsParameters: - name: MonoRuntimePacks + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: MonoRuntimePacks # build PerfBDN app - template: /eng/pipelines/common/platform-matrix.yml @@ -429,12 +434,13 @@ jobs: isOfficialBuild: false pool: vmImage: 'macos-12' - extraStepsTemplate: /eng/pipelines/coreclr/templates/build-perf-bdn-app.yml - extraStepsParameters: - rootFolder: '$(Build.SourcesDirectory)/artifacts/' - includeRootFolder: true - displayName: Android BDN App Artifacts - artifactName: PerfBDNAppArm - archiveExtension: '.tar.gz' - archiveType: tar - tarCompression: gz + postBuildSteps: + - template: /eng/pipelines/coreclr/templates/build-perf-bdn-app.yml + parameters: + rootFolder: '$(Build.SourcesDirectory)/artifacts/' + includeRootFolder: true + displayName: Android BDN App Artifacts + artifactName: PerfBDNAppArm + archiveExtension: '.tar.gz' + archiveType: tar + tarCompression: gz diff --git a/eng/pipelines/coreclr/perf-wasm-jobs.yml b/eng/pipelines/coreclr/perf-wasm-jobs.yml index 7758eac4d12cb0..bbfba488347560 100644 --- a/eng/pipelines/coreclr/perf-wasm-jobs.yml +++ b/eng/pipelines/coreclr/perf-wasm-jobs.yml @@ -25,9 +25,10 @@ jobs: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS) nameSuffix: wasm isOfficialBuild: false - extraStepsTemplate: /eng/pipelines/coreclr/perf-wasm-prepare-artifacts-steps.yml - extraStepsParameters: - configForBuild: Release + postBuildSteps: + - template: /eng/pipelines/coreclr/perf-wasm-prepare-artifacts-steps.yml + parameters: + configForBuild: Release #run mono wasm microbenchmarks perf job - template: /eng/pipelines/common/platform-matrix.yml @@ -94,9 +95,10 @@ jobs: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS) nameSuffix: wasm isOfficialBuild: false - extraStepsTemplate: /eng/pipelines/coreclr/perf-wasm-prepare-artifacts-steps.yml - extraStepsParameters: - configForBuild: Release + postBuildSteps: + - template: /eng/pipelines/coreclr/perf-wasm-prepare-artifacts-steps.yml + parameters: + configForBuild: Release # run mono wasm interpreter (default) microbenchmarks perf job - template: /eng/pipelines/common/platform-matrix.yml diff --git a/eng/pipelines/coreclr/perf_slow.yml b/eng/pipelines/coreclr/perf_slow.yml index 91e3ad34f38c80..d6124364554b07 100644 --- a/eng/pipelines/coreclr/perf_slow.yml +++ b/eng/pipelines/coreclr/perf_slow.yml @@ -143,15 +143,16 @@ extends: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true /p:BuildMonoAOTCrossCompiler=true /p:MonoLibClang="/usr/local/lib/libclang.so.16" /p:AotHostArchitecture=arm64 /p:AotHostOS=linux nameSuffix: AOT isOfficialBuild: false - extraStepsTemplate: /eng/pipelines/common/upload-artifact-step.yml - extraStepsParameters: - rootFolder: '$(Build.SourcesDirectory)/artifacts/' - includeRootFolder: true - displayName: AOT Mono Artifacts - artifactName: LinuxMonoAOTarm64 - archiveExtension: '.tar.gz' - archiveType: tar - tarCompression: gz + postBuildSteps: + - template: /eng/pipelines/common/upload-artifact-step.yml + parameters: + rootFolder: '$(Build.SourcesDirectory)/artifacts/' + includeRootFolder: true + displayName: AOT Mono Artifacts + artifactName: LinuxMonoAOTarm64 + archiveExtension: '.tar.gz' + archiveType: tar + tarCompression: gz # run mono aot microbenchmarks perf job - template: /eng/pipelines/common/platform-matrix.yml diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml index 23c57b87fe538c..9fd1769fe18fad 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml +++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml @@ -44,10 +44,11 @@ jobs: # Turn off the testing for now, until https://github.com/dotnet/runtime/issues/60128 gets resolved # ${{ if eq(variables['isRollingBuild'], true) }}: # # extra steps, run tests - # extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - # extraStepsParameters: - # creator: dotnet-bot - # testRunNamePrefixSuffix: Mono_$(_BuildConfig) + # postBuildSteps: + # - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + # parameters: + # creator: dotnet-bot + # testRunNamePrefixSuffix: Mono_$(_BuildConfig) # extraVariablesTemplates: # - template: /eng/pipelines/common/templates/runtimes/test-variables.yml @@ -77,7 +78,8 @@ jobs: buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:EnableAdditionalTimezoneChecks=true timeoutInMinutes: 480 # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml index 65a890976e7396..a114b1b744a136 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml +++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml @@ -40,10 +40,11 @@ jobs: buildArgs: -s mono+libs -c $(_BuildConfig) timeoutInMinutes: 240 # extra steps, run tests - extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml @@ -78,10 +79,11 @@ jobs: buildArgs: -s mono+libs -c $(_BuildConfig) timeoutInMinutes: 240 # extra steps, run tests - extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml @@ -111,7 +113,8 @@ jobs: buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) timeoutInMinutes: 180 # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml index 84477d2c25a8ad..ef0425042b5e6d 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml +++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml @@ -38,11 +38,12 @@ jobs: buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg) /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=true /p:BuildDarwinFrameworks=true /p:IsManualOrRollingBuild=true timeoutInMinutes: 480 # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) - extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true # # iOS/tvOS devices @@ -80,14 +81,15 @@ jobs: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml parameters: testGroup: innerloop - extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - extraStepsParameters: - creator: dotnet-bot - compileOnHelix: true - interpreter: true - testBuildArgs: /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildTestsOnHelix=true - testRunNamePrefixSuffix: Mono_$(_BuildConfig) - extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + parameters: + creator: dotnet-bot + compileOnHelix: true + interpreter: true + testBuildArgs: /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildTestsOnHelix=true + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true # # iOS/tvOS devices @@ -116,11 +118,12 @@ jobs: buildArgs: --cross -s clr.alljits+clr.tools+clr.nativeaotruntime+clr.nativeaotlibs+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:DevTeamProvisioning=- /p:BuildTestsOnHelix=true /p:UseNativeAOTRuntime=true /p:RunAOTCompilation=false /p:ContinuousIntegrationBuild=true timeoutInMinutes: 180 # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) - extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) + extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true # # Build the whole product using NativeAOT for iOS/tvOS and run runtime tests with iOS/tvOS devices @@ -151,8 +154,9 @@ jobs: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml parameters: testGroup: innerloop - extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - extraStepsParameters: - creator: dotnet-bot - testBuildArgs: tree nativeaot/SmokeTests /p:BuildNativeAOTRuntimePack=true - testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + parameters: + creator: dotnet-bot + testBuildArgs: tree nativeaot/SmokeTests /p:BuildNativeAOTRuntimePack=true + testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml index c7bcfc15e132be..b11b4be72ed6e4 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml +++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml @@ -40,11 +40,12 @@ jobs: buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildDarwinFrameworks=true timeoutInMinutes: 180 # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - interpreter: true - testRunNamePrefixSuffix: Mono_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + interpreter: true + testRunNamePrefixSuffix: Mono_$(_BuildConfig) # # Build the whole product using Mono for iOSSimulator/tvOSSimulator and run runtime tests with iOS/tvOS simulators @@ -84,14 +85,15 @@ jobs: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml parameters: testGroup: innerloop - extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - extraStepsParameters: - creator: dotnet-bot - compileOnHelix: true - interpreter: true - testBuildArgs: /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildTestsOnHelix=true - testRunNamePrefixSuffix: Mono_$(_BuildConfig) - extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + parameters: + creator: dotnet-bot + compileOnHelix: true + interpreter: true + testBuildArgs: /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildTestsOnHelix=true + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true # # Build the whole product using Native AOT for iOSSimulator/tvOSSimulator and run runtime tests with iOS/tvOS simulators @@ -131,8 +133,9 @@ jobs: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml parameters: testGroup: innerloop - extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - extraStepsParameters: - creator: dotnet-bot - testBuildArgs: tree nativeaot/SmokeTests /p:BuildNativeAOTRuntimePack=true - testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + parameters: + creator: dotnet-bot + testBuildArgs: tree nativeaot/SmokeTests /p:BuildNativeAOTRuntimePack=true + testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-linuxbionic.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-linuxbionic.yml index 352eabe9d22d4a..7eb5fa47f80829 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-linuxbionic.yml +++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-linuxbionic.yml @@ -42,7 +42,8 @@ jobs: buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true timeoutInMinutes: 480 # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig)_LinuxBionic + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig)_LinuxBionic diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-maccatalyst.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-maccatalyst.yml index 736bf0516dfdf2..936fe60bb48330 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-maccatalyst.yml +++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-maccatalyst.yml @@ -37,10 +37,11 @@ jobs: buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=adhoc /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildDarwinFrameworks=true timeoutInMinutes: 180 # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) # # MacCatalyst interp - requires AOT Compilation and Interp flags @@ -70,8 +71,9 @@ jobs: buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:DevTeamProvisioning=adhoc /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildDarwinFrameworks=true /p:EnableAppSandbox=true timeoutInMinutes: 180 # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - interpreter: true - testRunNamePrefixSuffix: Mono_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + interpreter: true + testRunNamePrefixSuffix: Mono_$(_BuildConfig) diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml index c279c318e34d59..ee481119ad9607 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml +++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml @@ -279,15 +279,16 @@ jobs: eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true), eq(variables['isRollingBuild'], true)) # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) - condition: >- - or( - eq(variables['librariesContainsChange'], true), - eq(variables['monoContainsChange'], true), - eq(variables['isRollingBuild'], true)) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + condition: >- + or( + eq(variables['librariesContainsChange'], true), + eq(variables['monoContainsChange'], true), + eq(variables['isRollingBuild'], true)) # # Build the whole product using Mono and run runtime tests @@ -380,11 +381,12 @@ jobs: eq(dependencies.evaluate_paths.outputs['SetPathVars_mono_excluding_wasm.containsChange'], true), eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true), eq(variables['isRollingBuild'], true)) - extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - extraStepsParameters: - creator: dotnet-bot - llvmAotStepContainer: linux_x64_llvmaot - testRunNamePrefixSuffix: Mono_Release + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + parameters: + creator: dotnet-bot + llvmAotStepContainer: linux_x64_llvmaot + testRunNamePrefixSuffix: Mono_Release extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml diff --git a/eng/pipelines/libraries/outerloop-mono.yml b/eng/pipelines/libraries/outerloop-mono.yml index e15fc35f9d41c9..34b1af3c71b56a 100644 --- a/eng/pipelines/libraries/outerloop-mono.yml +++ b/eng/pipelines/libraries/outerloop-mono.yml @@ -39,11 +39,12 @@ extends: timeoutInMinutes: 180 includeAllPlatforms: ${{ variables['isRollingBuild'] }} # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - testScope: outerloop - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + testScope: outerloop + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) - template: /eng/pipelines/common/platform-matrix.yml parameters: @@ -60,10 +61,11 @@ extends: timeoutInMinutes: 180 includeAllPlatforms: ${{ variables['isRollingBuild'] }} # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - scenarios: - - normal - testScope: outerloop - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + scenarios: + - normal + testScope: outerloop + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) diff --git a/eng/pipelines/libraries/outerloop.yml b/eng/pipelines/libraries/outerloop.yml index 121d405fc7c7c4..597f298c37a3e0 100644 --- a/eng/pipelines/libraries/outerloop.yml +++ b/eng/pipelines/libraries/outerloop.yml @@ -45,11 +45,12 @@ extends: timeoutInMinutes: 180 includeAllPlatforms: ${{ variables['isRollingBuild'] }} # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - testScope: outerloop - creator: dotnet-bot - testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + testScope: outerloop + creator: dotnet-bot + testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig) - ${{ if eq(variables['isRollingBuild'], false) }}: - template: /eng/pipelines/common/platform-matrix.yml @@ -73,11 +74,12 @@ extends: timeoutInMinutes: 180 includeAllPlatforms: ${{ variables['isRollingBuild'] }} # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - testScope: outerloop - creator: dotnet-bot - testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + testScope: outerloop + creator: dotnet-bot + testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig) - ${{ if eq(variables['includeWindowsOuterloop'], true) }}: - template: /eng/pipelines/common/platform-matrix.yml @@ -97,8 +99,9 @@ extends: timeoutInMinutes: 180 includeAllPlatforms: ${{ variables['isRollingBuild'] }} # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - testScope: outerloop - creator: dotnet-bot - extraHelixArguments: /p:BuildTargetFramework=net48 + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + testScope: outerloop + creator: dotnet-bot + extraHelixArguments: /p:BuildTargetFramework=net48 diff --git a/eng/pipelines/runtime-android-grpc-client-tests.yml b/eng/pipelines/runtime-android-grpc-client-tests.yml index 00e51f766d95ce..707b1d78ebc0e4 100644 --- a/eng/pipelines/runtime-android-grpc-client-tests.yml +++ b/eng/pipelines/runtime-android-grpc-client-tests.yml @@ -43,8 +43,9 @@ extends: buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunGrpcTestsOnly=true /p:BuildGrpcServerDockerImage=true timeoutInMinutes: 180 # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - extraHelixArguments: /p:RunGrpcTestsOnly=true /p:BuildGrpcServerDockerImage=true - testRunNamePrefixSuffix: Mono_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + extraHelixArguments: /p:RunGrpcTestsOnly=true /p:BuildGrpcServerDockerImage=true + testRunNamePrefixSuffix: Mono_$(_BuildConfig) diff --git a/eng/pipelines/runtime-community.yml b/eng/pipelines/runtime-community.yml index bab086f75c23dc..a91388e244b0b8 100644 --- a/eng/pipelines/runtime-community.yml +++ b/eng/pipelines/runtime-community.yml @@ -71,15 +71,16 @@ extends: eq(dependencies.evaluate_paths.outputs['SetPathVars_mono_excluding_wasm.containsChange'], true), eq(variables['isRollingBuild'], true)) # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) - condition: >- - or( - eq(variables['librariesContainsChange'], true), - eq(variables['monoContainsChange'], true), - eq(variables['isRollingBuild'], true)) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + condition: >- + or( + eq(variables['librariesContainsChange'], true), + eq(variables['monoContainsChange'], true), + eq(variables['isRollingBuild'], true)) # # Build the whole product using Mono @@ -138,7 +139,8 @@ extends: eq(variables['isRollingBuild'], true)) ${{ if eq(variables['isRollingBuild'], true) }}: # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) diff --git a/eng/pipelines/runtime-linker-tests.yml b/eng/pipelines/runtime-linker-tests.yml index 9db2062a953d32..1cb0f8428ef7b8 100644 --- a/eng/pipelines/runtime-linker-tests.yml +++ b/eng/pipelines/runtime-linker-tests.yml @@ -103,7 +103,8 @@ extends: eq(dependencies.evaluate_paths.outputs['SetPathVars_non_mono_and_wasm.containsChange'], true), eq(variables['isRollingBuild'], true)) buildArgs: -s clr+libs+tools.illink -c $(_BuildConfig) - extraStepsTemplate: /eng/pipelines/libraries/execute-trimming-tests-steps.yml + postBuildSteps: + - template: /eng/pipelines/libraries/execute-trimming-tests-steps.yml # # Build Release config vertical for Browser-wasm @@ -126,6 +127,7 @@ extends: eq(dependencies.evaluate_paths.outputs['SetPathVars_wasm_specific_except_wbt_dbg.containsChange'], true), eq(dependencies.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'], true), eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_NET_ILLink_Tasks'], true)) - extraStepsTemplate: /eng/pipelines/libraries/execute-trimming-tests-steps.yml - extraStepsParameters: - extraTestArgs: '/p:WasmBuildNative=false' + postBuildSteps: + - template: /eng/pipelines/libraries/execute-trimming-tests-steps.yml + parameters: + extraTestArgs: '/p:WasmBuildNative=false' diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index 34658018fca406..3138f18ebd734b 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -124,9 +124,10 @@ extends: buildArgs: -s clr.nativeaotlibs+clr.nativeaotruntime+libs+packs -c $(_BuildConfig) /p:BuildNativeAOTRuntimePack=true /p:SkipLibrariesNativeRuntimePackages=true nameSuffix: AllSubsets_NativeAOT isOfficialBuild: ${{ variables.isOfficialBuild }} - extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - extraStepsParameters: - name: NativeAOTRuntimePacks + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: NativeAOTRuntimePacks # # Build Mono runtime packs @@ -166,9 +167,10 @@ extends: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:BuildMonoAOTCrossCompiler=false nameSuffix: AllSubsets_Mono isOfficialBuild: ${{ variables.isOfficialBuild }} - extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - extraStepsParameters: - name: MonoRuntimePacks + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: MonoRuntimePacks - template: /eng/pipelines/common/platform-matrix.yml parameters: @@ -182,9 +184,10 @@ extends: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS) nameSuffix: AllSubsets_Mono isOfficialBuild: ${{ variables.isOfficialBuild }} - extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - extraStepsParameters: - name: MonoRuntimePacks + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: MonoRuntimePacks - template: /eng/pipelines/common/platform-matrix.yml parameters: @@ -198,9 +201,10 @@ extends: nameSuffix: AllSubsets_Mono_multithread isOfficialBuild: ${{ variables.isOfficialBuild }} runtimeVariant: multithread - extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - extraStepsParameters: - name: MonoRuntimePacks + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: MonoRuntimePacks # Build Mono AOT offset headers once, for consumption elsewhere # @@ -242,9 +246,10 @@ extends: - android - browser isOfficialBuild: ${{ variables.isOfficialBuild }} - extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - extraStepsParameters: - name: MonoRuntimePacks + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: MonoRuntimePacks - template: /eng/pipelines/common/platform-matrix.yml parameters: @@ -265,9 +270,10 @@ extends: - android - browser isOfficialBuild: ${{ variables.isOfficialBuild }} - extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - extraStepsParameters: - name: MonoRuntimePacks + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: MonoRuntimePacks - template: /eng/pipelines/common/platform-matrix.yml parameters: @@ -295,9 +301,10 @@ extends: - ios - maccatalyst isOfficialBuild: ${{ variables.isOfficialBuild }} - extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - extraStepsParameters: - name: MonoRuntimePacks + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: MonoRuntimePacks # # Build Mono LLVM runtime packs @@ -325,9 +332,10 @@ extends: nameSuffix: AllSubsets_Mono_LLVMJIT runtimeVariant: LLVMJIT isOfficialBuild: ${{ variables.isOfficialBuild }} - extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - extraStepsParameters: - name: MonoRuntimePacks + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: MonoRuntimePacks #LLVMAOT - jobTemplate: /eng/pipelines/common/global-build-job.yml buildConfig: release @@ -338,9 +346,10 @@ extends: nameSuffix: AllSubsets_Mono_LLVMAOT runtimeVariant: LLVMAOT isOfficialBuild: ${{ variables.isOfficialBuild }} - extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - extraStepsParameters: - name: MonoRuntimePacks + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: MonoRuntimePacks # # Build libraries using live CoreLib from CoreCLR @@ -395,9 +404,10 @@ extends: - SourceBuild_linux_x64 jobParameters: nameSuffix: PortableSourceBuild - extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - extraStepsParameters: - name: SourceBuildPackages + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: SourceBuildPackages timeoutInMinutes: 95 # diff --git a/eng/pipelines/runtime-sanitized.yml b/eng/pipelines/runtime-sanitized.yml index 3bc49fec690830..5db421762ed0d4 100644 --- a/eng/pipelines/runtime-sanitized.yml +++ b/eng/pipelines/runtime-sanitized.yml @@ -38,13 +38,14 @@ extends: buildArgs: -s clr+libs -c $(_BuildConfig) $(_nativeSanitizersArg) timeoutInMinutes: 300 # extra steps, run tests - extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig) - scenarios: - - normal - - no_tiered_compilation + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig) + scenarios: + - normal + - no_tiered_compilation extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml parameters: @@ -72,12 +73,13 @@ extends: buildArgs: -s clr+libs+libs.tests -c $(_BuildConfig) -rc Checked $(_nativeSanitizersArg) /p:ArchiveTests=true timeoutInMinutes: 180 # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Libraries_$(_BuildConfig) - scenarios: - - normal + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Libraries_$(_BuildConfig) + scenarios: + - normal # # NativeAOT release build and smoke tests with AddressSanitizer @@ -98,11 +100,12 @@ extends: timeoutInMinutes: 120 nameSuffix: NativeAOT buildArgs: -s clr.aot+host.native+libs -rc $(_BuildConfig) -lc Release -hc Release $(_nativeSanitizersArg) - extraStepsTemplate: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml - extraStepsParameters: - creator: dotnet-bot - testBuildArgs: nativeaot tree nativeaot - liveLibrariesBuildConfig: Release + postBuildSteps: + - template: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml + parameters: + creator: dotnet-bot + testBuildArgs: nativeaot tree nativeaot + liveLibrariesBuildConfig: Release extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml parameters: diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index f2657982aee552..c83a76993e60d6 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -103,9 +103,10 @@ extends: testGroup: innerloop nameSuffix: Native_GCC buildArgs: -s clr.native+libs.native+mono+host.native -c $(_BuildConfig) -gcc - extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests.yml - extraStepsParameters: - testBuildArgs: skipmanaged skipgeneratelayout skiprestorepackages -gcc + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests.yml + parameters: + testBuildArgs: skipmanaged skipgeneratelayout skiprestorepackages -gcc condition: >- or( eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), @@ -249,12 +250,13 @@ extends: timeoutInMinutes: 120 nameSuffix: NativeAOT buildArgs: -s clr.aot+host.native+libs -rc $(_BuildConfig) -lc Release -hc Release - extraStepsTemplate: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml - extraStepsParameters: - creator: dotnet-bot - testBuildArgs: nativeaot tree nativeaot - liveLibrariesBuildConfig: Release - testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml + parameters: + creator: dotnet-bot + testBuildArgs: nativeaot tree nativeaot + liveLibrariesBuildConfig: Release + testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml parameters: @@ -286,12 +288,13 @@ extends: timeoutInMinutes: 180 nameSuffix: NativeAOT buildArgs: -s clr.aot+host.native+libs -rc $(_BuildConfig) -lc Release -hc Release - extraStepsTemplate: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml - extraStepsParameters: - creator: dotnet-bot - testBuildArgs: 'nativeaot tree ";nativeaot;Loader;Interop;tracing;" /p:BuildNativeAotFrameworkObjects=true' - liveLibrariesBuildConfig: Release - testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml + parameters: + creator: dotnet-bot + testBuildArgs: 'nativeaot tree ";nativeaot;Loader;Interop;tracing;" /p:BuildNativeAotFrameworkObjects=true' + liveLibrariesBuildConfig: Release + testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml parameters: @@ -329,12 +332,13 @@ extends: timeoutInMinutes: 120 nameSuffix: NativeAOT buildArgs: -s clr.aot+host.native+libs+tools.illink -c $(_BuildConfig) -rc $(_BuildConfig) -lc Release -hc Release - extraStepsTemplate: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml - extraStepsParameters: - creator: dotnet-bot - testBuildArgs: 'nativeaot tree ";nativeaot;tracing/eventpipe/providervalidation;"' - liveLibrariesBuildConfig: Release - testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml + parameters: + creator: dotnet-bot + testBuildArgs: 'nativeaot tree ";nativeaot;tracing/eventpipe/providervalidation;"' + liveLibrariesBuildConfig: Release + testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml parameters: @@ -366,10 +370,11 @@ extends: buildArgs: -s clr.aot+host.native+libs+libs.tests -c $(_BuildConfig) /p:TestNativeAot=true /p:RunSmokeTestsOnly=true /p:ArchiveTests=true timeoutInMinutes: 240 # Doesn't actually take long, but we've seen the ARM64 Helix queue often get backlogged for 2+ hours # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) condition: >- or( eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), @@ -627,15 +632,16 @@ extends: eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true), eq(variables['isRollingBuild'], true)) # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) - condition: >- - or( - eq(variables['librariesContainsChange'], true), - eq(variables['monoContainsChange'], true), - eq(variables['isRollingBuild'], true)) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + condition: >- + or( + eq(variables['librariesContainsChange'], true), + eq(variables['monoContainsChange'], true), + eq(variables['isRollingBuild'], true)) # # iOS/tvOS devices - Full AOT + AggressiveTrimming to reduce size @@ -668,16 +674,17 @@ extends: eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true), eq(variables['isRollingBuild'], true)) # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) - extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true - condition: >- - or( - eq(variables['librariesContainsChange'], true), - eq(variables['monoContainsChange'], true), - eq(variables['isRollingBuild'], true)) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true + condition: >- + or( + eq(variables['librariesContainsChange'], true), + eq(variables['monoContainsChange'], true), + eq(variables['isRollingBuild'], true)) # # iOS/tvOS devices @@ -710,16 +717,17 @@ extends: eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true), eq(variables['isRollingBuild'], true)) # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) - extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true - condition: >- - or( - eq(variables['librariesContainsChange'], true), - eq(variables['coreclrContainsChange'], true), - eq(variables['isRollingBuild'], true)) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) + extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true + condition: >- + or( + eq(variables['librariesContainsChange'], true), + eq(variables['coreclrContainsChange'], true), + eq(variables['isRollingBuild'], true)) # # MacCatalyst interp - requires AOT Compilation and Interp flags @@ -753,15 +761,16 @@ extends: eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true), eq(variables['isRollingBuild'], true)) # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) - condition: >- - or( - eq(variables['librariesContainsChange'], true), - eq(variables['monoContainsChange'], true), - eq(variables['isRollingBuild'], true)) + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + condition: >- + or( + eq(variables['librariesContainsChange'], true), + eq(variables['monoContainsChange'], true), + eq(variables['isRollingBuild'], true)) # # Build Mono and Installer on LLVMJIT mode @@ -1073,32 +1082,45 @@ extends: condition: >- eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true) + # + # Build and test libraries for .NET Framework + # - template: /eng/pipelines/common/platform-matrix.yml parameters: - jobTemplate: /eng/pipelines/libraries/build-job.yml + jobTemplate: /eng/pipelines/common/global-build-job.yml buildConfig: Release platforms: - windows_x86 helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml jobParameters: framework: net48 - runTests: true - testScope: innerloop + buildArgs: -s tools+libs+libs.tests -framework net48 -c $(_BuildConfig) -testscope innerloop /p:ArchiveTests=true + nameSuffix: Libraries_NET48 + timeoutInMinutes: 150 + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: NET48_$(_BuildConfig) + extraHelixArguments: /p:BuildTargetFramework=net48 condition: >- or( eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), eq(variables['isRollingBuild'], true)) + # + # Build and test libraries AllConfigurations + # - template: /eng/pipelines/common/platform-matrix.yml parameters: - jobTemplate: /eng/pipelines/libraries/build-job.yml + jobTemplate: /eng/pipelines/common/global-build-job.yml buildConfig: ${{ variables.debugOnPrReleaseOnRolling }} platforms: - windows_x64 jobParameters: - framework: allConfigurations - runTests: true - useHelix: false + buildArgs: -test -s tools+libs+libs.tests -allConfigurations -c $(_BuildConfig) /p:TestAssemblies=false /p:TestPackages=true + nameSuffix: Libraries_AllConfigurations + timeoutInMinutes: 150 condition: >- or( eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), @@ -1294,10 +1316,11 @@ extends: eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true), eq(variables['isRollingBuild'], true)) - extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_Release + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_Release extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml @@ -1329,10 +1352,11 @@ extends: eq(dependencies.evaluate_paths.outputs['SetPathVars_mono_excluding_wasm.containsChange'], true), eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true), eq(variables['isRollingBuild'], true)) - extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_Release + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_Release extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml # @@ -1366,11 +1390,12 @@ extends: eq(dependencies.evaluate_paths.outputs['SetPathVars_mono_excluding_wasm.containsChange'], true), eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true), eq(variables['isRollingBuild'], true)) - extraStepsTemplate: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - extraStepsParameters: - creator: dotnet-bot - llvmAotStepContainer: linux_x64_llvmaot - testRunNamePrefixSuffix: Mono_Release + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + parameters: + creator: dotnet-bot + llvmAotStepContainer: linux_x64_llvmaot + testRunNamePrefixSuffix: Mono_Release extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml @@ -1565,8 +1590,6 @@ extends: - SourceBuild_centos8_x64 jobParameters: nameSuffix: centos8SourceBuild - extraStepsParameters: - name: SourceBuildPackages timeoutInMinutes: 95 condition: eq(variables['isRollingBuild'], true) @@ -1579,7 +1602,5 @@ extends: - SourceBuild_banana24_x64 jobParameters: nameSuffix: banana24SourceBuild - extraStepsParameters: - name: SourceBuildPackages timeoutInMinutes: 95 condition: eq(variables['isRollingBuild'], true) diff --git a/eng/pipelines/runtimelab.yml b/eng/pipelines/runtimelab.yml index a5c4e033433113..7c34126757d739 100644 --- a/eng/pipelines/runtimelab.yml +++ b/eng/pipelines/runtimelab.yml @@ -65,9 +65,10 @@ extends: timeoutInMinutes: 100 testGroup: innerloop buildArgs: -s clr+libs+host+packs -c debug -runtimeConfiguration Checked - extraStepsTemplate: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml - extraStepsParameters: - uploadRuntimeTests: true + postBuildSteps: + - template: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml + parameters: + uploadRuntimeTests: true # # Build with Release config and Release runtimeConfiguration @@ -83,10 +84,11 @@ extends: timeoutInMinutes: 100 isOfficialBuild: ${{ variables.isOfficialBuild }} testGroup: innerloop - extraStepsTemplate: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml - extraStepsParameters: - uploadLibrariesTests: ${{ eq(variables.isOfficialBuild, false) }} - uploadIntermediateArtifacts: false + postBuildSteps: + - template: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml + parameters: + uploadLibrariesTests: ${{ eq(variables.isOfficialBuild, false) }} + uploadIntermediateArtifacts: false ${{ if eq(variables.isOfficialBuild, false) }}: buildArgs: -s clr+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true ${{ if eq(variables.isOfficialBuild, true) }}: @@ -107,11 +109,12 @@ extends: nameSuffix: AllConfigurations buildArgs: -s libs -c $(_BuildConfig) -allConfigurations ${{ if eq(variables.isOfficialBuild, true) }}: - extraStepsTemplate: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml - extraStepsParameters: - uploadIntermediateArtifacts: true - isOfficialBuild: true - librariesBinArtifactName: libraries_bin_official_allconfigurations + postBuildSteps: + - template: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml + parameters: + uploadIntermediateArtifacts: true + isOfficialBuild: true + librariesBinArtifactName: libraries_bin_official_allconfigurations # Installer official builds need to build installers and need the libraries all configurations build - ${{ if eq(variables.isOfficialBuild, true) }}: From 144fc6112ca791e9e24c6d28cfc22a123d5c970e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 11:27:58 -0700 Subject: [PATCH 722/783] Remove dead code in PGO scenarios. (#101649) Co-authored-by: Aaron R Robinson --- src/coreclr/vm/jitinterface.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 1cc6c37e09c227..67e127bf91ea62 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -11881,23 +11881,6 @@ HRESULT CEEJitInfo::allocPgoInstrumentationBySchema( JIT_TO_EE_TRANSITION(); - // We need to know the code size. Typically we can get the code size - // from m_ILHeader. For dynamic methods, m_ILHeader will be NULL, so - // for that case we need to use DynamicResolver to get the code size. - - unsigned codeSize = 0; - if (m_pMethodBeingCompiled->IsDynamicMethod()) - { - unsigned stackSize, ehSize; - CorInfoOptions options; - DynamicResolver * pResolver = m_pMethodBeingCompiled->AsDynamicMethodDesc()->GetResolver(); - pResolver->GetCodeInfo(&codeSize, &stackSize, &options, &ehSize); - } - else - { - codeSize = m_ILHeader->GetCodeSize(); - } - #ifdef FEATURE_PGO hr = PgoManager::allocPgoInstrumentationBySchema(m_pMethodBeingCompiled, pSchema, countSchemaItems, pInstrumentationData); #else From 13a33f146f937737050dd659b0b7d9c1945682ef Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Thu, 2 May 2024 20:31:17 +0200 Subject: [PATCH 723/783] JIT: Track sideness of arrOp in GetCheckedBoundArithInfo (#100968) --- src/coreclr/jit/optcse.cpp | 7 ++++-- src/coreclr/jit/valuenum.cpp | 14 ++++++----- src/coreclr/jit/valuenum.h | 3 ++- .../JitBlue/Runtime_100809/Runtime_100809.cs | 23 +++++++++++++++++++ .../Runtime_100809/Runtime_100809.csproj | 5 ++++ 5 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.csproj diff --git a/src/coreclr/jit/optcse.cpp b/src/coreclr/jit/optcse.cpp index 4e7fc81df64bc1..505352250f4ecd 100644 --- a/src/coreclr/jit/optcse.cpp +++ b/src/coreclr/jit/optcse.cpp @@ -3066,8 +3066,11 @@ class CSE_Heuristic assert(vnStore->IsVNCompareCheckedBoundArith(oldCmpVN)); vnStore->GetCompareCheckedBoundArithInfo(oldCmpVN, &info); - newCmpArgVN = vnStore->VNForFunc(vnStore->TypeOfVN(info.arrOp), (VNFunc)info.arrOper, - info.arrOp, theConservativeVN); + ValueNum arrOp1 = info.arrOpLHS ? info.arrOp : theConservativeVN; + ValueNum arrOp2 = info.arrOpLHS ? theConservativeVN : info.arrOp; + + newCmpArgVN = + vnStore->VNForFunc(vnStore->TypeOfVN(info.arrOp), (VNFunc)info.arrOper, arrOp1, arrOp2); } ValueNum newCmpVN = vnStore->VNForFunc(vnStore->TypeOfVN(oldCmpVN), (VNFunc)info.cmpOper, info.cmpOp, newCmpArgVN); diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index fa60633afbc233..fbc80330eb92f3 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -6576,15 +6576,17 @@ void ValueNumStore::GetCheckedBoundArithInfo(ValueNum vn, CompareCheckedBoundAri bool isOp1CheckedBound = IsVNCheckedBound(funcArith.m_args[1]); if (isOp1CheckedBound) { - info->arrOper = funcArith.m_func; - info->arrOp = funcArith.m_args[0]; - info->vnBound = funcArith.m_args[1]; + info->arrOper = funcArith.m_func; + info->arrOp = funcArith.m_args[0]; + info->vnBound = funcArith.m_args[1]; + info->arrOpLHS = true; } else { - info->arrOper = funcArith.m_func; - info->arrOp = funcArith.m_args[1]; - info->vnBound = funcArith.m_args[0]; + info->arrOper = funcArith.m_func; + info->arrOp = funcArith.m_args[1]; + info->vnBound = funcArith.m_args[0]; + info->arrOpLHS = false; } } diff --git a/src/coreclr/jit/valuenum.h b/src/coreclr/jit/valuenum.h index 04fed7bfbc1f67..af6ba52901483f 100644 --- a/src/coreclr/jit/valuenum.h +++ b/src/coreclr/jit/valuenum.h @@ -920,9 +920,10 @@ class ValueNumStore ValueNum vnBound; unsigned arrOper; ValueNum arrOp; + bool arrOpLHS; // arrOp is on the left side of cmpOp expression unsigned cmpOper; ValueNum cmpOp; - CompareCheckedBoundArithInfo() : vnBound(NoVN), arrOper(GT_NONE), arrOp(NoVN), cmpOper(GT_NONE), cmpOp(NoVN) + CompareCheckedBoundArithInfo() : vnBound(NoVN), arrOper(GT_NONE), arrOp(NoVN), arrOpLHS(false), cmpOper(GT_NONE), cmpOp(NoVN) { } #ifdef DEBUG diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.cs b/src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.cs new file mode 100644 index 00000000000000..e7c94f11ac2dc0 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public static class Runtime_100809 +{ + [Fact] + public static int TestEntryPoint() + { + return AlwaysFalse(96) ? -1 : 100; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool AlwaysFalse(int x) + { + var result = new byte[x]; + int count = result.Length - 2; + return (x < 0 || result.Length - count < 0); + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.csproj new file mode 100644 index 00000000000000..197767e2c4e249 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.csproj @@ -0,0 +1,5 @@ + + + + + From 40804203a22be83c5a13bb85230718257dbb7ad8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 12:36:32 -0700 Subject: [PATCH 724/783] Revert "disable optimizations for PopCount (#99796)" (#101245) This reverts commit aee49579769188d0ff7cf3ca872d2126e5bb3c70. Co-authored-by: Manish Godse <61718172+mangod9@users.noreply.github.com> --- src/coreclr/jit/utils.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index 4c9fe6479eca41..2e1c0a52a3d81b 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -3192,11 +3192,6 @@ uint32_t BitOperations::Log2(uint64_t value) // Return Value: // The population count (number of bits set) of value // -#if defined(_MSC_VER) -// Disable optimizations for PopCount to avoid the compiler from generating intrinsics -// not supported on all platforms. -#pragma optimize("", off) -#endif // _MSC_VER uint32_t BitOperations::PopCount(uint32_t value) { #if defined(_MSC_VER) @@ -3249,9 +3244,6 @@ uint32_t BitOperations::PopCount(uint64_t value) return static_cast(result); #endif } -#if defined(_MSC_VER) -#pragma optimize("", on) -#endif // _MSC_VER //------------------------------------------------------------------------ // BitOperations::ReverseBits: Reverses the bits in an integer value From 70f51120fde46628c497d383cecfa3992682dc8e Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 2 May 2024 16:54:30 -0400 Subject: [PATCH 725/783] Add cryptographic operation counts to prevent process crashes --- .../src/Resources/Strings.resx | 3 + .../src/System.Security.Cryptography.csproj | 2 + .../Cryptography/ConcurrencyBlock.NoOp.cs | 25 +++++++ .../Security/Cryptography/ConcurrencyBlock.cs | 40 +++++++++++ .../HashProviderDispenser.OpenSsl.cs | 66 +++++++++++++------ 5 files changed, 116 insertions(+), 20 deletions(-) create mode 100644 src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ConcurrencyBlock.NoOp.cs create mode 100644 src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ConcurrencyBlock.cs diff --git a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx index 1bd529a087a6ac..4bcfdcfd3454fc 100644 --- a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx @@ -273,6 +273,9 @@ The specified CipherMode '{0}' is not supported. + + Concurrent operations from multiple threads on this type are not supported. + This key is for algorithm '{0}'. Expected '{1}'. diff --git a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj index 691235d0de2902..591ae21cfd716d 100644 --- a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj +++ b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj @@ -817,6 +817,7 @@ + @@ -977,6 +978,7 @@ + diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ConcurrencyBlock.NoOp.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ConcurrencyBlock.NoOp.cs new file mode 100644 index 00000000000000..18736cacfc2734 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ConcurrencyBlock.NoOp.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading; + +namespace System.Security.Cryptography +{ + internal struct ConcurrencyBlock + { + internal static Scope Enter(ref ConcurrencyBlock block) + { + _ = block; + return default; + } + + internal ref struct Scope + { +#pragma warning disable CA1822 // Member can be marked static + internal void Dispose() + { + } +#pragma warning restore CA1822 + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ConcurrencyBlock.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ConcurrencyBlock.cs new file mode 100644 index 00000000000000..c0eafe849da906 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ConcurrencyBlock.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading; + +namespace System.Security.Cryptography +{ + internal struct ConcurrencyBlock + { + private int _count; + + internal static Scope Enter(ref ConcurrencyBlock block) + { + int count = Interlocked.Increment(ref block._count); + + if (count != 1) + { + Interlocked.Decrement(ref block._count); + throw new CryptographicException(SR.Cryptography_ConcurrentUseNotSupported); + } + + return new Scope(ref block._count); + } + + internal ref struct Scope + { + private ref int _parentCount; + + internal Scope(ref int parentCount) + { + _parentCount = ref parentCount; + } + + internal void Dispose() + { + Interlocked.Decrement(ref _parentCount); + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs index a048496fc3f789..ef15a1736b6bc6 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.OpenSsl.cs @@ -102,6 +102,7 @@ private sealed class EvpHashProvider : HashProvider { private readonly LiteHash _liteHash; private bool _running; + private ConcurrencyBlock _block; public EvpHashProvider(string hashAlgorithmId) { @@ -110,21 +111,30 @@ public EvpHashProvider(string hashAlgorithmId) public override void AppendHashData(ReadOnlySpan data) { - _liteHash.Append(data); - _running = true; + using (ConcurrencyBlock.Enter(ref _block)) + { + _liteHash.Append(data); + _running = true; + } } public override int FinalizeHashAndReset(Span destination) { - int written = _liteHash.Finalize(destination); - _liteHash.Reset(); - _running = false; - return written; + using (ConcurrencyBlock.Enter(ref _block)) + { + int written = _liteHash.Finalize(destination); + _liteHash.Reset(); + _running = false; + return written; + } } public override int GetCurrentHash(Span destination) { - return _liteHash.Current(destination); + using (ConcurrencyBlock.Enter(ref _block)) + { + return _liteHash.Current(destination); + } } public override int HashSizeInBytes => _liteHash.HashSizeInBytes; @@ -139,10 +149,13 @@ public override void Dispose(bool disposing) public override void Reset() { - if (_running) + using (ConcurrencyBlock.Enter(ref _block)) { - _liteHash.Reset(); - _running = false; + if (_running) + { + _liteHash.Reset(); + _running = false; + } } } } @@ -151,6 +164,7 @@ private sealed class HmacHashProvider : HashProvider { private readonly LiteHmac _liteHmac; private bool _running; + private ConcurrencyBlock _block; public HmacHashProvider(string hashAlgorithmId, ReadOnlySpan key) { @@ -159,21 +173,30 @@ public HmacHashProvider(string hashAlgorithmId, ReadOnlySpan key) public override void AppendHashData(ReadOnlySpan data) { - _liteHmac.Append(data); - _running = true; + using (ConcurrencyBlock.Enter(ref _block)) + { + _liteHmac.Append(data); + _running = true; + } } public override int FinalizeHashAndReset(Span destination) { - int written = _liteHmac.Finalize(destination); - _liteHmac.Reset(); - _running = false; - return written; + using (ConcurrencyBlock.Enter(ref _block)) + { + int written = _liteHmac.Finalize(destination); + _liteHmac.Reset(); + _running = false; + return written; + } } public override int GetCurrentHash(Span destination) { - return _liteHmac.Current(destination); + using (ConcurrencyBlock.Enter(ref _block)) + { + return _liteHmac.Current(destination); + } } public override int HashSizeInBytes => _liteHmac.HashSizeInBytes; @@ -188,10 +211,13 @@ public override void Dispose(bool disposing) public override void Reset() { - if (_running) + using (ConcurrencyBlock.Enter(ref _block)) { - _liteHmac.Reset(); - _running = false; + if (_running) + { + _liteHmac.Reset(); + _running = false; + } } } } From 4021666c9a7e528dc4897955f76c44e7e16dc7e9 Mon Sep 17 00:00:00 2001 From: Michael Simons Date: Thu, 2 May 2024 16:16:36 -0500 Subject: [PATCH 726/783] Revert "Enable repackaging of NETStandard 2.1 Targeting Pack (#101518)" (#101812) This reverts commit c67a2e4216e156f4129638d71ea99a6a731106ed. --- eng/Subsets.props | 1 - eng/Versions.props | 8 --- src/installer/pkg/sfx/installers.proj | 4 -- .../pkg/sfx/installers/netstandard2.1.proj | 60 ------------------- 4 files changed, 73 deletions(-) delete mode 100644 src/installer/pkg/sfx/installers/netstandard2.1.proj diff --git a/eng/Subsets.props b/eng/Subsets.props index 00ae8a31c58cf1..a35f99ef759b7d 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -507,7 +507,6 @@ - diff --git a/eng/Versions.props b/eng/Versions.props index 92d5aeedb2d438..9ef3967e0ed5f5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -260,12 +260,4 @@ 8.0.101 $(MicrosoftDotnetSdkInternalVersion) - - - true - diff --git a/src/installer/pkg/sfx/installers.proj b/src/installer/pkg/sfx/installers.proj index 2f947e6d9e291e..7f4ce6b9c1c409 100644 --- a/src/installer/pkg/sfx/installers.proj +++ b/src/installer/pkg/sfx/installers.proj @@ -22,10 +22,6 @@ - - - - - - true - true - netstandard-targeting-pack-2.1 - NETStandard.Library.Ref - NETStandard.Library.Ref 2.1.0 - false - ToolPack - true - netstandard-targeting-pack-2.1.0-x64.rpm - https://dotnetcli.blob.core.windows.net/dotnet/Runtime/3.1.0/$(OriginalNETStandard21PkgFilename) - $([MSBuild]::NormalizeDirectory('$(BaseIntermediateOutputPath)', 'download')) - $(NETStandard21TempDir)$(OriginalNETStandard21PkgFilename) - $(NETStandard21TempDir)netstandard21.semaphore - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From affe9fc3a8ee9b537ff9d9d63aa863f208ed1ed1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 15:09:13 -0700 Subject: [PATCH 727/783] Update dependencies from https://github.com/dotnet/emsdk build 20240502.3 (#101817) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.5-servicing.24215.1 -> To Version 8.0.6-servicing.24252.3 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/NuGet.config b/NuGet.config index e768edae2abb39..58277f76a142da 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index be70162daab100..c2d1b0ca3f6dd6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,13 +90,13 @@ 45dd3a73dd5b64b010c4251303b3664bb30df029 - + https://github.com/dotnet/emsdk - 6a06b5454e26309fe4ec786857853056c2c541e0 + a1cd44fdc64aa1f1c4630ddcd95580800d229180 - + https://github.com/dotnet/emsdk - 6a06b5454e26309fe4ec786857853056c2c541e0 + a1cd44fdc64aa1f1c4630ddcd95580800d229180 diff --git a/eng/Versions.props b/eng/Versions.props index 9ef3967e0ed5f5..fcd7ee550f6e18 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.5 + 8.0.6 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda From 783771d6acf9b3e656b9392bd53301f999428e67 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Thu, 2 May 2024 20:15:35 -0500 Subject: [PATCH 728/783] Pin net7.0 to 7.0.19 (#101823) --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index fcd7ee550f6e18..ba8e464d4f35ec 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,8 +7,8 @@ 0 6 8.0.100 - 7.0.$([MSBuild]::Add($(PatchVersion),14)) - 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) + 7.0.19 + 6.0.$([MSBuild]::Add($(PatchVersion),25)) servicing From fa5b0d8f4a8b424732cc992158aa92842f8a2846 Mon Sep 17 00:00:00 2001 From: Eirik George Tsarpalis Date: Fri, 3 May 2024 14:36:33 +0000 Subject: [PATCH 729/783] Merged PR 39242: Add a fallback to filling buffers in DeserializeAsyncEnumerable. Fix https://dev.azure.com/devdiv/DevDiv/_workitems/edit/2017927 Recreated from https://dev.azure.com/dnceng/internal/_git/dotnet-runtime/pullrequest/38745 --- eng/Versions.props | 2 + .../Microsoft.NET.HostModel.csproj | 2 +- ...icrosoft.Extensions.DependencyModel.csproj | 2 + .../src/System.Text.Json.csproj | 4 +- .../Json/Serialization/ReadBufferState.cs | 25 +++++- .../Stream.DeserializeAsyncEnumerable.cs | 86 +++++++++++++++++++ 6 files changed, 117 insertions(+), 4 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index ba8e464d4f35ec..15d6cacdfdf0b7 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -136,6 +136,8 @@ 5.0.0 5.0.0 7.0.0 + + 7.0.3 8.0.0-rc.1.23406.6 6.0.0 7.0.0 diff --git a/src/installer/managed/Microsoft.NET.HostModel/Microsoft.NET.HostModel.csproj b/src/installer/managed/Microsoft.NET.HostModel/Microsoft.NET.HostModel.csproj index de2e9ac36a7949..3eb55ac664eea2 100644 --- a/src/installer/managed/Microsoft.NET.HostModel/Microsoft.NET.HostModel.csproj +++ b/src/installer/managed/Microsoft.NET.HostModel/Microsoft.NET.HostModel.csproj @@ -22,7 +22,7 @@ - + diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj b/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj index 6cd3d26b2b6f63..9cb379a7ad24d8 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj @@ -3,6 +3,8 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true true + true + 1 Provides abstractions for reading `.deps` files. When a .NET application is compiled, the SDK generates a JSON manifest file (`<ApplicationName>.deps.json`) that contains information about application dependencies. You can use `Microsoft.Extensions.DependencyModel` to read information from this manifest at run time. This is useful when you want to dynamically compile code (for example, using Roslyn Emit API) referencing the same dependencies as your main application. By default, the dependency manifest contains information about the application's target framework and runtime dependencies. Set the PreserveCompilationContext project property to `true` to additionally include information about reference assemblies used during compilation. diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index 10d8f70c130538..bb62fa90611143 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -8,8 +8,8 @@ CS8969 true true - false - 3 + true + 4 Provides high-performance and low-allocating types that serialize objects to JavaScript Object Notation (JSON) text and deserialize JSON text to objects, with UTF-8 support built-in. Also provides types to read and write JSON text encoded as UTF-8, and to create an in-memory document object model (DOM), that is read-only, for random access of the JSON elements within a structured view of the data. The System.Text.Json library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs index c84c00a35247af..8107fa5edbdb38 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs @@ -20,6 +20,27 @@ internal struct ReadBufferState : IDisposable private bool _isFirstBlock; private bool _isFinalBlock; + // An "unsuccessful read" in this context refers to a buffer read operation that + // wasn't sufficient to advance the reader to the next token. This occurs primarily + // when consuming large JSON strings (which don't support streaming today) but is + // also possible with other token types such as numbers, booleans, or nulls. + // + // The JsonSerializer.DeserializeAsyncEnumerable methods employ a special buffering + // strategy where rather than attempting to fill the entire buffer, the deserializer + // will be invoked as soon as the first chunk of data is read from the stream. + // This is to ensure liveness: data should be surfaced on the IAE as soon as they + // are streamed from the server. On the other hand, this can create performance + // problems in cases where the underlying stream uses extremely fine-grained buffering. + // For this reason, we employ a threshold that will revert to buffer filling once crossed. + // The counter is reset to zero whenever the JSON reader has been advanced successfully. + // + // The threshold is set to 5 unsuccessful reads. This is a relatively conservative threshold + // but should still make fallback unlikely in most scenaria. It should ensure that fallback + // isn't triggered in null or boolean tokens even in the worst-case scenario where they are + // streamed one byte at a time. + private const int UnsuccessfulReadCountThreshold = 5; + private int _unsuccessfulReadCount; + public ReadBufferState(int initialBufferSize) { _buffer = ArrayPool.Shared.Rent(Math.Max(initialBufferSize, JsonConstants.Utf8Bom.Length)); @@ -46,6 +67,7 @@ public readonly async ValueTask ReadFromStreamAsync( // make all updates on a copy which is returned once complete. ReadBufferState bufferState = this; + int minBufferCount = fillBuffer || _unsuccessfulReadCount > UnsuccessfulReadCountThreshold ? bufferState._buffer.Length : 0; do { int bytesRead = await utf8Json.ReadAsync( @@ -64,7 +86,7 @@ public readonly async ValueTask ReadFromStreamAsync( bufferState._count += bytesRead; } - while (fillBuffer && bufferState._count < bufferState._buffer.Length); + while (bufferState._count < minBufferCount); bufferState.ProcessReadBytes(); return bufferState; @@ -107,6 +129,7 @@ public void AdvanceBuffer(int bytesConsumed) Debug.Assert(bytesConsumed <= _count); Debug.Assert(!_isFinalBlock || _count == bytesConsumed, "The reader should have thrown if we have remaining bytes."); + _unsuccessfulReadCount = bytesConsumed == 0 ? _unsuccessfulReadCount + 1 : 0; _count -= bytesConsumed; if (!_isFinalBlock) diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs index aa578a51e9c8ec..ee6da9261a204a 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; using System.IO; using System.Linq; using System.Text.Json.Serialization.Metadata; @@ -228,6 +230,47 @@ await Assert.ThrowsAsync(async () => }); } + [Theory] + [InlineData(5, 1024)] + [InlineData(5, 1024 * 1024)] + public static async Task DeserializeAsyncEnumerable_SlowStreamWithLargeStrings(int totalStrings, int stringLength) + { + var options = new JsonSerializerOptions + { + Converters = { new StringLengthConverter() } + }; + + using var stream = new SlowStream(GenerateJsonCharacters()); + string expectedElement = stringLength.ToString(CultureInfo.InvariantCulture); + IAsyncEnumerable asyncEnumerable = JsonSerializer.DeserializeAsyncEnumerable(stream, options); + + await foreach (string? value in asyncEnumerable) + { + Assert.Equal(expectedElement, value); + } + + IEnumerable GenerateJsonCharacters() + { + // ["xxx...x","xxx...x",...,"xxx...x"] + yield return (byte)'['; + for (int i = 0; i < totalStrings; i++) + { + yield return (byte)'"'; + for (int j = 0; j < stringLength; j++) + { + yield return (byte)'x'; + } + yield return (byte)'"'; + + if (i < totalStrings - 1) + { + yield return (byte)','; + } + } + yield return (byte)']'; + } + } + public static IEnumerable GetAsyncEnumerableSources() { yield return WrapArgs(Enumerable.Empty(), 1, DeserializeAsyncEnumerableOverload.JsonSerializerOptions); @@ -276,5 +319,48 @@ private static async Task> ToListAsync(this IAsyncEnumerable sourc } return list; } + + private sealed class SlowStream(IEnumerable byteSource) : Stream, IDisposable + { + private readonly IEnumerator _enumerator = byteSource.GetEnumerator(); + private long _position; + + public override bool CanRead => true; + public override int Read(byte[] buffer, int offset, int count) + { + Debug.Assert(buffer != null); + Debug.Assert(offset >= 0 && count <= buffer.Length - offset); + + if (count == 0 || !_enumerator.MoveNext()) + { + return 0; + } + + _position++; + buffer[offset] = _enumerator.Current; + return 1; + } + + public override bool CanSeek => false; + public override bool CanWrite => false; + public override long Position { get => _position; set => throw new NotSupportedException(); } + public override long Length => throw new NotSupportedException(); + public override void Flush() => throw new NotSupportedException(); + public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException(); + public override void SetLength(long value) => throw new NotSupportedException(); + public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException(); + void IDisposable.Dispose() => _enumerator.Dispose(); + } + + private sealed class StringLengthConverter : JsonConverter + { + public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + Debug.Assert(!reader.ValueIsEscaped && !reader.HasValueSequence); + return reader.ValueSpan.Length.ToString(CultureInfo.InvariantCulture); + } + + public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) => throw new NotImplementedException(); + } } } From 0fdb1335fd9f7fa59552626037c8aa41d06c980b Mon Sep 17 00:00:00 2001 From: Eduardo Velarde <32459232+eduardo-vp@users.noreply.github.com> Date: Fri, 10 May 2024 11:34:14 -0700 Subject: [PATCH 730/783] [release/8.0-staging] Transition to 1ES templates work (Backport crossgen2 changes) (#101869) * Add check for tizen in ilc and crossgen2 (#90310) * Enable trimming for crossgen2 publishing and fix symbol bug (#91135) * Use a different crossgen2 when running crossgen2 during our build than the crossgen2 that we are shipping (#92677) * Remove explicit listing of RIDs to avoid trying to restore the runtime packs for all possible targets. Use the local targeting and runtime packs explicitly to make sure we're publishing crossgen2 with the local build. Extracted from https://github.com/dotnet/runtime/pull/92826 --------- Co-authored-by: Aleksandr Shaurtaev <38426614+ashaurtaev@users.noreply.github.com> Co-authored-by: Andy Gocke Co-authored-by: Jeremy Koritzinsky Co-authored-by: Jeremy Koritzinsky --- eng/Subsets.props | 2 +- eng/targetingpacks.targets | 6 +- src/coreclr/crossgen-corelib.proj | 3 +- .../tools/aot/ILCompiler/ILCompiler.csproj | 1 + .../tools/aot/crossgen2/crossgen2.csproj | 119 ++---------------- .../tools/aot/crossgen2/crossgen2.props | 1 - .../aot/crossgen2/crossgen2_crossarch.csproj | 8 -- .../aot/crossgen2/crossgen2_inbuild.csproj | 9 ++ .../aot/crossgen2/crossgen2_publish.csproj | 105 ++++++++++++++++ .../Microsoft.NETCore.App.Crossgen2.sfxproj | 42 +++---- .../Microsoft.NETCore.App/ReadyToRun.targets | 4 +- 11 files changed, 147 insertions(+), 153 deletions(-) delete mode 100644 src/coreclr/tools/aot/crossgen2/crossgen2_crossarch.csproj create mode 100644 src/coreclr/tools/aot/crossgen2/crossgen2_inbuild.csproj create mode 100644 src/coreclr/tools/aot/crossgen2/crossgen2_publish.csproj diff --git a/eng/Subsets.props b/eng/Subsets.props index a35f99ef759b7d..69924723836c21 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -342,7 +342,7 @@ - + diff --git a/eng/targetingpacks.targets b/eng/targetingpacks.targets index b3ad8560d63b1c..e9ca4e11615267 100644 --- a/eng/targetingpacks.targets +++ b/eng/targetingpacks.targets @@ -35,7 +35,7 @@ LatestRuntimeFrameworkVersion="$(ProductVersion)" RuntimeFrameworkName="$(LocalFrameworkOverrideName)" RuntimePackNamePatterns="$(LocalFrameworkOverrideName).Runtime.**RID**" - RuntimePackRuntimeIdentifiers="linux-arm;linux-arm64;linux-musl-arm64;linux-musl-x64;linux-x64;osx-x64;rhel.6-x64;tizen.4.0.0-armel;tizen.5.0.0-armel;win-arm64;win-x64;win-x86;linux-musl-arm;osx-arm64;maccatalyst-x64;maccatalyst-arm64;linux-s390x;linux-bionic-arm;linux-bionic-arm64;linux-bionic-x64;linux-bionic-x86" + RuntimePackRuntimeIdentifiers="linux-arm;linux-arm64;linux-musl-arm64;linux-musl-x64;linux-x64;osx-x64;rhel.6-x64;tizen.4.0.0-armel;tizen.5.0.0-armel;win-arm64;win-x64;win-x86;linux-musl-arm;osx-arm64;maccatalyst-x64;maccatalyst-arm64;linux-s390x;linux-bionic-arm;linux-bionic-arm64;linux-bionic-x64;linux-bionic-x86;freebsd-x64;freebsd-arm64" TargetFramework="$(NetCoreAppCurrent)" TargetingPackName="$(LocalFrameworkOverrideName).Ref" TargetingPackVersion="$(ProductVersion)" @@ -104,6 +104,10 @@ Condition="'$(UsePackageDownload)' == 'true' and $([System.String]::Copy('%(Identity)').StartsWith('$(LocalFrameworkOverrideName).Runtime'))" /> + + - - + diff --git a/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj b/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj index 7c25444f209c33..c0a239225fa3e7 100644 --- a/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj +++ b/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj @@ -12,6 +12,7 @@ $(RuntimeBinDir)ilc-published/ false + false false true diff --git a/src/coreclr/tools/aot/crossgen2/crossgen2.csproj b/src/coreclr/tools/aot/crossgen2/crossgen2.csproj index ef1b82f537fbfd..6f8578b26b9691 100644 --- a/src/coreclr/tools/aot/crossgen2/crossgen2.csproj +++ b/src/coreclr/tools/aot/crossgen2/crossgen2.csproj @@ -1,113 +1,14 @@ - - - - + - $(RuntimeBinDir)crossgen2 - - false - - true - linux-x64;linux-musl-x64;linux-arm;linux-musl-arm;linux-arm64;linux-musl-arm64;freebsd-x64;freebsd-arm64;osx-x64;osx-arm64;win-x64;win-x86;win-arm64 - $(PackageRID) - false - true + $(RuntimeBinDir)/crossgen2 + false + + $(NetCoreAppToolCurrent) - - - - true - true - - false - - false - true - - - - - - $(CoreCLRILCompilerDir) - $(CoreCLRCrossILCompilerDir) - $(ROOTFS_DIR) - $(CoreCLRILCompilerDir)netstandard/ILCompiler.Build.Tasks.dll - $(CoreCLRAotSdkDir) - $(MicrosoftNetCoreAppRuntimePackRidLibTfmDir) - $(MicrosoftNetCoreAppRuntimePackNativeDir) - false - - .dwarf - --flat - - - - - - - - - - - - - - - - - $(MicrosoftNetCoreAppRuntimePackDir) - - - - - - - - - $(RuntimeIdentifier) - - - x86_64 - aarch64 - arm64 - - - $(CrossCompileArch)-linux-gnu - $(CrossCompileArch)-alpine-linux-musl - $(CrossCompileArch)-unknown-freebsd12 - - - - - - - - - - clang - - - - - - - - $(_CC_LDFLAGS.SubString(0, $(_CC_LDFLAGS.IndexOf(';')))) - <_LDFLAGS>$(_CC_LDFLAGS.SubString($([MSBuild]::Add($(_CC_LDFLAGS.IndexOf(';')), 1)))) - lld - - - diff --git a/src/coreclr/tools/aot/crossgen2/crossgen2.props b/src/coreclr/tools/aot/crossgen2/crossgen2.props index 0f2f954c6a1544..4d5cc30c3bb604 100644 --- a/src/coreclr/tools/aot/crossgen2/crossgen2.props +++ b/src/coreclr/tools/aot/crossgen2/crossgen2.props @@ -3,7 +3,6 @@ crossgen2 true Exe - $(NetCoreAppToolCurrent) 8002,NU1701 x64;x86;arm64;arm;loongarch64 AnyCPU diff --git a/src/coreclr/tools/aot/crossgen2/crossgen2_crossarch.csproj b/src/coreclr/tools/aot/crossgen2/crossgen2_crossarch.csproj deleted file mode 100644 index 544b4271117b5f..00000000000000 --- a/src/coreclr/tools/aot/crossgen2/crossgen2_crossarch.csproj +++ /dev/null @@ -1,8 +0,0 @@ - - - $(BuildArchitecture) - $(RuntimeBinDir)/$(CrossHostArch)/crossgen2 - false - - - diff --git a/src/coreclr/tools/aot/crossgen2/crossgen2_inbuild.csproj b/src/coreclr/tools/aot/crossgen2/crossgen2_inbuild.csproj new file mode 100644 index 00000000000000..75766fd75eabde --- /dev/null +++ b/src/coreclr/tools/aot/crossgen2/crossgen2_inbuild.csproj @@ -0,0 +1,9 @@ + + + $(BuildArchitecture) + $(RuntimeBinDir)/$(BuildArchitecture)/crossgen2 + false + $(NetCoreAppToolCurrent) + + + diff --git a/src/coreclr/tools/aot/crossgen2/crossgen2_publish.csproj b/src/coreclr/tools/aot/crossgen2/crossgen2_publish.csproj new file mode 100644 index 00000000000000..d5105eccff36de --- /dev/null +++ b/src/coreclr/tools/aot/crossgen2/crossgen2_publish.csproj @@ -0,0 +1,105 @@ + + + + + + false + false + true + $(PackageRID) + true + $(NetCoreAppCurrent) + true + true + + + + + + true + true + + false + + false + true + + + + + + + + + + + + + $(CoreCLRILCompilerDir) + $(CoreCLRCrossILCompilerDir) + $(ROOTFS_DIR) + $(CoreCLRILCompilerDir)netstandard/ILCompiler.Build.Tasks.dll + $(CoreCLRAotSdkDir) + $(MicrosoftNetCoreAppRuntimePackRidLibTfmDir) + $(MicrosoftNetCoreAppRuntimePackNativeDir) + false + + .dwarf + --flat + + + + + + + + + + + + + + + $(RuntimeIdentifier) + + + x86_64 + aarch64 + arm64 + + + $(CrossCompileArch)-linux-gnu + $(CrossCompileArch)-alpine-linux-musl + $(CrossCompileArch)-unknown-freebsd12 + + + + + + + + + + clang + + + + + + + + $(_CC_LDFLAGS.SubString(0, $(_CC_LDFLAGS.IndexOf(';')))) + <_LDFLAGS>$(_CC_LDFLAGS.SubString($([MSBuild]::Add($(_CC_LDFLAGS.IndexOf(';')), 1)))) + lld + + + + diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Crossgen2.sfxproj b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Crossgen2.sfxproj index e8e8591bbaf8b5..a95eb81b9317fb 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Crossgen2.sfxproj +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Crossgen2.sfxproj @@ -28,36 +28,22 @@ + + + + - - - - - - - - - - <_CrossgenPublishFiles Include="@(_RawCrossgenPublishFiles->'%(OutputPath)')" KeepMetadata="REMOVE_ALL" /> diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/ReadyToRun.targets b/src/installer/pkg/sfx/Microsoft.NETCore.App/ReadyToRun.targets index 0b82891e6c42e4..6b24c54f4c1eb6 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/ReadyToRun.targets +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/ReadyToRun.targets @@ -14,9 +14,7 @@ - - $(BuildArchitecture) - $(CoreCLRArtifactsPath)\$(CrossDir)\crossgen2\crossgen2.dll + $(CoreCLRArtifactsPath)\$(BuildArchitecture)\crossgen2\crossgen2.dll true @(PublishReadyToRunCrossgen2ExtraArgsList) From 76b5685d7ec25a12d1b1abd6a712308bc7699bca Mon Sep 17 00:00:00 2001 From: Radek Zikmund <32671551+rzikm@users.noreply.github.com> Date: Mon, 13 May 2024 22:29:58 +0200 Subject: [PATCH 731/783] [release/8.0] Fix data race leading to a deadlock when opening QuicStream (#102147) * Fix data race leading to a deadlock when opening QuicStream (#101250) * Fix data race leading to a deadlock. * Remove unwanted change * Code review feedback * Fix hang * Add assert * Fix potential crash * Code review feedback * Fix thrown exception. --- .../System/Net/Quic/Internal/ThrowHelper.cs | 27 +++++++++++++++---- .../src/System/Net/Quic/QuicConnection.cs | 23 +++++++++++++--- .../src/System/Net/Quic/QuicStream.cs | 14 +++++++--- 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/ThrowHelper.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/ThrowHelper.cs index ec677f9f4e58d6..e99f5fda640e1d 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/ThrowHelper.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/ThrowHelper.cs @@ -27,13 +27,27 @@ internal static QuicException GetOperationAbortedException(string? message = nul return new QuicException(QuicError.OperationAborted, null, message ?? SR.net_quic_operationaborted); } - internal static bool TryGetStreamExceptionForMsQuicStatus(int status, [NotNullWhen(true)] out Exception? exception) + internal static bool TryGetStreamExceptionForMsQuicStatus(int status, [NotNullWhen(true)] out Exception? exception, bool streamWasSuccessfullyStarted = true, string? message = null) { if (status == QUIC_STATUS_ABORTED) { - // If status == QUIC_STATUS_ABORTED, we will receive an event later, which will complete the task source. - exception = null; - return false; + // Connection has been closed by the peer (either at transport or application level), + if (streamWasSuccessfullyStarted) + { + // we will receive an event later, which will complete the stream with concrete + // information why the connection was aborted. + exception = null; + return false; + } + else + { + // we won't be receiving any event callback for shutdown on this stream, so we don't + // necessarily know which error to report. So we throw an exception which we can distinguish + // at the caller (ConnectionAborted normally has App error code) and throw the correct + // exception from there. + exception = new QuicException(QuicError.ConnectionAborted, null, ""); + return true; + } } else if (status == QUIC_STATUS_INVALID_STATE) { @@ -43,13 +57,16 @@ internal static bool TryGetStreamExceptionForMsQuicStatus(int status, [NotNullWh } else if (StatusFailed(status)) { - exception = GetExceptionForMsQuicStatus(status); + exception = GetExceptionForMsQuicStatus(status, message: message); return true; } exception = null; return false; } + // see TryGetStreamExceptionForMsQuicStatus for explanation + internal static bool IsConnectionAbortedWhenStartingStreamException(Exception ex) => ex is QuicException qe && qe.QuicError == QuicError.ConnectionAborted && qe.ApplicationErrorCode is null; + internal static Exception GetExceptionForMsQuicStatus(int status, long? errorCode = default, string? message = null) { Exception ex = GetExceptionInternal(status, errorCode, message); diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index a2ade033afe59f..13351faaa20c0b 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -98,6 +98,11 @@ static async ValueTask StartConnectAsync(QuicClientConnectionOpt /// private int _disposed; + /// + /// Completed when connection shutdown is initiated. + /// + private TaskCompletionSource _connectionCloseTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + private readonly ValueTaskSource _connectedTcs = new ValueTaskSource(); private readonly ValueTaskSource _shutdownTcs = new ValueTaskSource(); @@ -376,16 +381,22 @@ public async ValueTask OpenOutboundStreamAsync(QuicStreamType type, stream = new QuicStream(_handle, type, _defaultStreamErrorCode); await stream.StartAsync(cancellationToken).ConfigureAwait(false); } - catch + catch (Exception ex) { if (stream is not null) { await stream.DisposeAsync().ConfigureAwait(false); } + + // In case of an incoming race when the connection is closed by the peer just before we open the stream, + // we receive QUIC_STATUS_ABORTED from MsQuic, but we don't know how the connection was closed. We throw + // special exception and handle it here where we can determine the shutdown reason. + bool connectionAbortedByPeer = ThrowHelper.IsConnectionAbortedWhenStartingStreamException(ex); + // Propagate connection error if present. - if (_acceptQueue.Reader.Completion.IsFaulted) + if (_connectionCloseTcs.Task.IsFaulted || connectionAbortedByPeer) { - await _acceptQueue.Reader.Completion.ConfigureAwait(false); + await _connectionCloseTcs.Task.ConfigureAwait(false); } throw; } @@ -475,17 +486,21 @@ private unsafe int HandleEventShutdownInitiatedByTransport(ref SHUTDOWN_INITIATE { Exception exception = ExceptionDispatchInfo.SetCurrentStackTrace(ThrowHelper.GetExceptionForMsQuicStatus(data.Status, (long)data.ErrorCode)); _connectedTcs.TrySetException(exception); + _connectionCloseTcs.TrySetException(exception); _acceptQueue.Writer.TryComplete(exception); return QUIC_STATUS_SUCCESS; } private unsafe int HandleEventShutdownInitiatedByPeer(ref SHUTDOWN_INITIATED_BY_PEER_DATA data) { - _acceptQueue.Writer.TryComplete(ExceptionDispatchInfo.SetCurrentStackTrace(ThrowHelper.GetConnectionAbortedException((long)data.ErrorCode))); + Exception exception = ExceptionDispatchInfo.SetCurrentStackTrace(ThrowHelper.GetConnectionAbortedException((long)data.ErrorCode)); + _connectionCloseTcs.TrySetException(exception); + _acceptQueue.Writer.TryComplete(exception); return QUIC_STATUS_SUCCESS; } private unsafe int HandleEventShutdownComplete() { Exception exception = ExceptionDispatchInfo.SetCurrentStackTrace(ThrowHelper.GetOperationAbortedException()); + _connectionCloseTcs.TrySetException(exception); _acceptQueue.Writer.TryComplete(exception); _connectedTcs.TrySetException(exception); _shutdownTcs.TrySetResult(); diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicStream.cs index 6165f2085cb5f0..82ee656dc6bdc6 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicStream.cs @@ -161,13 +161,18 @@ internal unsafe QuicStream(MsQuicContextSafeHandle connectionHandle, QuicStreamT try { QUIC_HANDLE* handle; - ThrowHelper.ThrowIfMsQuicError(MsQuicApi.Api.StreamOpen( + int status = MsQuicApi.Api.StreamOpen( connectionHandle, type == QuicStreamType.Unidirectional ? QUIC_STREAM_OPEN_FLAGS.UNIDIRECTIONAL : QUIC_STREAM_OPEN_FLAGS.NONE, &NativeCallback, (void*)GCHandle.ToIntPtr(context), - &handle), - "StreamOpen failed"); + &handle); + + if (ThrowHelper.TryGetStreamExceptionForMsQuicStatus(status, out Exception? ex, streamWasSuccessfullyStarted: false, message: "StreamOpen failed")) + { + throw ex; + } + _handle = new MsQuicContextSafeHandle(handle, context, SafeHandleType.Stream, connectionHandle); } catch @@ -241,7 +246,8 @@ internal ValueTask StartAsync(CancellationToken cancellationToken = default) int status = MsQuicApi.Api.StreamStart( _handle, QUIC_STREAM_START_FLAGS.SHUTDOWN_ON_FAIL | QUIC_STREAM_START_FLAGS.INDICATE_PEER_ACCEPT); - if (ThrowHelper.TryGetStreamExceptionForMsQuicStatus(status, out Exception? exception)) + + if (ThrowHelper.TryGetStreamExceptionForMsQuicStatus(status, out Exception? exception, streamWasSuccessfullyStarted: false)) { _startedTcs.TrySetException(exception); } From bb432d7f3ade0f79671717a5c10ef55d7d82a9a1 Mon Sep 17 00:00:00 2001 From: Eduardo Velarde <32459232+eduardo-vp@users.noreply.github.com> Date: Tue, 14 May 2024 12:58:24 -0700 Subject: [PATCH 732/783] [release/8.0-staging] Backport "Merge CoreCLR-based official builds legs into one leg per platform" (#102097) * Merge CoreCLR-based official builds legs into one leg per platform (#92901) * Pass "is official build" variable to AllConfigurations leg in the official build. (#93078) --------- Co-authored-by: Jeremy Koritzinsky --- eng/pipelines/common/global-build-job.yml | 9 +- .../common/templates/global-build-step.yml | 12 + .../common/templates/runtimes/xplat-job.yml | 9 - eng/pipelines/common/xplat-setup.yml | 9 + eng/pipelines/coreclr/templates/build-job.yml | 21 -- .../coreclr/templates/crossdac-build.yml | 80 ---- .../coreclr/templates/crossdac-hostarch.yml | 9 + .../coreclr/templates/crossdac-pack.yml | 75 ---- .../coreclr/templates/xplat-pipeline-job.yml | 6 - eng/pipelines/installer/jobs/build-job.yml | 29 +- .../jobs/steps/build-linux-package.yml | 2 + eng/pipelines/runtime-official.yml | 344 +++++++++++++----- eng/pipelines/runtime.yml | 23 +- src/coreclr/build-runtime.cmd | 9 +- 14 files changed, 317 insertions(+), 320 deletions(-) create mode 100644 eng/pipelines/common/templates/global-build-step.yml delete mode 100644 eng/pipelines/coreclr/templates/crossdac-build.yml create mode 100644 eng/pipelines/coreclr/templates/crossdac-hostarch.yml delete mode 100644 eng/pipelines/coreclr/templates/crossdac-pack.yml diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index cdda8c99dc519c..4b06818b1408c5 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -237,10 +237,11 @@ jobs: - task: CodeQL3000Init@0 displayName: Initialize CodeQL (manually-injected) - - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -ci $(_archParameter) $(_osParameter) $(crossArg) ${{ parameters.buildArgs }} $(_officialBuildParameter) $(_buildDarwinFrameworksParameter) $(_overrideTestScriptWindowsCmdParameter) - displayName: Build product - ${{ if eq(parameters.useContinueOnErrorDuringBuild, true) }}: - continueOnError: ${{ parameters.shouldContinueOnError }} + - template: /eng/pipelines/common/templates/global-build-step.yml + parameters: + buildArgs: ${{ parameters.buildArgs }} + useContinueOnErrorDuringBuild: ${{ parameters.useContinueOnErrorDuringBuild }} + shouldContinueOnError: ${{ parameters.shouldContinueOnError }} - ${{ if eq(parameters.isManualCodeQLBuild, true) }}: - task: CodeQL3000Finalize@0 diff --git a/eng/pipelines/common/templates/global-build-step.yml b/eng/pipelines/common/templates/global-build-step.yml new file mode 100644 index 00000000000000..7f38a9fd118405 --- /dev/null +++ b/eng/pipelines/common/templates/global-build-step.yml @@ -0,0 +1,12 @@ +parameters: + buildArgs: '' + useContinueOnErrorDuringBuild: false + shouldContinueOnError: false + archParameter: $(_archParameter) + displayName: Build product + +steps: + - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -ci ${{ parameters.archParameter }} $(_osParameter) $(crossArg) ${{ parameters.buildArgs }} $(_officialBuildParameter) $(_buildDarwinFrameworksParameter) $(_overrideTestScriptWindowsCmdParameter) + displayName: ${{ parameters.displayName }} + ${{ if eq(parameters.useContinueOnErrorDuringBuild, true) }}: + continueOnError: ${{ parameters.shouldContinueOnError }} diff --git a/eng/pipelines/common/templates/runtimes/xplat-job.yml b/eng/pipelines/common/templates/runtimes/xplat-job.yml index f4ac7e82957123..23e74c70e57ace 100644 --- a/eng/pipelines/common/templates/runtimes/xplat-job.yml +++ b/eng/pipelines/common/templates/runtimes/xplat-job.yml @@ -77,15 +77,6 @@ jobs: - name: buildConfig value: ${{ parameters.buildConfig }} - - name: archType - value: ${{ parameters.archType }} - - - name: osGroup - value: ${{ parameters.osGroup }} - - - name: osSubgroup - value: ${{ parameters.osSubgroup }} - - ${{ if and(eq(variables['System.TeamProject'], 'internal'), ne(variables['Build.Reason'], 'PullRequest')) }}: - name: _HelixSource value: official/dotnet/runtime/$(Build.SourceBranch) diff --git a/eng/pipelines/common/xplat-setup.yml b/eng/pipelines/common/xplat-setup.yml index eb19570aeecac2..675a2679201861 100644 --- a/eng/pipelines/common/xplat-setup.yml +++ b/eng/pipelines/common/xplat-setup.yml @@ -45,6 +45,15 @@ jobs: - name: _BuildConfig value: $(buildConfigUpper) + + - name: archType + value: ${{ parameters.archType }} + + - name: osGroup + value: ${{ parameters.osGroup }} + + - name: osSubgroup + value: ${{ parameters.osSubgroup }} - name: _runSmokeTestsOnlyArg value: '/p:RunSmokeTestsOnly=$(isRunSmokeTestsOnly)' diff --git a/eng/pipelines/coreclr/templates/build-job.yml b/eng/pipelines/coreclr/templates/build-job.yml index e995e626a56991..ebaeae5e124042 100644 --- a/eng/pipelines/coreclr/templates/build-job.yml +++ b/eng/pipelines/coreclr/templates/build-job.yml @@ -231,27 +231,6 @@ jobs: artifactName: $(buildProductArtifactName) displayName: 'product build' - - ${{ if and(in(parameters.osGroup, 'windows', 'linux'), ne(parameters.archType, 'x86')) }}: - - template: /eng/pipelines/coreclr/templates/crossdac-build.yml - parameters: - archType: ${{ parameters.archType }} - osGroup: ${{ parameters.osGroup }} - osSubgroup: ${{ parameters.osSubgroup }} - isOfficialBuild: ${{ parameters.signBinaries }} - ${{ if eq(parameters.archType, 'arm') }}: - hostArchType: x86 - ${{ else }}: - hostArchType: x64 - - - ${{ if and(in(parameters.osGroup, 'windows'), eq(parameters.archType, 'x86')) }}: - - template: /eng/pipelines/coreclr/templates/crossdac-build.yml - parameters: - archType: arm - osGroup: ${{ parameters.osGroup }} - osSubgroup: ${{ parameters.osSubgroup }} - isOfficialBuild: ${{ parameters.signBinaries }} - hostArchType: x86 - - ${{ if and(ne(parameters.testGroup, ''), ne(parameters.disableClrTest, true)) }}: # Publish test native components for consumption by test execution. - ${{ if ne(parameters.isOfficialBuild, true) }}: diff --git a/eng/pipelines/coreclr/templates/crossdac-build.yml b/eng/pipelines/coreclr/templates/crossdac-build.yml deleted file mode 100644 index a8accb9d2e3d28..00000000000000 --- a/eng/pipelines/coreclr/templates/crossdac-build.yml +++ /dev/null @@ -1,80 +0,0 @@ -parameters: - archType: '' - isOfficialBuild: false - osGroup: '' - osSubgroup: '' - hostArchType: '' - -steps: - # Always build the crossdac, that way we know in CI/PR if things break to build. - - ${{ if and(eq(parameters.osGroup, 'windows'), notin(parameters.archType, 'x86')) }}: - - script: $(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) ${{ parameters.archType }} -hostarch ${{ parameters.hostArchType }} -ci -os linux -cmakeargs "-DCLR_CROSS_COMPONENTS_BUILD=1" -ninja $(officialBuildIdArg) -component crosscomponents - displayName: Build Cross OS Linux DAC for Windows - - - script: $(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) ${{ parameters.archType }} -hostarch ${{ parameters.hostArchType }} -ci -os alpine -cmakeargs "-DCLR_CROSS_COMPONENTS_BUILD=1" -ninja $(officialBuildIdArg) -component crosscomponents - displayName: Build Cross OS Linux-musl DAC for Windows - - - powershell: | - function CopyAndVerifyCrossOsAssets { - [CmdletBinding()] - param ( - [Parameter(Mandatory)][string]$crossDacDir, - [Parameter(Mandatory)][string]$targetDir - ) - - $crossDacDir = Join-Path $crossDacDir -ChildPath '${{ parameters.hostArchType }}' - - $availableFiles = ls -File $crossDacDir - - Write-Host "Probed for files in ""$crossDacDir"", found:" - $availableFiles | fl - - if (-not ("mscordaccore.dll" -in $availableFiles.Name ` - -and "mscordaccore.pdb" -in $availableFiles.Name ` - -and "mscordbi.dll" -in $availableFiles.Name ` - -and "mscordbi.pdb" -in $availableFiles.Name` - )) - { - Write-Error "Couldn't find one of the expected crossdac files." - } - - New-Item $targetDir -ItemType 'Directory' -Force -ea 0 - $availableFiles | %{ cp $_.FullName $targetDir -v } - } - - $buildMuslDacRootFolderPath = "$(Build.SourcesDirectory)/artifacts/bin/coreclr/alpine.${{ parameters.archType }}.$(buildConfigUpper)" - $buildMuslStagingPath = "$(crossDacArtifactPath)/Linux_musl.${{ parameters.archType }}.$(buildConfigUpper)/${{ parameters.hostArchType }}" - - $buildLinuxDacRootFolderPath = "$(Build.SourcesDirectory)/artifacts/bin/coreclr/Linux.${{ parameters.archType }}.$(buildConfigUpper)" - $buildLinuxDacStagingPath = "$(crossDacArtifactPath)/Linux.${{ parameters.archType }}.$(buildConfigUpper)/${{ parameters.hostArchType }}" - - - CopyAndVerifyCrossOsAssets -CrossDacDir $buildMuslDacRootFolderPath -TargetDir $buildMuslStagingPath - CopyAndVerifyCrossOsAssets -CrossDacDir $buildLinuxDacRootFolderPath -TargetDir $buildLinuxDacStagingPath - - Write-Host "Final directory contents:" - ls -R $(crossDacArtifactPath) - - displayName: Gather CrossDac Artifacts - - - template: /eng/pipelines/coreclr/templates/sign-diagnostic-files.yml - parameters: - basePath: $(crossDacArtifactPath) - isOfficialBuild: ${{ parameters.isOfficialBuild }} - timeoutInMinutes: 30 - - - ${{ if eq(parameters.osGroup, 'linux') }}: - - task: CopyFiles@2 - displayName: Gather runtime for CrossDac - inputs: - SourceFolder: $(coreClrProductRootFolderPath) - Contents: libcoreclr.so - TargetFolder: '$(crossDacArtifactPath)/${{ parameters.osGroup }}${{ parameters.osSubgroup }}.$(archType).$(buildConfigUpper)/${{ parameters.hostArchType }}' - - # Make the assets available in a single container for the packaging job. - - task: PublishBuildArtifacts@1 - displayName: Publish runtime for CrossDac - inputs: - pathtoPublish: $(crossDacArtifactPath) - PublishLocation: Container - artifactName: $(buildCrossDacArtifactName) diff --git a/eng/pipelines/coreclr/templates/crossdac-hostarch.yml b/eng/pipelines/coreclr/templates/crossdac-hostarch.yml new file mode 100644 index 00000000000000..e100217a48151a --- /dev/null +++ b/eng/pipelines/coreclr/templates/crossdac-hostarch.yml @@ -0,0 +1,9 @@ +parameters: + archType: '' + +variables: + - name: crossDacHostArch + value: x64 + - ${{ if eq(parameters.archType, 'arm') }}: + - name: crossDacHostArch + value: x86 \ No newline at end of file diff --git a/eng/pipelines/coreclr/templates/crossdac-pack.yml b/eng/pipelines/coreclr/templates/crossdac-pack.yml deleted file mode 100644 index 520eb65fb337e6..00000000000000 --- a/eng/pipelines/coreclr/templates/crossdac-pack.yml +++ /dev/null @@ -1,75 +0,0 @@ -parameters: - archType: '' - buildConfig: '' - container: '' - crossDacPlatforms: {} - dependOnEvaluatePaths: false - isOfficialBuild: false - osGroup: '' - osSubgroup: '' - platform: '' - pool: '' - runtimeVariant: '' - testGroup: '' - timeoutInMinutes: '' - variables: {} - -jobs: -- template: xplat-pipeline-job.yml - parameters: - archType: ${{ parameters.archType }} - buildConfig: ${{ parameters.buildConfig }} - container: ${{ parameters.container }} - condition: ${{ parameters.isOfficialBuild }} - helixType: 'build/product/' - osGroup: ${{ parameters.osGroup }} - osSubgroup: ${{ parameters.osSubgroup }} - pool: ${{ parameters.pool }} - runtimeVariant: ${{ parameters.runtimeVariant }} - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - dependOnEvaluatePaths: ${{ parameters.dependOnEvaluatePaths }} - - name: crossdacpack - displayName: CrossDac Packaging - - variables: - - name: officialBuildIdArg - value: '' - - name: crossDacArgs - value: '/p:CrossDacArtifactsDir=$(crossDacArtifactPath)/$(buildCrossDacArtifactName)' - - ${{ if and(eq(variables['System.TeamProject'], 'internal'), ne(variables['Build.Reason'], 'PullRequest')) }}: - - name: officialBuildIdArg - value: '/p:OfficialBuildId=$(Build.BuildNumber)' - - name: SignType - value: $[ coalesce(variables.OfficialSignType, 'real') ] - - ${{ parameters.variables }} - - dependsOn: - - ${{ if ne(parameters.crossDacPlatforms, '') }}: - - ${{ each platform in parameters.crossDacPlatforms }}: - - ${{ parameters.runtimeFlavor }}_${{ parameters.runtimeVariant }}_product_build_${{ platform }}_${{ parameters.buildConfig }} - - steps: - - task: DownloadBuildArtifacts@0 - displayName: Download CrossDac artifacts - inputs: - artifactName: $(buildCrossDacArtifactName) - downloadPath: $(crossDacArtifactPath) - checkDownloadedFiles: true - - - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset crossdacpack -arch $(archType) $(osArg) -c $(buildConfig) $(officialBuildIdArg) $(crossDacArgs) -ci - displayName: Build crossdac packaging - - # Save packages using the prepare-signed-artifacts format. - - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - parameters: - name: ${{ parameters.platform }} - - # Upload to artifacts to be signed - - task: PublishPipelineArtifact@1 - displayName: Publish Logs - inputs: - targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: 'CrossDacPackagingLogs_Attempt$(System.JobAttempt)' - continueOnError: true - condition: always() diff --git a/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml b/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml index 162f5e9f0ed1c8..b6c57be0c7fbae 100644 --- a/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml +++ b/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml @@ -69,12 +69,6 @@ jobs: - name: buildProductRootFolderPath value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(buildConfigUpper)' - - name: buildCrossDacArtifactName - value: CoreCLRCrossDacArtifacts - - - name: crossDacArtifactPath - value: $(Build.SourcesDirectory)/artifacts/$(buildCrossDacArtifactName) - # We need this because both mono and coreclr build currently depends on CoreClr - name: coreClrProductArtifactName value: 'CoreCLRProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' diff --git a/eng/pipelines/installer/jobs/build-job.yml b/eng/pipelines/installer/jobs/build-job.yml index 1c45b437c8013f..43f19c69ccacfc 100644 --- a/eng/pipelines/installer/jobs/build-job.yml +++ b/eng/pipelines/installer/jobs/build-job.yml @@ -339,32 +339,9 @@ jobs: df -h displayName: Disk Usage before Build - # Build the default subset non-MacOS platforms - - ${{ if ne(parameters.osGroup, 'osx') }}: - - script: $(BaseJobBuildCommand) - displayName: Build - continueOnError: ${{ and(eq(variables.SkipTests, false), eq(parameters.shouldContinueOnError, true)) }} - - # Build corehost, sign and add entitlements to MacOS binaries - - ${{ if eq(parameters.osGroup, 'osx') }}: - - script: $(BaseJobBuildCommand) -subset host.native - displayName: Build CoreHost - continueOnError: ${{ and(eq(variables.SkipTests, false), eq(parameters.shouldContinueOnError, true)) }} - - - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - template: /eng/pipelines/common/macos-sign-with-entitlements.yml - parameters: - filesToSign: - - name: dotnet - path: $(Build.SourcesDirectory)/artifacts/bin/osx-${{ parameters.archType }}.$(_BuildConfig)/corehost - entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/entitlements.plist - - name: apphost - path: $(Build.SourcesDirectory)/artifacts/bin/osx-${{ parameters.archType }}.$(_BuildConfig)/corehost - entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/entitlements.plist - - - script: $(BaseJobBuildCommand) -subset host.pkg+host.tools+host.tests+packs - displayName: Build and Package - continueOnError: ${{ and(eq(variables.SkipTests, false), eq(parameters.shouldContinueOnError, true)) }} + - script: $(BaseJobBuildCommand) + displayName: Build + continueOnError: ${{ and(eq(variables.SkipTests, false), eq(parameters.shouldContinueOnError, true)) }} - ${{ if and(eq(parameters.isOfficialBuild, true), eq(parameters.osGroup, 'windows')) }}: - powershell: ./eng/collect_vsinfo.ps1 -ArchiveRunName postbuild_log diff --git a/eng/pipelines/installer/jobs/steps/build-linux-package.yml b/eng/pipelines/installer/jobs/steps/build-linux-package.yml index a5645af3d9ccd3..102eab770c278f 100644 --- a/eng/pipelines/installer/jobs/steps/build-linux-package.yml +++ b/eng/pipelines/installer/jobs/steps/build-linux-package.yml @@ -4,6 +4,7 @@ parameters: packageStepDescription: null packagingArgs: '' subsetArg: '' + condition: succeeded() steps: ## Run NuGet Authentication for each of the side containers @@ -20,6 +21,7 @@ steps: /bl:artifacts/log/$(_BuildConfig)/msbuild.${{ parameters.packageType }}.installers.binlog displayName: Package ${{ parameters.packageStepDescription }} - ${{ parameters.packageType }} target: ${{ parameters.target }} + condition: ${{ parameters.condition }} # Broken symbolic links break the SBOM processing # We make some symlinks during the installer generation process, # but they aren't always valid on disk afterwards. Some of our tooling, diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index 3138f18ebd734b..6e6781bb134d5d 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -58,47 +58,246 @@ extends: sourceIndexBuildCommand: build.cmd -subset libs.sfx+libs.oob -binarylog -os linux -ci /p:SkipLibrariesNativeRuntimePackages=true # - # Build CoreCLR + # Build CoreCLR runtime packs + # Windows x64/arm64 + # Sign diagnostic files after native build # - template: /eng/pipelines/common/platform-matrix.yml parameters: - jobTemplate: /eng/pipelines/coreclr/templates/build-job.yml + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: release + platforms: + - windows_x64 + - windows_arm64 + jobParameters: + buildArgs: -s clr.runtime+clr.alljits+clr.nativeaotruntime -c $(_BuildConfig) /bl:$(Build.SourcesDirectory)/artifacts/logs/$(_BuildConfig)/CoreClrNativeBuild.binlog + nameSuffix: CoreCLR + isOfficialBuild: ${{ variables.isOfficialBuild }} + timeoutInMinutes: 120 + postBuildSteps: + - template: /eng/pipelines/coreclr/templates/sign-diagnostic-files.yml + parameters: + basePath: $(Build.SourcesDirectory)/artifacts/bin/coreclr + isOfficialBuild: ${{ variables.isOfficialBuild }} + timeoutInMinutes: 30 + # Now that we've signed the diagnostic files, do the rest of the build. + - template: /eng/pipelines/common/templates/global-build-step.yml + parameters: + buildArgs: -s clr.corelib+clr.nativecorelib+clr.nativeaotlibs+clr.tools+clr.packages+libs+host+packs -c $(_BuildConfig) + displayName: Build managed CoreCLR components, all libraries, hosts, and packs + + # Upload the results. + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: $(osGroup)$(osSubgroup)_$(archType) + + + # + # Build CoreCLR runtime packs + # Windows x86 + # No NativeAOT as NativeAOT is not supported on x86 + # Sign diagnostic files after native build + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: release + platforms: + - windows_x86 + jobParameters: + buildArgs: -s clr.runtime+clr.alljits -c $(_BuildConfig) /bl:$(Build.SourcesDirectory)/artifacts/logs/$(_BuildConfig)/CoreClrNativeBuild.binlog + nameSuffix: CoreCLR + isOfficialBuild: ${{ variables.isOfficialBuild }} + timeoutInMinutes: 120 + postBuildSteps: + - template: /eng/pipelines/coreclr/templates/sign-diagnostic-files.yml + parameters: + basePath: $(Build.SourcesDirectory)/artifacts/bin/coreclr + isOfficialBuild: ${{ variables.isOfficialBuild }} + timeoutInMinutes: 30 + # Now that we've signed the diagnostic files, do the rest of the build. + - template: /eng/pipelines/common/templates/global-build-step.yml + parameters: + buildArgs: -s clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs+host+packs -c $(_BuildConfig) + displayName: Build managed CoreCLR components, all libraries, hosts, and packs + + # Upload the results. + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: $(osGroup)$(osSubgroup)_$(archType) + # + # Build CoreCLR runtime packs + # Mac x64/arm64 + # Sign and entitle createdump and corerun after native build. + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml buildConfig: release platforms: - osx_arm64 - osx_x64 + jobParameters: + buildArgs: -s clr.runtime+clr.alljits+clr.nativeaotruntime+host.native -c $(_BuildConfig) /bl:$(Build.SourcesDirectory)/artifacts/logs/$(_BuildConfig)/CoreClrNativeBuild.binlog + nameSuffix: CoreCLR + isOfficialBuild: ${{ variables.isOfficialBuild }} + timeoutInMinutes: 120 + postBuildSteps: + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - template: /eng/pipelines/common/macos-sign-with-entitlements.yml + parameters: + filesToSign: + - name: createdump + path: $(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(_BuildConfig) + entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/createdump-entitlements.plist + - name: corerun + path: $(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(_BuildConfig) + entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/entitlements.plist + - name: dotnet + path: $(Build.SourcesDirectory)/artifacts/bin/$(osGroup)-$(archType).$(_BuildConfig)/corehost + entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/entitlements.plist + - name: apphost + path: $(Build.SourcesDirectory)/artifacts/bin/$(osGroup)-$(archType).$(_BuildConfig)/corehost + entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/entitlements.plist + + - task: CopyFiles@2 + displayName: 'Copy signed createdump to sharedFramework' + inputs: + contents: createdump + sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(_BuildConfig) + targetFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(_BuildConfig)/sharedFramework + overWrite: true + + # Now that we've entitled and signed createdump, we can build the rest. + - template: /eng/pipelines/common/templates/global-build-step.yml + parameters: + buildArgs: -s clr.corelib+clr.nativecorelib+clr.nativeaotlibs+clr.tools+clr.packages+libs+host.tools+host.pkg+packs -c $(_BuildConfig) + displayName: Build managed CoreCLR and host components, all libraries, and packs + + # Upload the results. + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: $(osGroup)$(osSubgroup)_$(archType) + + # + # Build CoreCLR runtime packs + # Linux and Linux_musl + # CoreCLR runtime for CrossDac packaging + # Create Linux installers + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: release + platforms: - linux_x64 - linux_arm - linux_arm64 - linux_musl_x64 - linux_musl_arm - linux_musl_arm64 - - windows_x86 - - windows_x64 - - windows_arm64 jobParameters: + buildArgs: -s clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.aot+clr.packages+libs+host+packs -c $(_BuildConfig) + nameSuffix: CoreCLR isOfficialBuild: ${{ variables.isOfficialBuild }} - signBinaries: ${{ variables.isOfficialBuild }} timeoutInMinutes: 120 + postBuildSteps: + # Upload libcoreclr.so for CrossDac packaging + - task: CopyFiles@2 + displayName: Gather runtime for CrossDac + inputs: + SourceFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(_BuildConfig) + Contents: libcoreclr.so + TargetFolder: $(Build.SourcesDirectory)/artifacts/CoreCLRCrossDacArtifacts/$(osGroup)$(osSubgroup).$(archType).$(_BuildConfig)/$(crossDacHostArch) + - task: PublishBuildArtifacts@1 + displayName: Publish runtime for CrossDac + inputs: + pathToPublish: $(Build.SourcesDirectory)/artifacts/CoreCLRCrossDacArtifacts + PublishLocation: Container + artifactName: CoreCLRCrossDacArtifacts + # Create RPMs and DEBs + - template: /eng/pipelines/installer/jobs/steps/build-linux-package.yml + parameters: + packageType: deb + target: debpkg + packageStepDescription: Runtime Deps, Runtime, Framework Packs Deb installers + subsetArg: -s packs.installers + packagingArgs: -c $(_BuildConfig) --arch $(archType) --os $(osGroup) --ci /p:OfficialBuildId=$(Build.BuildNumber) /p:BuildDebPackage=true + condition: and(succeeded(), eq(variables.osSubgroup, ''), eq(variables.archType, 'x64')) + - template: /eng/pipelines/installer/jobs/steps/build-linux-package.yml + parameters: + packageType: rpm + target: rpmpkg + packageStepDescription: Runtime Deps, Runtime, Framework Packs RPM installers + subsetArg: -s packs.installers + packagingArgs: -c $(_BuildConfig) --arch $(archType) --os $(osGroup) --ci /p:OfficialBuildId=$(Build.BuildNumber) /p:BuildRpmPackage=true + condition: and(succeeded(), eq(variables.osSubgroup, ''), in(variables.archType, 'x64', 'arm64')) + # Upload the results. + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: $(osGroup)$(osSubgroup)_$(archType) + extraVariablesTemplates: + - template: /eng/pipelines/coreclr/templates/crossdac-hostarch.yml + + # + # Build and Pack CrossDac + # - template: /eng/pipelines/common/platform-matrix.yml parameters: - jobTemplate: /eng/pipelines/coreclr/templates/crossdac-pack.yml + jobTemplate: /eng/pipelines/common/global-build-job.yml buildConfig: release platforms: - windows_x64 jobParameters: + buildArgs: -s crossdacpack -c $(_BuildConfig) /p:CrossDacArtifactsDir=$(crossDacArtifactsPath) + nameSuffix: CrossDac isOfficialBuild: ${{ variables.isOfficialBuild }} timeoutInMinutes: 120 - crossDacPlatforms: - - linux_x64 - - linux_arm - - linux_arm64 - - linux_musl_x64 - - linux_musl_arm - - linux_musl_arm64 - - windows_x64 - - windows_arm64 + preBuildSteps: + - task: DownloadBuildArtifacts@0 + displayName: Download Runtimes for CrossDac packaging + inputs: + artifactName: $(crossDacArtifactsContainer) + downloadPath: $(crossDacArtifactsBasePath) + checkDownloadedFiles: true + - template: /eng/pipelines/common/templates/global-build-step.yml + parameters: + buildArgs: -s linuxdac+alpinedac -c $(_BuildConfig) + archParameter: -arch x64,x86,arm,arm64 + - task: CopyFiles@2 + displayName: Gather CrossDacs + inputs: + SourceFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr + Contents: | + ** + !**\sharedFramework\** + TargetFolder: $(crossDacArtifactsPath) + - template: /eng/pipelines/coreclr/templates/sign-diagnostic-files.yml + parameters: + basePath: $(crossDacArtifactsPath) + isOfficialBuild: ${{ variables.isOfficialBuild }} + timeoutInMinutes: 30 + postBuildSteps: + # Save packages using the prepare-signed-artifacts format. + # CrossDac packages are expected to be in the windows_x64 folder. + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: windows_x64 + dependsOn: + - build_linux_x64_release_CoreCLR + - build_linux_arm_release_CoreCLR + - build_linux_arm64_release_CoreCLR + - build_linux_musl_x64_release_CoreCLR + - build_linux_musl_arm_release_CoreCLR + - build_linux_musl_arm64_release_CoreCLR + variables: + - name: crossDacArtifactsContainer + value: CoreCLRCrossDacArtifacts + - name: crossDacArtifactsBasePath + value: $(Build.StagingDirectory)/CrossDac + - name: crossDacArtifactsPath + value: $(crossDacArtifactsBasePath)/$(crossDacArtifactsContainer) # # Build NativeAOT runtime packs @@ -122,7 +321,7 @@ extends: - linux_bionic_x64 jobParameters: buildArgs: -s clr.nativeaotlibs+clr.nativeaotruntime+libs+packs -c $(_BuildConfig) /p:BuildNativeAOTRuntimePack=true /p:SkipLibrariesNativeRuntimePackages=true - nameSuffix: AllSubsets_NativeAOT + nameSuffix: NativeAOT isOfficialBuild: ${{ variables.isOfficialBuild }} postBuildSteps: - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml @@ -165,7 +364,7 @@ extends: # - windows_arm64 jobParameters: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:BuildMonoAOTCrossCompiler=false - nameSuffix: AllSubsets_Mono + nameSuffix: Mono isOfficialBuild: ${{ variables.isOfficialBuild }} postBuildSteps: - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml @@ -182,7 +381,7 @@ extends: - wasi_wasm jobParameters: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS) - nameSuffix: AllSubsets_Mono + nameSuffix: Mono isOfficialBuild: ${{ variables.isOfficialBuild }} postBuildSteps: - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml @@ -198,7 +397,7 @@ extends: - browser_wasm jobParameters: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:MonoWasmBuildVariant=multithread /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS) - nameSuffix: AllSubsets_Mono_multithread + nameSuffix: Mono_multithread isOfficialBuild: ${{ variables.isOfficialBuild }} runtimeVariant: multithread postBuildSteps: @@ -329,7 +528,7 @@ extends: jobParameters: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:MonoEnableLLVM=true /p:MonoBundleLLVMOptimizer=false - nameSuffix: AllSubsets_Mono_LLVMJIT + nameSuffix: Mono_LLVMJIT runtimeVariant: LLVMJIT isOfficialBuild: ${{ variables.isOfficialBuild }} postBuildSteps: @@ -343,7 +542,7 @@ extends: jobParameters: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true - nameSuffix: AllSubsets_Mono_LLVMAOT + nameSuffix: Mono_LLVMAOT runtimeVariant: LLVMAOT isOfficialBuild: ${{ variables.isOfficialBuild }} postBuildSteps: @@ -352,49 +551,26 @@ extends: name: MonoRuntimePacks # - # Build libraries using live CoreLib from CoreCLR + # Build libraries AllConfigurations for packages # - template: /eng/pipelines/common/platform-matrix.yml parameters: - jobTemplate: /eng/pipelines/libraries/build-job.yml + jobTemplate: /eng/pipelines/common/global-build-job.yml buildConfig: Release platforms: - - osx_arm64 - - osx_x64 - - linux_x64 - - linux_arm - - linux_arm64 - - linux_musl_x64 - - linux_musl_arm - - linux_musl_arm64 - - windows_x86 - windows_x64 - - windows_arm64 jobParameters: + buildArgs: -s tools+libs -allConfigurations -c $(_BuildConfig) /p:TestAssemblies=false /p:TestPackages=true + nameSuffix: Libraries_AllConfigurations isOfficialBuild: ${{ variables.isOfficialBuild }} - liveRuntimeBuildConfig: release - # Official builds don't run tests, locally or on Helix - runTests: false - useHelix: false - + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: Libraries_AllConfigurations + timeoutInMinutes: 95 # - # Build libraries AllConfigurations for packages + # Build SourceBuild packages # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/libraries/build-job.yml - buildConfig: Release - platforms: - - windows_x64 - jobParameters: - framework: allConfigurations - isOfficialBuild: ${{ variables.isOfficialBuild }} - isOfficialAllConfigurations: true - liveRuntimeBuildConfig: release - # Official builds don't run tests, locally or on Helix - runTests: false - useHelix: false - - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/common/global-build-job.yml @@ -410,30 +586,6 @@ extends: name: SourceBuildPackages timeoutInMinutes: 95 - # - # Installer Build - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/installer/jobs/build-job.yml - buildConfig: Release - jobParameters: - liveRuntimeBuildConfig: release - liveLibrariesBuildConfig: Release - isOfficialBuild: ${{ variables.isOfficialBuild }} - platforms: - - osx_arm64 - - osx_x64 - - linux_x64 - - linux_arm - - linux_arm64 - - linux_musl_x64 - - linux_musl_arm - - linux_musl_arm64 - - windows_x86 - - windows_x64 - - windows_arm64 - # # Build PGO Instrumented CoreCLR Release # @@ -470,24 +622,24 @@ extends: isOfficialBuild: ${{ variables.isOfficialBuild }} timeoutInMinutes: 120 dependsOn: - - Build_android_arm_release_AllSubsets_Mono - - Build_android_arm64_release_AllSubsets_Mono - - Build_android_x86_release_AllSubsets_Mono - - Build_android_x64_release_AllSubsets_Mono - - Build_browser_wasm_Linux_release_AllSubsets_Mono - - Build_wasi_wasm_linux_release_AllSubsets_Mono - - Build_ios_arm64_release_AllSubsets_Mono - - Build_iossimulator_x64_release_AllSubsets_Mono - - Build_iossimulator_arm64_release_AllSubsets_Mono - - Build_maccatalyst_arm64_release_AllSubsets_Mono - - Build_maccatalyst_x64_release_AllSubsets_Mono - - Build_tvos_arm64_release_AllSubsets_Mono - - Build_tvossimulator_arm64_release_AllSubsets_Mono - - Build_tvossimulator_x64_release_AllSubsets_Mono + - Build_android_arm_release_Mono + - Build_android_arm64_release_Mono + - Build_android_x86_release_Mono + - Build_android_x64_release_Mono + - Build_browser_wasm_Linux_release_Mono + - Build_wasi_wasm_linux_release_Mono + - Build_ios_arm64_release_Mono + - Build_iossimulator_x64_release_Mono + - Build_iossimulator_arm64_release_Mono + - Build_maccatalyst_arm64_release_Mono + - Build_maccatalyst_x64_release_Mono + - Build_tvos_arm64_release_Mono + - Build_tvossimulator_arm64_release_Mono + - Build_tvossimulator_x64_release_Mono - Build_windows_x64_release_CrossAOT_Mono - - installer_coreclr__windows_x64_Release_ - - installer_coreclr__windows_x86_Release_ - - installer_coreclr__windows_arm64_Release_ + - Build_windows_x64_release_CoreCLR + - Build_windows_x86_release_CoreCLR + - Build_windows_arm64_release_CoreCLR - ${{ if eq(variables.isOfficialBuild, true) }}: - template: /eng/pipelines/official/stages/publish.yml diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index c83a76993e60d6..767b3dc9ba424b 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -400,6 +400,27 @@ extends: eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), eq(dependencies.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'], true), eq(variables['isRollingBuild'], true)) + # + # Build CrossDacs + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: release + platforms: + - windows_x64 + variables: + - name: _archParameter + value: -arch x64,x86,arm,arm64 + jobParameters: + buildArgs: -s linuxdac+alpinedac -c Checked,$(_BuildConfig) + nameSuffix: CrossDac + isOfficialBuild: false + timeoutInMinutes: 60 + postBuildSteps: + - publish: $(Build.SourcesDirectory)/artifacts/bin/coreclr + displayName: Publish CrossDacs for diagnostics + artifact: CoreCLRCrossDacArtifacts # Build Mono AOT offset headers once, for consumption elsewhere # Only when mono changed @@ -415,7 +436,7 @@ extends: - ios_arm64 - maccatalyst_x64 jobParameters: - isOfficialBuild: ${{ variables.isOfficialBuild }} + isOfficialBuild: false # needed by crossaot condition: >- or( diff --git a/src/coreclr/build-runtime.cmd b/src/coreclr/build-runtime.cmd index ec6887c78d84cb..d85e6c95909f02 100644 --- a/src/coreclr/build-runtime.cmd +++ b/src/coreclr/build-runtime.cmd @@ -211,8 +211,13 @@ if NOT "%__BuildType%"=="Release" ( set __PgoOptimize=0 ) -set "__BinDir=%__RootBinDir%\bin\coreclr\%__TargetOS%.%__TargetArch%.%__BuildType%" -set "__IntermediatesDir=%__RootBinDir%\obj\coreclr\%__TargetOS%.%__TargetArch%.%__BuildType%" +set __TargetOSDirName=%__TargetOS% +if "%__TargetOS%"=="alpine" ( + set __TargetOSDirName=linux_musl +) + +set "__BinDir=%__RootBinDir%\bin\coreclr\%__TargetOSDirName%.%__TargetArch%.%__BuildType%" +set "__IntermediatesDir=%__RootBinDir%\obj\coreclr\%__TargetOSDirName%.%__TargetArch%.%__BuildType%" set "__LogsDir=%__RootBinDir%\log\!__BuildType!" set "__MsbuildDebugLogsDir=%__LogsDir%\MsbuildDebugLogs" set "__ArtifactsIntermediatesDir=%__RepoRootDir%\artifacts\obj\coreclr\" From 98dd7f85c85fb89ccb82ce24d3eb630fce3057e3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 May 2024 23:24:56 +0200 Subject: [PATCH 733/783] [release/8.0-staging] [WinHttpHandler] Move `_cachedSendPinnedBuffer` ownership to `WinHttpRequestState` (#102083) * move _cachedSendPinnedBuffer ownership to WinHttpRequestState * set GeneratePackageOnBuild & ServicingVersion --- .../src/System.Net.Http.WinHttpHandler.csproj | 2 ++ .../System/Net/Http/WinHttpRequestState.cs | 22 +++++++++++++++++- .../System/Net/Http/WinHttpRequestStream.cs | 23 ++----------------- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj index 404e965fd8f512..21b2b54e3cbecf 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj @@ -4,6 +4,8 @@ true true true + true + 1 Provides a message handler for HttpClient based on the WinHTTP interface of Windows. While similar to HttpClientHandler, it provides developers more granular control over the application's HTTP communication than the HttpClientHandler. Commonly Used Types: diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs index a0af9a557f5809..f8b01f140b75ec 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs @@ -157,6 +157,7 @@ public WinHttpTransportContext TransportContext public long CurrentBytesRead { get; set; } private GCHandle _cachedReceivePinnedBuffer; + private GCHandle _cachedSendPinnedBuffer; public void PinReceiveBuffer(byte[] buffer) { @@ -171,6 +172,19 @@ public void PinReceiveBuffer(byte[] buffer) } } + public void PinSendBuffer(byte[] buffer) + { + if (!_cachedSendPinnedBuffer.IsAllocated || _cachedSendPinnedBuffer.Target != buffer) + { + if (_cachedSendPinnedBuffer.IsAllocated) + { + _cachedSendPinnedBuffer.Free(); + } + + _cachedSendPinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); + } + } + #region IDisposable Members private void Dispose(bool disposing) { @@ -193,12 +207,18 @@ private void Dispose(bool disposing) { // This method only gets called when the WinHTTP request handle is fully closed and thus all // async operations are done. So, it is safe at this point to unpin the buffers and release - // the strong GCHandle for this object. + // the strong GCHandle for the pinned buffers. if (_cachedReceivePinnedBuffer.IsAllocated) { _cachedReceivePinnedBuffer.Free(); _cachedReceivePinnedBuffer = default(GCHandle); } + + if (_cachedSendPinnedBuffer.IsAllocated) + { + _cachedSendPinnedBuffer.Free(); + _cachedSendPinnedBuffer = default(GCHandle); + } #if DEBUG Interlocked.Increment(ref s_dbg_operationHandleFree); #endif diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs index ebbb43eaeedb46..64288c537fa674 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs @@ -24,8 +24,6 @@ internal sealed class WinHttpRequestStream : Stream private readonly SafeWinHttpHandle _requestHandle; private readonly WinHttpChunkMode _chunkedMode; - private GCHandle _cachedSendPinnedBuffer; - internal WinHttpRequestStream(WinHttpRequestState state, WinHttpChunkMode chunkedMode) { _state = state; @@ -182,15 +180,7 @@ internal async Task EndUploadAsync(CancellationToken token) protected override void Dispose(bool disposing) { - if (!_disposed) - { - _disposed = true; - if (_cachedSendPinnedBuffer.IsAllocated) - { - _cachedSendPinnedBuffer.Free(); - } - } - + _disposed = true; base.Dispose(disposing); } @@ -234,16 +224,7 @@ private Task InternalWriteDataAsync(byte[] buffer, int offset, int count, { Debug.Assert(count > 0); - if (!_cachedSendPinnedBuffer.IsAllocated || _cachedSendPinnedBuffer.Target != buffer) - { - if (_cachedSendPinnedBuffer.IsAllocated) - { - _cachedSendPinnedBuffer.Free(); - } - - _cachedSendPinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); - } - + _state.PinSendBuffer(buffer); _state.TcsInternalWriteDataToRequestStream = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); From 49c1cf3c3653f34306203fd1ff00e1047ae54965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Thu, 16 May 2024 09:02:47 +0200 Subject: [PATCH 734/783] [wasm] Suppress export name minification (#102155) --- src/mono/wasm/build/WasmApp.Native.targets | 2 +- src/mono/wasm/wasm.proj | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index 52b2988f8dd3d3..7aa1203bd11551 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -257,7 +257,7 @@ <_EmccLDFlags Include="$(EmccLinkOptimizationFlag)" /> <_EmccLDFlags Include="@(_EmccCommonFlags)" /> - <_EmccLDFlags Include="-s EXPORT_ES6=1" /> + <_EmccLDFlags Include="-s EXPORT_ES6=1 -lexports.js" /> <_DriverCDependencies Include="$(_WasmPInvokeHPath);$(_WasmICallTablePath)" /> <_DriverCDependencies Include="$(_DriverGenCPath)" Condition="'$(_DriverGenCNeeded)' == 'true'" /> diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 3b75fa9feeb1f0..1790445cbc6726 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -370,7 +370,8 @@ $(CMakeConfigurationEmccFlags) -s ASSERTIONS=1 -O2 - $(CMakeConfigurationLinkFlags) -s EXPORT_ES6=1 + + $(CMakeConfigurationLinkFlags) -s EXPORT_ES6=1 -lexports.js $(CMakeConfigurationLinkFlags) -msimd128 $(CMakeConfigurationLinkFlags) -Wno-pthreads-mem-growth $(CMakeConfigurationLinkFlags) --emit-symbol-map From 69c5ca890a80d925ba6bd4ca117db34eaa1bffd7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 16:34:23 -0600 Subject: [PATCH 735/783] [release/8.0-staging] Update dependencies from dotnet/source-build-reference-packages (#101917) * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20240501.1 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.24163.3 -> To Version 8.0.0-alpha.1.24251.1 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20240507.2 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.24163.3 -> To Version 8.0.0-alpha.1.24257.2 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c2d1b0ca3f6dd6..758d2328e9c532 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -99,9 +99,9 @@ a1cd44fdc64aa1f1c4630ddcd95580800d229180 - + https://github.com/dotnet/source-build-reference-packages - 79827eed138fd2575a8b24820b4f385ee4ffb6e6 + 6ed73280a6d70f7e7ac39c86f2abe8c10983f0bb From a7ed09cb748f3dec5c8028b8716ce41d3608b288 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 16:34:31 -0600 Subject: [PATCH 736/783] [release/8.0-staging] Update dependencies from dotnet/source-build-externals (#101979) * Update dependencies from https://github.com/dotnet/source-build-externals build 20240506.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24216.1 -> To Version 8.0.0-alpha.1.24256.1 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240506.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24216.1 -> To Version 8.0.0-alpha.1.24256.1 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240506.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24216.1 -> To Version 8.0.0-alpha.1.24256.1 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240506.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24216.1 -> To Version 8.0.0-alpha.1.24256.1 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240506.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24216.1 -> To Version 8.0.0-alpha.1.24256.1 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240506.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24216.1 -> To Version 8.0.0-alpha.1.24256.1 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240513.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24216.1 -> To Version 8.0.0-alpha.1.24263.1 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240513.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24216.1 -> To Version 8.0.0-alpha.1.24263.1 * Update dependencies from https://github.com/dotnet/source-build-externals build 20240513.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24216.1 -> To Version 8.0.0-alpha.1.24263.1 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 758d2328e9c532..f9d045a4d4abdf 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -104,9 +104,9 @@ 6ed73280a6d70f7e7ac39c86f2abe8c10983f0bb - + https://github.com/dotnet/source-build-externals - 908177a58a41532b3302c17f1e1a8cf1c1234545 + a3021ef9ed72d7bdf799092a47d2d024fc13bfcd From fe21c03db56cb2ab70de27b3f986e314e4a652c4 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 16:51:30 -0600 Subject: [PATCH 737/783] [release/8.0-staging] Update dependencies from dotnet/emsdk (#101941) * Update dependencies from https://github.com/dotnet/emsdk build 20240506.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.6-servicing.24252.3 -> To Version 8.0.6-servicing.24256.2 * Update dependencies from https://github.com/dotnet/emsdk build 20240507.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.6-servicing.24252.3 -> To Version 8.0.6-servicing.24257.1 * Update dependencies from https://github.com/dotnet/emsdk build 20240508.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.6-servicing.24252.3 -> To Version 8.0.6-servicing.24258.1 * Update dependencies from https://github.com/dotnet/emsdk build 20240514.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.6-servicing.24252.3 -> To Version 8.0.6-servicing.24264.1 --------- Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 58277f76a142da..3e394d788ef3af 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f9d045a4d4abdf..77cf3d794bd856 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - a1cd44fdc64aa1f1c4630ddcd95580800d229180 + 16d77ddacb12870344abbc4831387cc3e8f97168 - + https://github.com/dotnet/emsdk - a1cd44fdc64aa1f1c4630ddcd95580800d229180 + 16d77ddacb12870344abbc4831387cc3e8f97168 From 0abb5108159f9910dad02d2b76458ca3e35a7681 Mon Sep 17 00:00:00 2001 From: Nikola Milosavljevic Date: Thu, 16 May 2024 16:18:03 -0700 Subject: [PATCH 738/783] Enable repackaging of NETStandard 2.1 Targeting Pack (#102081) * Initial changes * Enable building in 8.0.6 release * Build netstandard 2.1 installer for RPM only * Update target build to 8.0.7 --- eng/Subsets.props | 1 + eng/Versions.props | 8 +++ src/installer/pkg/sfx/installers.proj | 4 ++ .../pkg/sfx/installers/netstandard2.1.proj | 60 +++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 src/installer/pkg/sfx/installers/netstandard2.1.proj diff --git a/eng/Subsets.props b/eng/Subsets.props index 69924723836c21..c27a284127733e 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -507,6 +507,7 @@ + diff --git a/eng/Versions.props b/eng/Versions.props index ba8e464d4f35ec..677bef5639bf56 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -260,4 +260,12 @@ 8.0.101 $(MicrosoftDotnetSdkInternalVersion) + + + true + diff --git a/src/installer/pkg/sfx/installers.proj b/src/installer/pkg/sfx/installers.proj index 7f4ce6b9c1c409..2f947e6d9e291e 100644 --- a/src/installer/pkg/sfx/installers.proj +++ b/src/installer/pkg/sfx/installers.proj @@ -22,6 +22,10 @@ + + + + + + true + false + netstandard-targeting-pack-2.1 + NETStandard.Library.Ref + NETStandard.Library.Ref 2.1.0 + false + ToolPack + true + netstandard-targeting-pack-2.1.0-x64.rpm + https://dotnetcli.blob.core.windows.net/dotnet/Runtime/3.1.0/$(OriginalNETStandard21PkgFilename) + $([MSBuild]::NormalizeDirectory('$(BaseIntermediateOutputPath)', 'download')) + $(NETStandard21TempDir)$(OriginalNETStandard21PkgFilename) + $(NETStandard21TempDir)netstandard21.semaphore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 849596069fcb6ec0b30039ae05cadc9a40220ee6 Mon Sep 17 00:00:00 2001 From: Matous Kozak <55735845+matouskozak@users.noreply.github.com> Date: Fri, 17 May 2024 16:33:26 +0200 Subject: [PATCH 739/783] [mono] disable fullAOT-llvm x64 job (#102330) --- .../runtime-extra-platforms-other.yml | 67 ++++++++++--------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml index ee481119ad9607..e2e95c6bac5739 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml +++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-other.yml @@ -355,40 +355,41 @@ jobs: # Mono CoreCLR runtime Test executions using live libraries and LLVM Full AOT # Only when Mono is changed # -- template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml - buildConfig: Release - runtimeFlavor: mono - platforms: - - linux_x64 - # - linux_arm64 - variables: - - name: timeoutPerTestInMinutes - value: 60 - - name: timeoutPerTestCollectionInMinutes - value: 180 - jobParameters: - testGroup: innerloop - nameSuffix: AllSubsets_Mono_LLVMFullAot_RuntimeTests - runtimeVariant: llvmfullaot - buildArgs: -s mono+libs+clr.hosts+clr.iltools -c Release /p:MonoEnableLLVM=true /p:MonoBundleLLVMOptimizer=true - timeoutInMinutes: 300 +# Disabled due to OOM errors: https://github.com/dotnet/runtime/issues/90427 +# - template: /eng/pipelines/common/platform-matrix.yml +# parameters: +# jobTemplate: /eng/pipelines/common/global-build-job.yml +# helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml +# buildConfig: Release +# runtimeFlavor: mono +# platforms: +# - linux_x64 +# # - linux_arm64 +# variables: +# - name: timeoutPerTestInMinutes +# value: 60 +# - name: timeoutPerTestCollectionInMinutes +# value: 180 +# jobParameters: +# testGroup: innerloop +# nameSuffix: AllSubsets_Mono_LLVMFullAot_RuntimeTests +# runtimeVariant: llvmfullaot +# buildArgs: -s mono+libs+clr.hosts+clr.iltools -c Release /p:MonoEnableLLVM=true /p:MonoBundleLLVMOptimizer=true +# timeoutInMinutes: 300 - condition: >- - or( - eq(dependencies.evaluate_paths.outputs['SetPathVars_mono_excluding_wasm.containsChange'], true), - eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true), - eq(variables['isRollingBuild'], true)) - postBuildSteps: - - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - parameters: - creator: dotnet-bot - llvmAotStepContainer: linux_x64_llvmaot - testRunNamePrefixSuffix: Mono_Release - extraVariablesTemplates: - - template: /eng/pipelines/common/templates/runtimes/test-variables.yml +# condition: >- +# or( +# eq(dependencies.evaluate_paths.outputs['SetPathVars_mono_excluding_wasm.containsChange'], true), +# eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true), +# eq(variables['isRollingBuild'], true)) +# postBuildSteps: +# - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml +# parameters: +# creator: dotnet-bot +# llvmAotStepContainer: linux_x64_llvmaot +# testRunNamePrefixSuffix: Mono_Release +# extraVariablesTemplates: +# - template: /eng/pipelines/common/templates/runtimes/test-variables.yml # # Mono CoreCLR runtime Test executions using live libraries in interpreter mode From ba826e1e68a37031eb20ed427cf68e3090f3c23b Mon Sep 17 00:00:00 2001 From: vseanreesermsft <78103370+vseanreesermsft@users.noreply.github.com> Date: Fri, 17 May 2024 12:51:12 -0700 Subject: [PATCH 740/783] Update branding to 8.0.7 (#102356) * Update branding to 8.0.7 * Update eng/Versions.props Co-authored-by: Larry Ewing --------- Co-authored-by: Larry Ewing --- eng/Versions.props | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index ba8e464d4f35ec..f5f01e6504e0c1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,13 +1,13 @@ - 8.0.6 + 8.0.7 8 0 - 6 + 7 8.0.100 - 7.0.19 + 7.0.20 6.0.$([MSBuild]::Add($(PatchVersion),25)) servicing From 75dc9135818c14cafc8195b0b3b23f96f6e708f2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 17 May 2024 13:48:20 -0700 Subject: [PATCH 741/783] Update dependencies from https://github.com/dotnet/emsdk build 20240514.1 (#102400) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.6-servicing.24252.3 -> To Version 8.0.6-servicing.24264.1 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 58277f76a142da..3e394d788ef3af 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c2d1b0ca3f6dd6..3f51b32794afb6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - a1cd44fdc64aa1f1c4630ddcd95580800d229180 + 16d77ddacb12870344abbc4831387cc3e8f97168 - + https://github.com/dotnet/emsdk - a1cd44fdc64aa1f1c4630ddcd95580800d229180 + 16d77ddacb12870344abbc4831387cc3e8f97168 From a4902024b9733cb9d180d7d4db32825d9588bbbe Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Mon, 20 May 2024 18:03:58 +0000 Subject: [PATCH 742/783] Do not run n V8, only on the browser. (#102447) --- ...ystem.Globalization.Calendars.Hybrid.WASM.Tests.csproj | 8 ++++++++ .../Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/libraries/System.Globalization.Calendars/tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj b/src/libraries/System.Globalization.Calendars/tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj index 5b898363764087..e70dcc3b08ebf6 100644 --- a/src/libraries/System.Globalization.Calendars/tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj +++ b/src/libraries/System.Globalization.Calendars/tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj @@ -4,6 +4,14 @@ true true true + + + + WasmTestOnBrowser + $(TestArchiveRoot)browserornodejs/ + $(TestArchiveTestsRoot)$(OSPlatformConfig)/ + $(DefineConstants);TARGET_BROWSER + true diff --git a/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj b/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj index a39604c1cfaccd..0a0322d77f3028 100644 --- a/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj +++ b/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj @@ -5,6 +5,14 @@ true true true + + + + WasmTestOnBrowser + $(TestArchiveRoot)browserornodejs/ + $(TestArchiveTestsRoot)$(OSPlatformConfig)/ + $(DefineConstants);TARGET_BROWSER + true From 7e758f66b96527ffb3f4e800bf5a9dcf5de9ca27 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 11:24:31 -0700 Subject: [PATCH 743/783] Update dependencies from https://github.com/dotnet/arcade build 20240516.3 (#102432) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24204.3 -> To Version 8.0.0-beta.24266.3 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 72 +++++++++---------- eng/Versions.props | 30 ++++---- .../job/source-index-stage1.yml | 49 ++++++++----- .../templates/job/source-index-stage1.yml | 44 ++++++++---- global.json | 6 +- 5 files changed, 118 insertions(+), 83 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3f51b32794afb6..9e7077e92e7ac9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -111,9 +111,9 @@ - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac @@ -121,69 +121,69 @@ 73f0850939d96131c28cf6ea6ee5aacb4da0083a - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac https://github.com/dotnet/runtime-assets @@ -334,9 +334,9 @@ https://github.com/dotnet/xharness 9d21162000c444b2da3d6cdd805d43e1af51453a - + https://github.com/dotnet/arcade - 188340e12c0a372b1681ad6a5e72c608021efdba + e6f70c7dd528f05cd28cec2a179d58c22e91d9ac https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index f5f01e6504e0c1..fa91d8d68f319f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -87,21 +87,21 @@ 8.0.100 - 8.0.0-beta.24204.3 - 8.0.0-beta.24204.3 - 8.0.0-beta.24204.3 - 8.0.0-beta.24204.3 - 8.0.0-beta.24204.3 - 2.5.1-beta.24204.3 - 8.0.0-beta.24204.3 - 8.0.0-beta.24204.3 - 8.0.0-beta.24204.3 - 8.0.0-beta.24204.3 - 8.0.0-beta.24204.3 - 8.0.0-beta.24204.3 - 8.0.0-beta.24204.3 - 8.0.0-beta.24204.3 - 8.0.0-beta.24204.3 + 8.0.0-beta.24266.3 + 8.0.0-beta.24266.3 + 8.0.0-beta.24266.3 + 8.0.0-beta.24266.3 + 8.0.0-beta.24266.3 + 2.5.1-beta.24266.3 + 8.0.0-beta.24266.3 + 8.0.0-beta.24266.3 + 8.0.0-beta.24266.3 + 8.0.0-beta.24266.3 + 8.0.0-beta.24266.3 + 8.0.0-beta.24266.3 + 8.0.0-beta.24266.3 + 8.0.0-beta.24266.3 + 8.0.0-beta.24266.3 6.0.0-preview.1.102 diff --git a/eng/common/templates-official/job/source-index-stage1.yml b/eng/common/templates-official/job/source-index-stage1.yml index f0513aee5b0da6..43ee0c202fc792 100644 --- a/eng/common/templates-official/job/source-index-stage1.yml +++ b/eng/common/templates-official/job/source-index-stage1.yml @@ -1,6 +1,7 @@ parameters: runAsPublic: false - sourceIndexPackageVersion: 1.0.1-20230228.2 + sourceIndexUploadPackageVersion: 2.0.0-20240502.12 + sourceIndexProcessBinlogPackageVersion: 1.0.1-20240129.2 sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" preSteps: [] @@ -14,15 +15,15 @@ jobs: dependsOn: ${{ parameters.dependsOn }} condition: ${{ parameters.condition }} variables: - - name: SourceIndexPackageVersion - value: ${{ parameters.sourceIndexPackageVersion }} + - name: SourceIndexUploadPackageVersion + value: ${{ parameters.sourceIndexUploadPackageVersion }} + - name: SourceIndexProcessBinlogPackageVersion + value: ${{ parameters.sourceIndexProcessBinlogPackageVersion }} - name: SourceIndexPackageSource value: ${{ parameters.sourceIndexPackageSource }} - name: BinlogPath value: ${{ parameters.binlogPath }} - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: source-dot-net stage1 variables - - template: /eng/common/templates-official/variables/pool-providers.yml + - template: /eng/common/templates/variables/pool-providers.yml ${{ if ne(parameters.pool, '') }}: pool: ${{ parameters.pool }} @@ -33,24 +34,23 @@ jobs: demands: ImageOverride -equals windows.vs2019.amd64.open ${{ if eq(variables['System.TeamProject'], 'internal') }}: name: $(DncEngInternalBuildPool) - image: windows.vs2022.amd64 - os: windows + demands: ImageOverride -equals windows.vs2019.amd64 steps: - ${{ each preStep in parameters.preSteps }}: - ${{ preStep }} - task: UseDotNet@2 - displayName: Use .NET Core SDK 6 + displayName: Use .NET 8 SDK inputs: packageType: sdk - version: 6.0.x + version: 8.0.x installationPath: $(Agent.TempDirectory)/dotnet workingDirectory: $(Agent.TempDirectory) - script: | - $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools - $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(sourceIndexProcessBinlogPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(sourceIndexUploadPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools displayName: Download Tools # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. workingDirectory: $(Agent.TempDirectory) @@ -62,7 +62,24 @@ jobs: displayName: Process Binlog into indexable sln - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) - displayName: Upload stage1 artifacts to source index - env: - BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url) + - task: AzureCLI@2 + displayName: Get stage 1 auth token + inputs: + azureSubscription: 'SourceDotNet Stage1 Publish' + addSpnToEnvironment: true + scriptType: 'ps' + scriptLocation: 'inlineScript' + inlineScript: | + echo "##vso[task.setvariable variable=ARM_CLIENT_ID]$env:servicePrincipalId" + echo "##vso[task.setvariable variable=ARM_ID_TOKEN]$env:idToken" + echo "##vso[task.setvariable variable=ARM_TENANT_ID]$env:tenantId" + + - script: | + echo "Client ID: $(ARM_CLIENT_ID)" + echo "ID Token: $(ARM_ID_TOKEN)" + echo "Tenant ID: $(ARM_TENANT_ID)" + az login --service-principal -u $(ARM_CLIENT_ID) --tenant $(ARM_TENANT_ID) --allow-no-subscriptions --federated-token $(ARM_ID_TOKEN) + displayName: "Login to Azure" + + - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1 + displayName: Upload stage1 artifacts to source index \ No newline at end of file diff --git a/eng/common/templates/job/source-index-stage1.yml b/eng/common/templates/job/source-index-stage1.yml index b98202aa02d824..43ee0c202fc792 100644 --- a/eng/common/templates/job/source-index-stage1.yml +++ b/eng/common/templates/job/source-index-stage1.yml @@ -1,6 +1,7 @@ parameters: runAsPublic: false - sourceIndexPackageVersion: 1.0.1-20230228.2 + sourceIndexUploadPackageVersion: 2.0.0-20240502.12 + sourceIndexProcessBinlogPackageVersion: 1.0.1-20240129.2 sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" preSteps: [] @@ -14,14 +15,14 @@ jobs: dependsOn: ${{ parameters.dependsOn }} condition: ${{ parameters.condition }} variables: - - name: SourceIndexPackageVersion - value: ${{ parameters.sourceIndexPackageVersion }} + - name: SourceIndexUploadPackageVersion + value: ${{ parameters.sourceIndexUploadPackageVersion }} + - name: SourceIndexProcessBinlogPackageVersion + value: ${{ parameters.sourceIndexProcessBinlogPackageVersion }} - name: SourceIndexPackageSource value: ${{ parameters.sourceIndexPackageSource }} - name: BinlogPath value: ${{ parameters.binlogPath }} - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: source-dot-net stage1 variables - template: /eng/common/templates/variables/pool-providers.yml ${{ if ne(parameters.pool, '') }}: @@ -40,16 +41,16 @@ jobs: - ${{ preStep }} - task: UseDotNet@2 - displayName: Use .NET Core SDK 6 + displayName: Use .NET 8 SDK inputs: packageType: sdk - version: 6.0.x + version: 8.0.x installationPath: $(Agent.TempDirectory)/dotnet workingDirectory: $(Agent.TempDirectory) - script: | - $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools - $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(sourceIndexProcessBinlogPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(sourceIndexUploadPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools displayName: Download Tools # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. workingDirectory: $(Agent.TempDirectory) @@ -61,7 +62,24 @@ jobs: displayName: Process Binlog into indexable sln - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) - displayName: Upload stage1 artifacts to source index - env: - BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url) + - task: AzureCLI@2 + displayName: Get stage 1 auth token + inputs: + azureSubscription: 'SourceDotNet Stage1 Publish' + addSpnToEnvironment: true + scriptType: 'ps' + scriptLocation: 'inlineScript' + inlineScript: | + echo "##vso[task.setvariable variable=ARM_CLIENT_ID]$env:servicePrincipalId" + echo "##vso[task.setvariable variable=ARM_ID_TOKEN]$env:idToken" + echo "##vso[task.setvariable variable=ARM_TENANT_ID]$env:tenantId" + + - script: | + echo "Client ID: $(ARM_CLIENT_ID)" + echo "ID Token: $(ARM_ID_TOKEN)" + echo "Tenant ID: $(ARM_TENANT_ID)" + az login --service-principal -u $(ARM_CLIENT_ID) --tenant $(ARM_TENANT_ID) --allow-no-subscriptions --federated-token $(ARM_ID_TOKEN) + displayName: "Login to Azure" + + - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1 + displayName: Upload stage1 artifacts to source index \ No newline at end of file diff --git a/global.json b/global.json index e0a39423109f36..4a9225b709f773 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "8.0.101" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24204.3", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24204.3", - "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.24204.3", + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24266.3", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24266.3", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.24266.3", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6" From f87df2cb38a5b2088c3f796bd5704be44d28961a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 12:41:41 -0700 Subject: [PATCH 744/783] Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20240507.2 (#102431) Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.24163.3 -> To Version 8.0.0-alpha.1.24257.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9e7077e92e7ac9..bd1feb57131ce7 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -99,9 +99,9 @@ 16d77ddacb12870344abbc4831387cc3e8f97168 - + https://github.com/dotnet/source-build-reference-packages - 79827eed138fd2575a8b24820b4f385ee4ffb6e6 + 6ed73280a6d70f7e7ac39c86f2abe8c10983f0bb From 919e5b2b4995c0769f49d272042de50533b47c75 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 14:08:12 -0700 Subject: [PATCH 745/783] [release/8.0] Update dependencies from dotnet/emsdk (#102408) * Update dependencies from https://github.com/dotnet/emsdk build 20240517.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.6-servicing.24264.1 -> To Version 8.0.7-servicing.24267.1 * Update dependencies from https://github.com/dotnet/emsdk build 20240520.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.6-servicing.24264.1 -> To Version 8.0.7-servicing.24270.2 --------- Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/NuGet.config b/NuGet.config index 3e394d788ef3af..d74a62c8f125c8 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index bd1feb57131ce7..aba57a86483449 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,13 +90,13 @@ 45dd3a73dd5b64b010c4251303b3664bb30df029 - + https://github.com/dotnet/emsdk - 16d77ddacb12870344abbc4831387cc3e8f97168 + a3c7d8205559d673de8b7cdafd6d80d5f4d2cfed - + https://github.com/dotnet/emsdk - 16d77ddacb12870344abbc4831387cc3e8f97168 + a3c7d8205559d673de8b7cdafd6d80d5f4d2cfed diff --git a/eng/Versions.props b/eng/Versions.props index fa91d8d68f319f..c723e90c1bf1c3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.6 + 8.0.7 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda From 7650e52eed65b18feeb6c01b2f07228d1eafccc6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 14:44:55 -0700 Subject: [PATCH 746/783] Update dependencies from https://github.com/dotnet/source-build-externals build 20240519.1 (#102453) Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24263.1 -> To Version 8.0.0-alpha.1.24269.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 77cf3d794bd856..6d47402004470e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -104,9 +104,9 @@ 6ed73280a6d70f7e7ac39c86f2abe8c10983f0bb - + https://github.com/dotnet/source-build-externals - a3021ef9ed72d7bdf799092a47d2d024fc13bfcd + 4f2151df120194f0268944f1b723c14820738fc8 From 3ee9306680508d33d56a7cb2bb101d97d0efed3b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 14:45:44 -0700 Subject: [PATCH 747/783] Update dependencies from https://github.com/dotnet/xharness build 20240429.2 (#102433) Microsoft.DotNet.XHarness.CLI , Microsoft.DotNet.XHarness.TestRunners.Common , Microsoft.DotNet.XHarness.TestRunners.Xunit From Version 8.0.0-prerelease.24208.4 -> To Version 8.0.0-prerelease.24229.2 Co-authored-by: dotnet-maestro[bot] --- .config/dotnet-tools.json | 2 +- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index deb9fb7b21bbe9..a42011c11afee7 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "8.0.0-prerelease.24208.4", + "version": "8.0.0-prerelease.24229.2", "commands": [ "xharness" ] diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6d47402004470e..3a2af9bbaf8539 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -322,17 +322,17 @@ https://github.com/dotnet/runtime edbd5c769a19798b6955050baccf99e6797d3208 - + https://github.com/dotnet/xharness - 9d21162000c444b2da3d6cdd805d43e1af51453a + aacfb6328fdef17e572617bbb551431bb9cb1ff2 - + https://github.com/dotnet/xharness - 9d21162000c444b2da3d6cdd805d43e1af51453a + aacfb6328fdef17e572617bbb551431bb9cb1ff2 - + https://github.com/dotnet/xharness - 9d21162000c444b2da3d6cdd805d43e1af51453a + aacfb6328fdef17e572617bbb551431bb9cb1ff2 https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index 677bef5639bf56..f58fcfb6965db8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -183,9 +183,9 @@ 1.1.0 17.4.0-preview-20220707-01 - 8.0.0-prerelease.24208.4 - 8.0.0-prerelease.24208.4 - 8.0.0-prerelease.24208.4 + 8.0.0-prerelease.24229.2 + 8.0.0-prerelease.24229.2 + 8.0.0-prerelease.24229.2 8.0.0-alpha.0.24229.2 2.4.2 1.0.0 From abbf9c6f7c9f1dab403eff742683e2c3e5dc29ac Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 19:02:36 -0700 Subject: [PATCH 748/783] Update PGO to use the correct post-build steps model (#102527) --- eng/pipelines/runtime-official.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index 6e6781bb134d5d..d84f414f4657ce 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -604,9 +604,10 @@ extends: buildArgs: -s clr.native+clr.corelib+clr.tools+clr.nativecorelib+libs+host+packs -c $(_BuildConfig) -pgoinstrument isOfficialBuild: ${{ variables.isOfficialBuild }} nameSuffix: PGO - extraStepsTemplate: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - extraStepsParameters: - name: PGO + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: PGO timeoutInMinutes: 95 # From 0be90100caf4dda8ebaa64a9c3abd1f4ec26299a Mon Sep 17 00:00:00 2001 From: Nikola Milosavljevic Date: Thu, 23 May 2024 09:31:54 -0700 Subject: [PATCH 749/783] Update condition for NETStandard 2.1 Targeting Pack build (#102507) --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index f58fcfb6965db8..26f979c5617d2f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -264,8 +264,8 @@ - true + true From 44d824898bb9b1f632887566131e7ef5b5ad1295 Mon Sep 17 00:00:00 2001 From: Ivan Povazan <55002338+ivanpovazan@users.noreply.github.com> Date: Fri, 24 May 2024 11:38:02 +0200 Subject: [PATCH 750/783] Remove linux-arm as supported RID for NativeAOT (#102072) Fixes https://github.com/dotnet/runtime/issues/100929 --- .../projects/Microsoft.DotNet.ILCompiler/ILCompilerRIDs.props | 1 - 1 file changed, 1 deletion(-) diff --git a/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/ILCompilerRIDs.props b/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/ILCompilerRIDs.props index 1d51a78880ae2d..7cbe74757e28f5 100644 --- a/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/ILCompilerRIDs.props +++ b/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/ILCompilerRIDs.props @@ -2,7 +2,6 @@ - From 984885ca9d99593dfbc23ce1a208e13bbb6a5c4e Mon Sep 17 00:00:00 2001 From: Juan Hoyos <19413848+hoyosjs@users.noreply.github.com> Date: Fri, 24 May 2024 10:38:57 -0700 Subject: [PATCH 751/783] [release/8.0] Use V5 ESRP task with backing MI + AKV (#102582) --- .../coreclr/templates/sign-diagnostic-files.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/coreclr/templates/sign-diagnostic-files.yml b/eng/pipelines/coreclr/templates/sign-diagnostic-files.yml index 89cbbec6390df9..ed1f8523925846 100644 --- a/eng/pipelines/coreclr/templates/sign-diagnostic-files.yml +++ b/eng/pipelines/coreclr/templates/sign-diagnostic-files.yml @@ -12,10 +12,15 @@ steps: version: '6.0.x' installationPath: '$(Agent.TempDirectory)/dotnet' - - task: EsrpCodeSigning@1 + - task: EsrpCodeSigning@5 displayName: Sign Diagnostic Binaries inputs: - ConnectedServiceName: 'dotnetesrp-diagnostics-dnceng' + ConnectedServiceName: 'diagnostics-esrp-kvcertuser' + AppRegistrationClientId: '2234cdec-a13f-4bb2-aa63-04c57fd7a1f9' + AppRegistrationTenantId: '72f988bf-86f1-41af-91ab-2d7cd011db47' + AuthAKVName: 'clrdiag-esrp-id' + AuthCertName: 'dotnetesrp-diagnostics-aad-ssl-cert' + AuthSignCertName: 'dotnet-diagnostics-esrp-pki-onecert' FolderPath: ${{ parameters.basePath }} Pattern: | **/mscordaccore*.dll @@ -48,6 +53,7 @@ steps: SessionTimeout: ${{ parameters.timeoutInMinutes }} MaxConcurrency: '50' MaxRetryAttempts: '5' + PendingAnalysisWaitTimeoutMinutes: '5' env: DOTNET_MULTILEVEL_LOOKUP: 0 DOTNET_ROOT: '$(Agent.TempDirectory)/dotnet' From 48a9496667c8437db38177ba3f05f635bc189dfb Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Tue, 28 May 2024 21:41:04 -0400 Subject: [PATCH 752/783] [release/8.0] Fix cancellation unregistration in DataflowBlock.OutputAvailableAsync (#102376) * Fix cancellation unregistration in DataflowBlock.OutputAvailableAsync (#99632) OutputAvailableAsync is not unregistering from the supplied CancellationToken. If a cancelable token is supplied and is long lived, each call with that token to OutputAvailableAsync will add another callback into that token, and that will continue to grow until either the token is dropped or has been cancellation requested. For a long-lived cancellation token, this is akin to a leak. The implementation was trying to be too clever in avoiding an additional continuation that was previously there. However, this continuation makes it a lot easier to avoid possible deadlocks that can occur if a cancellation request comes in concurrently with a message being pushed. Instead of trying to avoid it, just use an async method, which still incurs the extra task but does so with less allocation and greatly simplifies the code while also fixing the issue, as all cleanup can now be done in the continuation as part of the async method. * Enable DataFlow package in servicing --------- Co-authored-by: Eric StJohn --- .../src/Base/DataflowBlock.cs | 131 +++++------------- .../System.Threading.Tasks.Dataflow.csproj | 2 + 2 files changed, 39 insertions(+), 94 deletions(-) diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.cs index 63cdedf4b466a6..7007b0c80f5f7a 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.cs @@ -1434,63 +1434,48 @@ public static Task OutputAvailableAsync(this ISourceBlock OutputAvailableAsync( this ISourceBlock source, CancellationToken cancellationToken) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - // Fast path for cancellation - if (cancellationToken.IsCancellationRequested) - return Common.CreateTaskFromCancellation(cancellationToken); - - // In a method like this, normally we would want to check source.Completion.IsCompleted - // and avoid linking completely by simply returning a completed task. However, - // some blocks that are completed still have data available, like WriteOnceBlock, - // which completes as soon as it gets a value and stores that value forever. - // As such, OutputAvailableAsync must link from the source so that the source - // can push data to us if it has it, at which point we can immediately unlink. + return + source is null ? throw new ArgumentNullException(nameof(source)) : + cancellationToken.IsCancellationRequested ? Common.CreateTaskFromCancellation(cancellationToken) : + Impl(source, cancellationToken); - // Create a target task that will complete when it's offered a message (but it won't accept the message) - var target = new OutputAvailableAsyncTarget(); - try + static async Task Impl(ISourceBlock source, CancellationToken cancellationToken) { - // Link from the source. If the source propagates a message during or immediately after linking - // such that our target is already completed, just return its task. - target._unlinker = source.LinkTo(target, DataflowLinkOptions.UnlinkAfterOneAndPropagateCompletion); + // In a method like this, normally we would want to check source.Completion.IsCompleted + // and avoid linking completely by simply returning a completed task. However, + // some blocks that are completed still have data available, like WriteOnceBlock, + // which completes as soon as it gets a value and stores that value forever. + // As such, OutputAvailableAsync must link from the source so that the source + // can push data to us if it has it, at which point we can immediately unlink. - // If the task is already completed (an exception may have occurred, or the source may have propagated - // a message to the target during LinkTo or soon thereafter), just return the task directly. - if (target.Task.IsCompleted) - { - return target.Task; - } + // Create a target task that will complete when it's offered a message (but it won't accept the message) + var target = new OutputAvailableAsyncTarget(); - // If cancellation could be requested, hook everything up to be notified of cancellation requests. - if (cancellationToken.CanBeCanceled) + // Link from the source. + using (source.LinkTo(target, DataflowLinkOptions.UnlinkAfterOneAndPropagateCompletion)) { - // When cancellation is requested, unlink the target from the source and cancel the target. - target._ctr = cancellationToken.Register( + CancellationTokenRegistration registration = default; + try + { + // Register for cancellation if the target isn't already completed (the source may have propagated + // a message to the target during LinkTo or soon thereafter). + if (!target.Task.IsCompleted) + { + registration = #if NET6_0_OR_GREATER - OutputAvailableAsyncTarget.CancelAndUnlink, + cancellationToken.UnsafeRegister(static (state, cancellationToken) => ((OutputAvailableAsyncTarget)state!).TrySetCanceled(cancellationToken), target); #else - static state => OutputAvailableAsyncTarget.CancelAndUnlink(state, default), + cancellationToken.Register(static state => ((OutputAvailableAsyncTarget)state!).TrySetCanceled(), target); #endif - target); - } - - return target.Task; - } - catch (Exception exc) - { - // Source.LinkTo could throw, as could cancellationToken.Register if cancellation was already requested - // such that it synchronously invokes the source's unlinker IDisposable, which could throw. - target.TrySetException(exc); - - // Undo the link from the source to the target - target.AttemptThreadSafeUnlink(); + } - // Return the now faulted task - return target.Task; + return await target.Task.ConfigureAwait(false); + } + finally + { + registration.Dispose(); + } + } } } @@ -1504,46 +1489,6 @@ public OutputAvailableAsyncTarget() : { } - /// - /// Cached continuation delegate that unregisters from cancellation and - /// marshals the antecedent's result to the return value. - /// - internal static readonly Func, object?, bool> s_handleCompletion = (antecedent, state) => - { - var target = state as OutputAvailableAsyncTarget; - Debug.Assert(target != null, "Expected non-null target"); - target._ctr.Dispose(); - return antecedent.GetAwaiter().GetResult(); - }; - - /// Cancels the target and unlinks the target from the source. - /// An OutputAvailableAsyncTarget. - /// The token that triggered cancellation - internal static void CancelAndUnlink(object? state, CancellationToken cancellationToken) - { - var target = state as OutputAvailableAsyncTarget; - Debug.Assert(target != null, "Expected a non-null target"); - - target.TrySetCanceled(cancellationToken); - target.AttemptThreadSafeUnlink(); - } - - /// Disposes of _unlinker if the target has been linked. - internal void AttemptThreadSafeUnlink() - { - // A race is possible. Therefore use an interlocked operation. - IDisposable? cachedUnlinker = _unlinker; - if (cachedUnlinker != null && Interlocked.CompareExchange(ref _unlinker, null, cachedUnlinker) == cachedUnlinker) - { - cachedUnlinker.Dispose(); - } - } - - /// The IDisposable used to unlink this target from its source. - internal IDisposable? _unlinker; - /// The registration used to unregister this target from the cancellation token. - internal CancellationTokenRegistration _ctr; - /// Completes the task when offered a message (but doesn't consume the message). DataflowMessageStatus ITargetBlock.OfferMessage(DataflowMessageHeader messageHeader, T messageValue, ISourceBlock? source, bool consumeToAccept) { @@ -1551,14 +1496,12 @@ DataflowMessageStatus ITargetBlock.OfferMessage(DataflowMessageHeader message if (source == null) throw new ArgumentNullException(nameof(source)); TrySetResult(true); + return DataflowMessageStatus.DecliningPermanently; } /// - void IDataflowBlock.Complete() - { - TrySetResult(false); - } + void IDataflowBlock.Complete() => TrySetResult(false); /// void IDataflowBlock.Fault(Exception exception) @@ -1572,13 +1515,13 @@ void IDataflowBlock.Fault(Exception exception) } /// - Task IDataflowBlock.Completion { get { throw new NotSupportedException(SR.NotSupported_MemberNotNeeded); } } + Task IDataflowBlock.Completion => throw new NotSupportedException(SR.NotSupported_MemberNotNeeded); /// The data to display in the debugger display attribute. private object DebuggerDisplayContent => $"{Common.GetNameForDebugger(this)} IsCompleted = {base.Task.IsCompleted}"; /// Gets the data to display in the debugger display attribute for this instance. - object IDebuggerDisplay.Content { get { return DebuggerDisplayContent; } } + object IDebuggerDisplay.Content => DebuggerDisplayContent; } #endregion diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj b/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj index 9835aa30e3b35a..3a4156130e82f9 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj @@ -2,6 +2,8 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.1;netstandard2.0;$(NetFrameworkMinimum) true + true + 1 TPL Dataflow promotes actor/agent-oriented designs through primitives for in-process message passing, dataflow, and pipelining. TDF builds upon the APIs and scheduling infrastructure provided by the Task Parallel Library (TPL), and integrates with the language support for asynchrony provided by C#, Visual Basic, and F#. Commonly Used Types: From 7b08fa8922f90028efd64f2d3a1fbb51165d07e3 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Wed, 29 May 2024 11:00:49 +0300 Subject: [PATCH 753/783] [mono][interp] Keep delegate alive during invocation (#100832) (#102159) When invoking a delegate, we were overwritting the stack slot containing the delegate object reference. In the case of invoking a delegate for a dynamic method, we were running into issues when the delegate object is collected while the method is executed because the method code is also discarded. --- src/mono/mono/mini/interp/interp-internals.h | 1 + src/mono/mono/mini/interp/interp.c | 3 +++ src/mono/mono/mini/interp/transform.c | 21 ++++++++++++++++++++ src/mono/mono/mini/interp/transform.h | 1 + 4 files changed, 26 insertions(+) diff --git a/src/mono/mono/mini/interp/interp-internals.h b/src/mono/mono/mini/interp/interp-internals.h index 4e0be7db043348..79b93dae1fb5f8 100644 --- a/src/mono/mono/mini/interp/interp-internals.h +++ b/src/mono/mono/mini/interp/interp-internals.h @@ -153,6 +153,7 @@ struct InterpMethod { unsigned int hasthis; // boolean MonoProfilerCallInstrumentationFlags prof_flags; InterpMethodCodeType code_type; + int ref_slot_offset; // GC visible pointer slot #ifdef ENABLE_EXPERIMENT_TIERED MiniTieredCounter tiered_counter; #endif diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 620dc135d50f27..2942fb23d3f82f 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -4047,6 +4047,9 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause } cmethod = del_imethod; if (!is_multicast) { + int ref_slot_offset = frame->imethod->ref_slot_offset; + if (ref_slot_offset >= 0) + LOCAL_VAR (ref_slot_offset, gpointer) = del; if (cmethod->param_count == param_count + 1) { // Target method is static but the delegate has a target object. We handle // this separately from the case below, because, for these calls, the instance diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 0d5ef5380de266..0150c3d32e3e03 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -412,6 +412,17 @@ create_interp_dummy_var (TransformData *td) td->locals [td->dummy_var].flags = INTERP_LOCAL_FLAG_GLOBAL; } +static int alloc_global_var_offset (TransformData *td, int var); + +static void +interp_create_ref_handle_var (TransformData *td) +{ + int var = create_interp_local_explicit (td, m_class_get_byval_arg (mono_defaults.int_class), sizeof (gpointer)); + td->locals [var].flags = INTERP_LOCAL_FLAG_GLOBAL; + alloc_global_var_offset (td, var); + td->ref_handle_var = var; +} + static int get_tos_offset (TransformData *td) { @@ -3798,6 +3809,10 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target td->last_ins->data [0] = get_data_item_index_imethod (td, mono_interp_get_imethod (target_method)); } else { if (is_delegate_invoke) { + // MINT_CALL_DELEGATE will store the delegate object into this slot so it is kept alive + // while the method is invoked + if (td->ref_handle_var == -1) + interp_create_ref_handle_var (td); interp_add_ins (td, MINT_CALL_DELEGATE); interp_ins_set_dreg (td->last_ins, dreg); interp_ins_set_sreg (td->last_ins, MINT_CALL_ARGS_SREG); @@ -11149,6 +11164,7 @@ generate (MonoMethod *method, MonoMethodHeader *header, InterpMethod *rtm, MonoG td->n_data_items = 0; td->max_data_items = 0; td->dummy_var = -1; + td->ref_handle_var = -1; td->data_items = NULL; td->data_hash = g_hash_table_new (NULL, NULL); #ifdef ENABLE_EXPERIMENT_TIERED @@ -11287,6 +11303,11 @@ generate (MonoMethod *method, MonoMethodHeader *header, InterpMethod *rtm, MonoG mono_interp_register_imethod_data_items (rtm->data_items, td->imethod_items); rtm->patchpoint_data = td->patchpoint_data; + if (td->ref_handle_var != -1) + rtm->ref_slot_offset = td->locals [td->ref_handle_var].offset; + else + rtm->ref_slot_offset = -1; + /* Save debug info */ interp_save_debug_info (rtm, header, td, td->line_numbers); diff --git a/src/mono/mono/mini/interp/transform.h b/src/mono/mono/mini/interp/transform.h index 2bfbe42390510e..c9ff2df80a598c 100644 --- a/src/mono/mono/mini/interp/transform.h +++ b/src/mono/mono/mini/interp/transform.h @@ -227,6 +227,7 @@ typedef struct gint32 max_stack_size; InterpLocal *locals; int dummy_var; + int ref_handle_var; int *local_ref_count; unsigned int il_locals_offset; unsigned int il_locals_size; From 32400f6b367f3ac34182c00710a62a19a9ef2161 Mon Sep 17 00:00:00 2001 From: Eduardo Velarde <32459232+eduardo-vp@users.noreply.github.com> Date: Wed, 29 May 2024 11:10:33 -0700 Subject: [PATCH 754/783] [release/8.0-staging] Backport 1ES templates (#102681) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [mono][infra] Fix mono-aot-cross build for linux-arm64 using biarch image (#91019) * Use host rootfs when TARGET_BUILD_ARCH matches * Don't build libraries native packages in the PGO leg (#92729) * Reenable OneLocBuild in runtime-official.yml (#95014) * Move FreeBSD CI leg to CBL-Mariner and v13 (#97038) * Use Ubuntu-22.04-based Tizen image (#98589) * Start moving over to official templates (#99433) * Start moving over to official templates * Parameterize runtime-inner-loop * Use default false for isOfficialBuild in pipeline-with-resources * Respond to PR comments * Code review comments * Use default template args * Move linux_x86, tizen_armel, and freebsd_x64 jobs to global-build.yml * Update thunktemplates.S (#100066) * Import pool providers (#100851) Import pool-providers in common variables. This should allow all stages access to the pool provider variables. * Pass templatePath to eng/pipelines/common/templates/runtimes/xplat-job.yml --------- Co-authored-by: Milos Kotlar Co-authored-by: Jeremy Koritzinsky Co-authored-by: Alexander Köplinger Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com> Co-authored-by: Andy Gocke Co-authored-by: Filip Navara Co-authored-by: Eduardo Manuel Velarde Polar --- eng/pipelines/common/global-build-job.yml | 30 ++- .../templates/pipeline-with-resources.yml | 231 +++++++++--------- .../templates/publish-build-artifacts.yml | 22 ++ .../templates/publish-pipeline-artifacts.yml | 17 ++ .../templates/runtimes/build-test-job.yml | 18 +- .../common/templates/runtimes/xplat-job.yml | 3 +- .../common/templates/template1es.yml | 31 +++ .../common/templates/templateDispatch.yml | 13 + .../common/templates/templatePublic.yml | 21 ++ eng/pipelines/common/upload-artifact-step.yml | 15 +- .../upload-intermediate-artifacts-step.yml | 14 +- eng/pipelines/common/variables.yml | 7 + eng/pipelines/common/xplat-setup.yml | 15 +- .../coreclr/templates/xplat-pipeline-job.yml | 2 + eng/pipelines/global-build.yml | 95 +++++++ .../mono/templates/generate-offsets.yml | 30 ++- .../mono/templates/workloads-build.yml | 18 +- .../mono/templates/xplat-pipeline-job.yml | 2 + .../jobs/prepare-signed-artifacts.yml | 17 +- eng/pipelines/official/stages/publish.yml | 6 +- eng/pipelines/runtime-official.yml | 46 +++- eng/pipelines/runtime.yml | 47 +--- src/coreclr/debug/daccess/CMakeLists.txt | 2 +- src/coreclr/vm/arm/thunktemplates.S | 2 +- src/mono/mono.proj | 12 +- 25 files changed, 478 insertions(+), 238 deletions(-) create mode 100644 eng/pipelines/common/templates/publish-build-artifacts.yml create mode 100644 eng/pipelines/common/templates/publish-pipeline-artifacts.yml create mode 100644 eng/pipelines/common/templates/template1es.yml create mode 100644 eng/pipelines/common/templates/templateDispatch.yml create mode 100644 eng/pipelines/common/templates/templatePublic.yml diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index 4b06818b1408c5..86cea9fbd98a20 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -30,9 +30,10 @@ parameters: extraVariablesTemplates: [] isManualCodeQLBuild: false preBuildSteps: [] + templatePath: 'templates' jobs: -- template: /eng/common/templates/job/job.yml +- template: /eng/common/${{ parameters.templatePath }}/job/job.yml parameters: ${{ if eq(parameters.hostedOs, '') }}: name: ${{ format('build_{0}{1}_{2}_{3}_{4}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.nameSuffix) }} @@ -141,6 +142,7 @@ jobs: - ${{ each variable in parameters.variables }}: - ${{ variable }} + steps: - ${{ if eq(parameters.osGroup, 'windows') }}: - template: /eng/pipelines/common/templates/disable-vsupdate-or-failfast.yml @@ -181,7 +183,7 @@ jobs: path: '$(Build.SourcesDirectory)/artifacts/obj/mono/offsetfiles' - ${{ if eq(parameters.isSourceBuild, true) }}: - - template: /eng/common/templates/steps/source-build.yml + - template: /eng/common/${{ parameters.templatePath }}/steps/source-build.yml parameters: platform: baseOS: ${{ parameters.baseOS }} @@ -285,14 +287,16 @@ jobs: displayName: Collect vslogs on exit condition: always() - - task: PublishBuildArtifacts@1 - displayName: Publish Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/' - PublishLocation: Container - ${{ if notin(parameters.osGroup, 'browser', 'wasi') }}: - ArtifactName: Logs_Build_Attempt$(System.JobAttempt)_${{ parameters.osGroup }}_${{ parameters.osSubGroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}_${{ parameters.nameSuffix }} - ${{ if in(parameters.osGroup, 'browser', 'wasi') }}: - ArtifactName: Logs_Build_Attempt$(System.JobAttempt)_${{ parameters.osGroup }}_${{ parameters.archType }}_${{ parameters.hostedOs }}_${{ parameters.buildConfig }}_${{ parameters.nameSuffix }} - continueOnError: true - condition: always() + - template: /eng/pipelines/common/templates/publish-build-artifacts.yml + parameters: + isOfficialBuild: ${{ parameters.isOfficialBuild }} + displayName: Publish Logs + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/' + PublishLocation: Container + ${{ if notin(parameters.osGroup, 'browser', 'wasi') }}: + ArtifactName: Logs_Build_Attempt$(System.JobAttempt)_${{ parameters.osGroup }}_${{ parameters.osSubGroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}_${{ parameters.nameSuffix }} + ${{ if in(parameters.osGroup, 'browser', 'wasi') }}: + ArtifactName: Logs_Build_Attempt$(System.JobAttempt)_${{ parameters.osGroup }}_${{ parameters.archType }}_${{ parameters.hostedOs }}_${{ parameters.buildConfig }}_${{ parameters.nameSuffix }} + continueOnError: true + condition: always() diff --git a/eng/pipelines/common/templates/pipeline-with-resources.yml b/eng/pipelines/common/templates/pipeline-with-resources.yml index edba5767b612c5..f5fd4abbd25bf8 100644 --- a/eng/pipelines/common/templates/pipeline-with-resources.yml +++ b/eng/pipelines/common/templates/pipeline-with-resources.yml @@ -1,113 +1,124 @@ parameters: - name: stages type: stageList - -resources: - containers: - - container: linux_arm - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm - env: - ROOTFS_DIR: /crossrootfs/arm - - - container: linux_armv6 - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-cross-armv6-raspbian-10 - env: - ROOTFS_DIR: /crossrootfs/armv6 - - - container: linux_arm64 - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm64 - env: - ROOTFS_DIR: /crossrootfs/arm64 - - - container: linux_musl_x64 - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-amd64-alpine - env: - ROOTFS_DIR: /crossrootfs/x64 - - - container: linux_musl_arm - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm-alpine - env: - ROOTFS_DIR: /crossrootfs/arm - - - container: linux_musl_arm64 - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm64-alpine - env: - ROOTFS_DIR: /crossrootfs/arm64 - - # This container contains all required toolsets to build for Android and for Linux with bionic libc. - - container: linux_bionic - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-android-amd64 - - # This container contains all required toolsets to build for Android as well as tooling to build docker images. - - container: android_docker - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-android-docker - - - container: linux_x64 - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-amd64 - env: - ROOTFS_DIR: /crossrootfs/x64 - - - container: linux_x86 - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-x86 - env: - ROOTFS_DIR: /crossrootfs/x86 - - - container: linux_x64_dev_innerloop - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04 - - # We use a CentOS Stream 9 image here to test building from source on CentOS Stream 9. - - container: SourceBuild_centos_x64 - image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9 - - # AlmaLinux 8 is a RHEL 8 rebuild, so we use it to test building from source on RHEL 8. - - container: SourceBuild_linux_x64 - image: mcr.microsoft.com/dotnet-buildtools/prereqs:almalinux-8-source-build - - - container: linux_s390x - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-s390x - env: - ROOTFS_DIR: /crossrootfs/s390x - - - container: linux_ppc64le - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-ppc64le - env: - ROOTFS_DIR: /crossrootfs/ppc64le - - - container: linux_riscv64 - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-cross-riscv64 - env: - ROOTFS_DIR: /crossrootfs/riscv64 - - - container: debian-12-gcc13-amd64 - image: mcr.microsoft.com/dotnet-buildtools/prereqs:debian-12-gcc13-amd64 - - - container: linux_x64_llvmaot - image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9 - - - container: browser_wasm - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly-20230913040940-1edc1c6 - env: - ROOTFS_DIR: /crossrootfs/x64 - - - container: wasi_wasm - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly-20230913040940-1edc1c6 - env: - ROOTFS_DIR: /crossrootfs/x64 - - - container: freebsd_x64 - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-freebsd-12 - env: - ROOTFS_DIR: /crossrootfs/x64 - - - container: tizen_armel - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-armel-tizen - env: - ROOTFS_DIR: /crossrootfs/armel - - - container: debpkg - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-debpkg - - - container: rpmpkg - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-fpm - -stages: ${{ parameters.stages }} + - name: isOfficialBuild + type: boolean + default: false + +extends: + template: templateDispatch.yml + parameters: + ${{ if parameters.isOfficialBuild }}: + templatePath: template1es.yml + ${{ else }}: + templatePath: templatePublic.yml + + stages: ${{ parameters.stages }} + + containers: + linux_arm: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm + env: + ROOTFS_DIR: /crossrootfs/arm + + linux_armv6: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-cross-armv6-raspbian-10 + env: + ROOTFS_DIR: /crossrootfs/armv6 + + linux_arm64: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-biarch-amd64-arm64 + env: + ROOTFS_HOST_DIR: /crossrootfs/x64 + ROOTFS_DIR: /crossrootfs/arm64 + + linux_musl_x64: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-amd64-alpine + env: + ROOTFS_DIR: /crossrootfs/x64 + + linux_musl_arm: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm-alpine + env: + ROOTFS_DIR: /crossrootfs/arm + + linux_musl_arm64: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm64-alpine + env: + ROOTFS_DIR: /crossrootfs/arm64 + + # This container contains all required toolsets to build for Android and for Linux with bionic libc. + linux_bionic: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-android-amd64 + + # This container contains all required toolsets to build for Android as well as tooling to build docker images. + android_docker: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-android-docker + + linux_x64: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-amd64 + env: + ROOTFS_DIR: /crossrootfs/x64 + + linux_x86: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-x86 + env: + ROOTFS_DIR: /crossrootfs/x86 + + linux_x64_dev_innerloop: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04 + + # We use a CentOS Stream 9 image here to test building from source on CentOS Stream 9. + SourceBuild_centos_x64: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9 + + # AlmaLinux 8 is a RHEL 8 rebuild, so we use it to test building from source on RHEL 8. + SourceBuild_linux_x64: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:almalinux-8-source-build + + linux_s390x: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-s390x + env: + ROOTFS_DIR: /crossrootfs/s390x + + linux_ppc64le: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-ppc64le + env: + ROOTFS_DIR: /crossrootfs/ppc64le + + linux_riscv64: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-cross-riscv64 + env: + ROOTFS_DIR: /crossrootfs/riscv64 + + debian-12-gcc13-amd64: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:debian-12-gcc13-amd64 + + linux_x64_llvmaot: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9 + + browser_wasm: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly-20230913040940-1edc1c6 + env: + ROOTFS_DIR: /crossrootfs/x64 + + wasi_wasm: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-webassembly-20230913040940-1edc1c6 + env: + ROOTFS_DIR: /crossrootfs/x64 + + freebsd_x64: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-amd64-freebsd-13 + env: + ROOTFS_DIR: /crossrootfs/x64 + + tizen_armel: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-cross-armel-tizen + env: + ROOTFS_DIR: /crossrootfs/armel + + debpkg: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-debpkg + + rpmpkg: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-fpm \ No newline at end of file diff --git a/eng/pipelines/common/templates/publish-build-artifacts.yml b/eng/pipelines/common/templates/publish-build-artifacts.yml new file mode 100644 index 00000000000000..b9b263c361f890 --- /dev/null +++ b/eng/pipelines/common/templates/publish-build-artifacts.yml @@ -0,0 +1,22 @@ +parameters: + - name: isOfficialBuild + type: boolean + - name: displayName + type: string + - name: inputs + type: object + - name: condition + type: string + default: '' + +steps: + - ${{ if parameters.isOfficialBuild }}: + - task: 1ES.PublishBuildArtifacts@1 + displayName: ${{ parameters.displayName }} + inputs: ${{ parameters.inputs }} + condition: ${{ parameters.condition }} + - ${{ else }}: + - task: PublishBuildArtifacts@1 + displayName: ${{ parameters.displayName }} + inputs: ${{ parameters.inputs }} + condition: ${{ parameters.condition }} \ No newline at end of file diff --git a/eng/pipelines/common/templates/publish-pipeline-artifacts.yml b/eng/pipelines/common/templates/publish-pipeline-artifacts.yml new file mode 100644 index 00000000000000..81f292ec5528ce --- /dev/null +++ b/eng/pipelines/common/templates/publish-pipeline-artifacts.yml @@ -0,0 +1,17 @@ +parameters: +- name: displayName + type: string +- name: inputs + type: object +- name: isOfficialBuild + type: boolean + +steps: + - ${{ if parameters.isOfficialBuild }}: + - task: 1ES.PublishPipelineArtifact@1 + displayName: ${{ parameters.displayName }} + inputs: ${{ parameters.inputs }} + - ${{ else }}: + - task: PublishPipelineArtifact@1 + displayName: ${{ parameters.displayName }} + inputs: ${{ parameters.inputs }} \ No newline at end of file diff --git a/eng/pipelines/common/templates/runtimes/build-test-job.yml b/eng/pipelines/common/templates/runtimes/build-test-job.yml index e249e8ac922a7f..2809d1487700f6 100644 --- a/eng/pipelines/common/templates/runtimes/build-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/build-test-job.yml @@ -14,6 +14,7 @@ parameters: dependsOn: [] dependOnEvaluatePaths: false crossBuild: false + isOfficialBuild: false ### Build managed test components (native components are getting built as part ### of the product build job). @@ -142,12 +143,13 @@ jobs: artifactName: $(microsoftNetSdkIlArtifactName) displayName: 'Microsoft.NET.Sdk.IL package' - # Publish Logs - - task: PublishPipelineArtifact@1 - displayName: Publish Logs - inputs: - targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: '${{ parameters.runtimeFlavor }}_Common_Runtime_TestBuildLogs_Attempt$(System.JobAttempt)_AnyOS_AnyCPU_$(buildConfig)_${{ parameters.testGroup }}' - continueOnError: true - condition: always() + - template: /eng/pipelines/common/templates/publish-pipeline-artifacts.yml + parameters: + displayName: Publish Logs + isOfficialBuild: ${{ parameters.isOfficialBuild }} + inputs: + targetPath: $(Build.SourcesDirectory)/artifacts/log + ArtifactName: '${{ parameters.runtimeFlavor }}_Common_Runtime_TestBuildLogs_Attempt$(System.JobAttempt)_AnyOS_AnyCPU_$(buildConfig)_${{ parameters.testGroup }}' + continueOnError: true + condition: always() diff --git a/eng/pipelines/common/templates/runtimes/xplat-job.yml b/eng/pipelines/common/templates/runtimes/xplat-job.yml index 23e74c70e57ace..625d88d63d3e97 100644 --- a/eng/pipelines/common/templates/runtimes/xplat-job.yml +++ b/eng/pipelines/common/templates/runtimes/xplat-job.yml @@ -20,11 +20,12 @@ parameters: enableMicrobuild: '' gatherAssetManifests: false disableComponentGovernance: false + templatePath: 'templates' variables: {} ## any extra variables to add to the defaults defined below jobs: -- template: /eng/common/templates/job/job.yml +- template: /eng/common/${{ parameters.templatePath }}/job/job.yml parameters: name: ${{ parameters.name }} diff --git a/eng/pipelines/common/templates/template1es.yml b/eng/pipelines/common/templates/template1es.yml new file mode 100644 index 00000000000000..0770e37d6bd0ed --- /dev/null +++ b/eng/pipelines/common/templates/template1es.yml @@ -0,0 +1,31 @@ + + +parameters: + - name: templatePath + type: string + default: 'templates-official' + - name: stages + type: stageList + - name: containers + type: object + + +resources: + repositories: + - repository: 1ESPipelineTemplates + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release + +extends: + template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates + parameters: + pool: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022 + os: windows + + containers: + ${{ parameters.containers }} + + stages: ${{ parameters.stages }} \ No newline at end of file diff --git a/eng/pipelines/common/templates/templateDispatch.yml b/eng/pipelines/common/templates/templateDispatch.yml new file mode 100644 index 00000000000000..1860af47aeefff --- /dev/null +++ b/eng/pipelines/common/templates/templateDispatch.yml @@ -0,0 +1,13 @@ +parameters: + - name: templatePath + type: string + - name: stages + type: stageList + - name: containers + type: object + +extends: + template: ${{ parameters.templatePath }} + parameters: + stages: ${{ parameters.stages }} + containers: ${{ parameters.containers }} \ No newline at end of file diff --git a/eng/pipelines/common/templates/templatePublic.yml b/eng/pipelines/common/templates/templatePublic.yml new file mode 100644 index 00000000000000..cd7c02720167d5 --- /dev/null +++ b/eng/pipelines/common/templates/templatePublic.yml @@ -0,0 +1,21 @@ + +parameters: + - name: templatePath + type: string + default: 'templates' + - name: stages + type: stageList + - name: containers + type: object + +resources: + containers: + - ${{ each container_pair in parameters.containers }}: + - ${{ if container_pair.value.image }}: + - container: ${{ container_pair.key }} + ${{ each pair in container_pair.value }}: + ${{ if notIn(pair.key, 'tenantId', 'identityType', 'registry') }}: + ${{ pair.key }}: ${{ pair.value }} + + +stages: ${{ parameters.stages }} \ No newline at end of file diff --git a/eng/pipelines/common/upload-artifact-step.yml b/eng/pipelines/common/upload-artifact-step.yml index 249da066c7aae6..d4091a7cc192f5 100644 --- a/eng/pipelines/common/upload-artifact-step.yml +++ b/eng/pipelines/common/upload-artifact-step.yml @@ -7,6 +7,7 @@ parameters: artifactName: '' displayName: '' condition: succeeded() + isOfficialBuild: false steps: # Zip Artifact @@ -20,9 +21,11 @@ steps: includeRootFolder: ${{ parameters.includeRootFolder }} condition: ${{ parameters.condition }} - - task: PublishBuildArtifacts@1 - displayName: 'Publish ${{ parameters.displayName }}' - inputs: - pathtoPublish: $(Build.StagingDirectory)/${{ parameters.artifactName }}${{ parameters.archiveExtension }} - artifactName: ${{ parameters.artifactName }} - condition: ${{ parameters.condition }} + - template: /eng/pipelines/common/templates/publish-build-artifacts.yml + parameters: + isOfficialBuild: ${{ parameters.isOfficialBuild }} + displayName: 'Publish ${{ parameters.displayName }}' + inputs: + PathtoPublish: $(Build.StagingDirectory)/${{ parameters.artifactName }}${{ parameters.archiveExtension }} + artifactName: ${{ parameters.artifactName }} + condition: ${{ parameters.condition }} \ No newline at end of file diff --git a/eng/pipelines/common/upload-intermediate-artifacts-step.yml b/eng/pipelines/common/upload-intermediate-artifacts-step.yml index bde6c61a0a04ad..da9b1ef0b627fd 100644 --- a/eng/pipelines/common/upload-intermediate-artifacts-step.yml +++ b/eng/pipelines/common/upload-intermediate-artifacts-step.yml @@ -25,9 +25,11 @@ steps: TargetFolder: '$(Build.StagingDirectory)/IntermediateArtifacts/${{ parameters.name }}' CleanTargetFolder: true -- task: PublishBuildArtifacts@1 - displayName: Publish intermediate artifacts - inputs: - pathToPublish: '$(Build.StagingDirectory)/IntermediateArtifacts' - artifactName: IntermediateArtifacts - artifactType: container +- template: /eng/pipelines/common/templates/publish-build-artifacts.yml + parameters: + isOfficialBuild: true + displayName: Publish intermediate artifacts + inputs: + PathtoPublish: '$(Build.StagingDirectory)/IntermediateArtifacts' + ArtifactName: IntermediateArtifacts + ArtifactType: container diff --git a/eng/pipelines/common/variables.yml b/eng/pipelines/common/variables.yml index 2a757f82572ad3..075dea178ab623 100644 --- a/eng/pipelines/common/variables.yml +++ b/eng/pipelines/common/variables.yml @@ -1,3 +1,8 @@ +parameters: + - name: templatePath + type: string + default: 'templates' + variables: # These values enable longer delays, configurable number of retries, and special understanding of TCP hang-up @@ -54,3 +59,5 @@ variables: eq(variables['isRollingBuild'], true))) ] - template: /eng/pipelines/common/perf-variables.yml + +- template: /eng/common/${{ parameters.templatePath }}/variables/pool-providers.yml \ No newline at end of file diff --git a/eng/pipelines/common/xplat-setup.yml b/eng/pipelines/common/xplat-setup.yml index 675a2679201861..794a23bb218b5e 100644 --- a/eng/pipelines/common/xplat-setup.yml +++ b/eng/pipelines/common/xplat-setup.yml @@ -22,7 +22,7 @@ jobs: dependOnEvaluatePaths: ${{ and(eq(variables['Build.Reason'], 'PullRequest'), in(variables['Build.DefinitionName'], 'runtime', 'runtime-community', 'runtime-extra-platforms', 'runtime-wasm', 'runtime-wasm-libtests', 'runtime-wasm-non-libtests', 'dotnet-linker-tests', 'runtime-dev-innerloop', 'runtime-coreclr superpmi-replay', 'runtime-coreclr superpmi-diffs')) }} variables: - - template: /eng/common/templates/variables/pool-providers.yml + - template: /eng/common/${{ coalesce(parameters.jobParameters.templatePath, 'templates') }}/variables/pool-providers.yml # Disable component governance in our CI builds. These builds are not shipping nor # are they a service. Also the component governance jobs issue lots of inconsequential # warnings and errors into our build timelines that make it hard to track down @@ -168,12 +168,19 @@ jobs: # Official Build Linux Pool ${{ if and(or(in(parameters.osGroup, 'linux', 'freebsd', 'android', 'tizen'), eq(parameters.jobParameters.hostedOs, 'linux')), ne(variables['System.TeamProject'], 'public')) }}: name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals Build.Ubuntu.1804.Amd64 + demands: ImageOverride -equals 1es-ubuntu-2204 + os: linux - # OSX Build Pool (we don't have on-prem OSX BuildPool). - ${{ if in(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator') }}: + # OSX Public Build Pool (we don't have on-prem OSX BuildPool). + ${{ if and(in(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator'), eq(variables['System.TeamProject'], 'public')) }}: vmImage: 'macos-12' + # OSX Internal Pool + ${{ if and(in(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator'), ne(variables['System.TeamProject'], 'public')) }}: + name: "Azure Pipelines" + vmImage: 'macOS-12' + os: macOS + # Official Build Windows Pool ${{ if and(or(eq(parameters.osGroup, 'windows'), eq(parameters.jobParameters.hostedOs, 'windows')), ne(variables['System.TeamProject'], 'public')) }}: name: $(DncEngInternalBuildPool) diff --git a/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml b/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml index b6c57be0c7fbae..82d6346a60d7a0 100644 --- a/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml +++ b/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml @@ -11,6 +11,7 @@ parameters: liveLibrariesBuildConfig: '' strategy: '' pool: '' + templatePath: 'templates' # arcade-specific parameters condition: true @@ -28,6 +29,7 @@ parameters: jobs: - template: /eng/pipelines/common/templates/runtimes/xplat-job.yml parameters: + templatePath: ${{ parameters.templatePath }} buildConfig: ${{ parameters.buildConfig }} archType: ${{ parameters.archType }} osGroup: ${{ parameters.osGroup }} diff --git a/eng/pipelines/global-build.yml b/eng/pipelines/global-build.yml index 6f80e6ad104525..8b6291cd0db0bc 100644 --- a/eng/pipelines/global-build.yml +++ b/eng/pipelines/global-build.yml @@ -30,6 +30,7 @@ variables: extends: template: /eng/pipelines/common/templates/pipeline-with-resources.yml parameters: + isOfficialBuild: false stages: - stage: Build jobs: @@ -177,3 +178,97 @@ extends: timeoutInMinutes: 95 condition: eq(dependencies.evaluate_paths.outputs['SetPathVars_non_mono_and_wasm.containsChange'], true) + + # + # Build CoreCLR as a non-portable build + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: checked + runtimeFlavor: coreclr + platforms: + - tizen_armel + jobParameters: + testScope: innerloop + nameSuffix: CoreCLR_NonPortable + buildArgs: -s clr.native+clr.tools+clr.corelib+clr.nativecorelib+clr.aot+clr.packages -c $(_BuildConfig) /p:PortableBuild=false + timeoutInMinutes: 120 + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), + eq(variables['isRollingBuild'], true)) + + # + # Build CoreCLR with no R2R + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: checked + runtimeFlavor: coreclr + platforms: + - linux_x86 + jobParameters: + testScope: innerloop + nameSuffix: CoreCLR_NoR2R + buildArgs: -s clr.runtime+clr.jit+clr.iltools+clr.spmi+clr.corelib -c $(_BuildConfig) + timeoutInMinutes: 120 + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), + eq(variables['isRollingBuild'], true)) + + # + # Build CoreCLR release + # Always as they are needed by Installer and we always build and test the Installer. + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/coreclr/templates/build-job.yml + buildConfig: release + platforms: + - freebsd_x64 + jobParameters: + testGroup: innerloop + # Mono/runtimetests also need this, but skip for wasm + condition: + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_non_mono_and_wasm.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_mono_excluding_wasm.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true), + eq(variables['isRollingBuild'], true)) + + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/libraries/build-job.yml + buildConfig: ${{ variables.debugOnPrReleaseOnRolling }} + platforms: + - freebsd_x64 + jobParameters: + testScope: innerloop + condition: + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_mono_excluding_wasm.containsChange'], true), + eq(variables['isRollingBuild'], true)) + + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/installer/jobs/build-job.yml + buildConfig: Release + platforms: + - freebsd_x64 + jobParameters: + liveRuntimeBuildConfig: release + liveLibrariesBuildConfig: ${{ variables.debugOnPrReleaseOnRolling }} + runOnlyIfDependenciesSucceeded: true + condition: + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_non_mono_and_wasm.containsChange'], true), + eq(variables['isRollingBuild'], true)) diff --git a/eng/pipelines/mono/templates/generate-offsets.yml b/eng/pipelines/mono/templates/generate-offsets.yml index c68adfe67a9e6b..909ca9a99c54d4 100644 --- a/eng/pipelines/mono/templates/generate-offsets.yml +++ b/eng/pipelines/mono/templates/generate-offsets.yml @@ -9,11 +9,13 @@ parameters: pool: '' condition: true isOfficialBuild: false + templatePath: 'templates' ### Product build jobs: - template: xplat-pipeline-job.yml parameters: + templatePath: ${{ parameters.templatePath }} buildConfig: ${{ parameters.buildConfig }} osGroup: ${{ parameters.osGroup }} osSubGroup: ${{ parameters.osSubGroup }} @@ -76,17 +78,21 @@ jobs: contents: '**/offsets-*.h' targetFolder: '$(Build.SourcesDirectory)/artifacts/obj/mono/offsetfiles/' - - task: PublishPipelineArtifact@1 - displayName: Upload offset files - inputs: - targetPath: '$(Build.SourcesDirectory)/artifacts/obj/mono/offsetfiles' - artifactName: 'Mono_Offsets_$(osGroup)$(osSubGroup)' + - template: /eng/pipelines/common/templates/publish-pipeline-artifacts.yml + parameters: + displayName: Upload offset files + isOfficialBuild: ${{ parameters.isOfficialBuild }} + inputs: + targetPath: '$(Build.SourcesDirectory)/artifacts/obj/mono/offsetfiles' + artifactName: 'Mono_Offsets_$(osGroup)$(osSubGroup)' # Publish Logs - - task: PublishPipelineArtifact@1 - displayName: Publish Logs - inputs: - targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: 'BuildLogs_Attempt$(System.JobAttempt)_Mono_Offsets_$(osGroup)$(osSubGroup)' - continueOnError: true - condition: always() + - template: /eng/pipelines/common/templates/publish-pipeline-artifacts.yml + parameters: + displayName: Publish Logs + isOfficialBuild: ${{ parameters.isOfficialBuild }} + inputs: + targetPath: $(Build.SourcesDirectory)/artifacts/log + artifactName: 'BuildLogs_Attempt$(System.JobAttempt)_Mono_Offsets_$(osGroup)$(osSubGroup)' + continueOnError: true + condition: always() diff --git a/eng/pipelines/mono/templates/workloads-build.yml b/eng/pipelines/mono/templates/workloads-build.yml index 4a50ed665e24ee..a10bf343fa4f1f 100644 --- a/eng/pipelines/mono/templates/workloads-build.yml +++ b/eng/pipelines/mono/templates/workloads-build.yml @@ -12,11 +12,13 @@ parameters: runtimeVariant: '' testGroup: '' timeoutInMinutes: '' + templatePath: 'templates' variables: {} jobs: - template: xplat-pipeline-job.yml parameters: + templatePath: ${{ parameters.templatePath }} archType: ${{ parameters.archType }} buildConfig: ${{ parameters.buildConfig }} container: ${{ parameters.container }} @@ -92,13 +94,15 @@ jobs: name: workloads # Publish Logs - - task: PublishPipelineArtifact@1 - displayName: Publish Logs - inputs: - targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: 'WorkloadLogs_Attempt$(System.JobAttempt)' - continueOnError: true - condition: always() + - template: /eng/pipelines/common/templates/publish-pipeline-artifacts.yml + parameters: + displayName: Publish Logs + isOfficialBuild: ${{ parameters.isOfficialBuild }} + inputs: + targetPath: $(Build.SourcesDirectory)/artifacts/log + artifactName: 'WorkloadLogs_Attempt$(System.JobAttempt)' + continueOnError: true + condition: always() # Delete wixpdb files before they are uploaded to artifacts - task: DeleteFiles@1 diff --git a/eng/pipelines/mono/templates/xplat-pipeline-job.yml b/eng/pipelines/mono/templates/xplat-pipeline-job.yml index 1ca84d9caac1bb..67b43722e0c57d 100644 --- a/eng/pipelines/mono/templates/xplat-pipeline-job.yml +++ b/eng/pipelines/mono/templates/xplat-pipeline-job.yml @@ -12,6 +12,7 @@ parameters: pool: '' runtimeVariant: '' liveRuntimeBuildConfig: 'release' + templatePath: 'templates' # arcade-specific parameters condition: true @@ -28,6 +29,7 @@ parameters: jobs: - template: /eng/pipelines/common/templates/runtimes/xplat-job.yml parameters: + templatePath: ${{ parameters.templatePath }} buildConfig: ${{ parameters.buildConfig }} archType: ${{ parameters.archType }} osGroup: ${{ parameters.osGroup }} diff --git a/eng/pipelines/official/jobs/prepare-signed-artifacts.yml b/eng/pipelines/official/jobs/prepare-signed-artifacts.yml index 908f2b64c71c22..24fd2df48d74be 100644 --- a/eng/pipelines/official/jobs/prepare-signed-artifacts.yml +++ b/eng/pipelines/official/jobs/prepare-signed-artifacts.yml @@ -20,6 +20,14 @@ jobs: - name: SignType value: $[ coalesce(variables.OfficialSignType, 'real') ] + templateContext: + outputs: + - output: pipelineArtifact + displayName: 'Publish BuildLogs' + condition: succeededOrFailed() + targetPath: '$(Build.StagingDirectory)\BuildLogs' + artifactName: ${{ parameters.logArtifactName }} + steps: - checkout: self clean: true @@ -65,11 +73,4 @@ jobs: **/*.binlog TargetFolder: '$(Build.StagingDirectory)\BuildLogs' continueOnError: true - condition: succeededOrFailed() - - - task: PublishPipelineArtifact@1 - displayName: Publish BuildLogs - inputs: - targetPath: '$(Build.StagingDirectory)\BuildLogs' - artifactName: ${{ parameters.logArtifactName }} - condition: succeededOrFailed() + condition: succeededOrFailed() \ No newline at end of file diff --git a/eng/pipelines/official/stages/publish.yml b/eng/pipelines/official/stages/publish.yml index d23afa7003b25d..9553baae305f2f 100644 --- a/eng/pipelines/official/stages/publish.yml +++ b/eng/pipelines/official/stages/publish.yml @@ -7,7 +7,7 @@ stages: - stage: PrepareForPublish displayName: Prepare for Publish variables: - - template: /eng/common/templates/variables/pool-providers.yml + - template: /eng/common/templates-official/variables/pool-providers.yml jobs: # Prep artifacts: sign them and upload pipeline artifacts expected by stages-based publishing. - template: /eng/pipelines/official/jobs/prepare-signed-artifacts.yml @@ -15,7 +15,7 @@ stages: PublishRidAgnosticPackagesFromPlatform: ${{ parameters.PublishRidAgnosticPackagesFromPlatform }} # Publish to Build Asset Registry in order to generate the ReleaseConfigs artifact. - - template: /eng/common/templates/job/publish-build-assets.yml + - template: /eng/common/templates-official/job/publish-build-assets.yml parameters: publishUsingPipelines: true publishAssetsImmediately: true @@ -26,7 +26,7 @@ stages: symbolPublishingAdditionalParameters: '/p:PublishSpecialClrFiles=true' # Stages-based publishing entry point -- template: /eng/common/templates/post-build/post-build.yml +- template: /eng/common/templates-official/post-build/post-build.yml parameters: publishingInfraVersion: ${{ parameters.publishingInfraVersion }} validateDependsOn: diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index d84f414f4657ce..7cadf6a800f675 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -23,6 +23,8 @@ pr: none variables: - template: /eng/pipelines/common/variables.yml + parameters: + templatePath: 'templates-official' - template: /eng/pipelines/common/internal-variables.yml parameters: teamName: dotnet-core-acquisition @@ -33,6 +35,7 @@ variables: extends: template: /eng/pipelines/common/templates/pipeline-with-resources.yml parameters: + isOfficialBuild: true stages: - stage: Build jobs: @@ -41,19 +44,18 @@ extends: # Localization build # - - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/release/8.0') }}: - - template: /eng/common/templates/job/onelocbuild.yml - parameters: - MirrorRepo: runtime - MirrorBranch: release/8.0 - LclSource: lclFilesfromPackage - LclPackageId: 'LCL-JUNO-PROD-RUNTIME' + - template: /eng/common/templates-official/job/onelocbuild.yml + parameters: + MirrorRepo: runtime + MirrorBranch: main + LclSource: lclFilesfromPackage + LclPackageId: 'LCL-JUNO-PROD-RUNTIME' # # Source Index Build # - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}: - - template: /eng/common/templates/job/source-index-stage1.yml + - template: /eng/common/templates-official/job/source-index-stage1.yml parameters: sourceIndexBuildCommand: build.cmd -subset libs.sfx+libs.oob -binarylog -os linux -ci /p:SkipLibrariesNativeRuntimePackages=true @@ -70,6 +72,7 @@ extends: - windows_x64 - windows_arm64 jobParameters: + templatePath: 'templates-official' buildArgs: -s clr.runtime+clr.alljits+clr.nativeaotruntime -c $(_BuildConfig) /bl:$(Build.SourcesDirectory)/artifacts/logs/$(_BuildConfig)/CoreClrNativeBuild.binlog nameSuffix: CoreCLR isOfficialBuild: ${{ variables.isOfficialBuild }} @@ -105,6 +108,7 @@ extends: platforms: - windows_x86 jobParameters: + templatePath: 'templates-official' buildArgs: -s clr.runtime+clr.alljits -c $(_BuildConfig) /bl:$(Build.SourcesDirectory)/artifacts/logs/$(_BuildConfig)/CoreClrNativeBuild.binlog nameSuffix: CoreCLR isOfficialBuild: ${{ variables.isOfficialBuild }} @@ -138,6 +142,7 @@ extends: - osx_arm64 - osx_x64 jobParameters: + templatePath: 'templates-official' buildArgs: -s clr.runtime+clr.alljits+clr.nativeaotruntime+host.native -c $(_BuildConfig) /bl:$(Build.SourcesDirectory)/artifacts/logs/$(_BuildConfig)/CoreClrNativeBuild.binlog nameSuffix: CoreCLR isOfficialBuild: ${{ variables.isOfficialBuild }} @@ -197,6 +202,7 @@ extends: - linux_musl_arm - linux_musl_arm64 jobParameters: + templatePath: 'templates-official' buildArgs: -s clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.aot+clr.packages+libs+host+packs -c $(_BuildConfig) nameSuffix: CoreCLR isOfficialBuild: ${{ variables.isOfficialBuild }} @@ -209,12 +215,12 @@ extends: SourceFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(_BuildConfig) Contents: libcoreclr.so TargetFolder: $(Build.SourcesDirectory)/artifacts/CoreCLRCrossDacArtifacts/$(osGroup)$(osSubgroup).$(archType).$(_BuildConfig)/$(crossDacHostArch) - - task: PublishBuildArtifacts@1 + - task: 1ES.PublishBuildArtifacts@1 displayName: Publish runtime for CrossDac inputs: - pathToPublish: $(Build.SourcesDirectory)/artifacts/CoreCLRCrossDacArtifacts + PathtoPublish: $(Build.SourcesDirectory)/artifacts/CoreCLRCrossDacArtifacts PublishLocation: Container - artifactName: CoreCLRCrossDacArtifacts + ArtifactName: CoreCLRCrossDacArtifacts # Create RPMs and DEBs - template: /eng/pipelines/installer/jobs/steps/build-linux-package.yml parameters: @@ -250,6 +256,7 @@ extends: platforms: - windows_x64 jobParameters: + templatePath: 'templates-official' buildArgs: -s crossdacpack -c $(_BuildConfig) /p:CrossDacArtifactsDir=$(crossDacArtifactsPath) nameSuffix: CrossDac isOfficialBuild: ${{ variables.isOfficialBuild }} @@ -320,6 +327,7 @@ extends: - linux_bionic_arm64 - linux_bionic_x64 jobParameters: + templatePath: 'templates-official' buildArgs: -s clr.nativeaotlibs+clr.nativeaotruntime+libs+packs -c $(_BuildConfig) /p:BuildNativeAOTRuntimePack=true /p:SkipLibrariesNativeRuntimePackages=true nameSuffix: NativeAOT isOfficialBuild: ${{ variables.isOfficialBuild }} @@ -363,6 +371,7 @@ extends: - windows_x86 # - windows_arm64 jobParameters: + templatePath: 'templates-official' buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:BuildMonoAOTCrossCompiler=false nameSuffix: Mono isOfficialBuild: ${{ variables.isOfficialBuild }} @@ -380,6 +389,7 @@ extends: - browser_wasm - wasi_wasm jobParameters: + templatePath: 'templates-official' buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS) nameSuffix: Mono isOfficialBuild: ${{ variables.isOfficialBuild }} @@ -396,6 +406,7 @@ extends: platforms: - browser_wasm jobParameters: + templatePath: 'templates-official' buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:MonoWasmBuildVariant=multithread /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS) nameSuffix: Mono_multithread isOfficialBuild: ${{ variables.isOfficialBuild }} @@ -418,6 +429,7 @@ extends: - ios_arm64 - maccatalyst_x64 jobParameters: + templatePath: 'templates-official' isOfficialBuild: ${{ variables.isOfficialBuild }} # @@ -434,6 +446,7 @@ extends: - linux_arm64 - linux_musl_arm64 jobParameters: + templatePath: 'templates-official' buildArgs: -s mono+packs -c $(_BuildConfig) /p:MonoCrossAOTTargetOS=android+browser /p:SkipMonoCrossJitConfigure=true /p:BuildMonoAOTCrossCompilerOnly=true nameSuffix: CrossAOT_Mono @@ -458,6 +471,7 @@ extends: platforms: - windows_x64 jobParameters: + templatePath: 'templates-official' buildArgs: -s mono+packs -c $(_BuildConfig) /p:MonoCrossAOTTargetOS=android+browser /p:SkipMonoCrossJitConfigure=true /p:BuildMonoAOTCrossCompilerOnly=true nameSuffix: CrossAOT_Mono @@ -483,6 +497,7 @@ extends: - osx_x64 - osx_arm64 jobParameters: + templatePath: 'templates-official' buildArgs: -s mono+packs -c $(_BuildConfig) /p:MonoCrossAOTTargetOS=android+browser+tvos+ios+maccatalyst /p:SkipMonoCrossJitConfigure=true /p:BuildMonoAOTCrossCompilerOnly=true nameSuffix: CrossAOT_Mono @@ -526,6 +541,7 @@ extends: buildConfig: release runtimeFlavor: mono jobParameters: + templatePath: 'templates-official' buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:MonoEnableLLVM=true /p:MonoBundleLLVMOptimizer=false nameSuffix: Mono_LLVMJIT @@ -540,6 +556,7 @@ extends: buildConfig: release runtimeFlavor: mono jobParameters: + templatePath: 'templates-official' buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true nameSuffix: Mono_LLVMAOT @@ -560,6 +577,7 @@ extends: platforms: - windows_x64 jobParameters: + templatePath: 'templates-official' buildArgs: -s tools+libs -allConfigurations -c $(_BuildConfig) /p:TestAssemblies=false /p:TestPackages=true nameSuffix: Libraries_AllConfigurations isOfficialBuild: ${{ variables.isOfficialBuild }} @@ -579,7 +597,9 @@ extends: platforms: - SourceBuild_linux_x64 jobParameters: + templatePath: 'templates-official' nameSuffix: PortableSourceBuild + isOfficialBuild: ${{ variables.isOfficialBuild }} postBuildSteps: - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml parameters: @@ -601,7 +621,8 @@ extends: - windows_arm64 - linux_arm64 jobParameters: - buildArgs: -s clr.native+clr.corelib+clr.tools+clr.nativecorelib+libs+host+packs -c $(_BuildConfig) -pgoinstrument + templatePath: 'templates-official' + buildArgs: -s clr.native+clr.corelib+clr.tools+clr.nativecorelib+libs+host+packs -c $(_BuildConfig) -pgoinstrument /p:SkipLibrariesNativeRuntimePackages=true isOfficialBuild: ${{ variables.isOfficialBuild }} nameSuffix: PGO postBuildSteps: @@ -620,6 +641,7 @@ extends: platforms: - windows_x64 jobParameters: + templatePath: 'templates-official' isOfficialBuild: ${{ variables.isOfficialBuild }} timeoutInMinutes: 120 dependsOn: diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 767b3dc9ba424b..8f001c4903003e 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -52,6 +52,7 @@ variables: extends: template: /eng/pipelines/common/templates/pipeline-with-resources.yml parameters: + isOfficialBuild: false stages: - stage: Build jobs: @@ -155,7 +156,6 @@ extends: - windows_x64 - windows_x86 - windows_arm64 - - freebsd_x64 jobParameters: testGroup: innerloop # Mono/runtimetests also need this, but skip for wasm @@ -187,48 +187,6 @@ extends: eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr_jit.containsChange'], true), eq(variables['isRollingBuild'], true))) - # - # Build CoreCLR with no R2R - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml - buildConfig: checked - runtimeFlavor: coreclr - platforms: - - linux_x86 - jobParameters: - testScope: innerloop - nameSuffix: CoreCLR_NoR2R - buildArgs: -s clr.runtime+clr.jit+clr.iltools+clr.spmi+clr.corelib -c $(_BuildConfig) - timeoutInMinutes: 120 - condition: >- - or( - eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), - eq(variables['isRollingBuild'], true)) - - # - # Build CoreCLR as a non-portable build - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml - buildConfig: checked - runtimeFlavor: coreclr - platforms: - - tizen_armel - jobParameters: - testScope: innerloop - nameSuffix: CoreCLR_NonPortable - buildArgs: -s clr.native+clr.tools+clr.corelib+clr.nativecorelib+clr.aot+clr.packages -c $(_BuildConfig) /p:PortableBuild=false - timeoutInMinutes: 120 - condition: >- - or( - eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), - eq(variables['isRollingBuild'], true)) - # # CoreCLR NativeAOT debug build and smoke tests # Only when CoreCLR is changed @@ -428,6 +386,7 @@ extends: - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/mono/templates/generate-offsets.yml + templatePath: 'templates' buildConfig: release platforms: - android_x64 @@ -1059,7 +1018,6 @@ extends: - osx_arm64 - osx_x64 - windows_x64 - - freebsd_x64 jobParameters: testScope: innerloop condition: @@ -1183,7 +1141,6 @@ extends: - linux_arm64 - linux_musl_x64 - windows_x64 - - freebsd_x64 jobParameters: liveRuntimeBuildConfig: release liveLibrariesBuildConfig: ${{ variables.debugOnPrReleaseOnRolling }} diff --git a/src/coreclr/debug/daccess/CMakeLists.txt b/src/coreclr/debug/daccess/CMakeLists.txt index 9a867c078019dd..5332e957c9eca1 100644 --- a/src/coreclr/debug/daccess/CMakeLists.txt +++ b/src/coreclr/debug/daccess/CMakeLists.txt @@ -53,7 +53,7 @@ if(CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD OR CLR_CMAKE_HOST_SUNOS) DEPENDS coreclr VERBATIM COMMAND_EXPAND_LISTS - COMMAND ${CLR_DIR}/pal/tools/gen-dactable-rva.sh ${args} + COMMAND ${CMAKE_COMMAND} -E env NM=${CMAKE_NM} ${CLR_DIR}/pal/tools/gen-dactable-rva.sh ${args} COMMENT Generating ${GENERATED_INCLUDE_DIR}/dactablerva.h ) diff --git a/src/coreclr/vm/arm/thunktemplates.S b/src/coreclr/vm/arm/thunktemplates.S index 0686bb2ed4b735..8744c8ebb63264 100644 --- a/src/coreclr/vm/arm/thunktemplates.S +++ b/src/coreclr/vm/arm/thunktemplates.S @@ -11,7 +11,7 @@ PAGE_SIZE = 4096 -#define DATA_SLOT(stub, field) stub##Code + PAGE_SIZE + stub##Data__##field +#define DATA_SLOT(stub, field) . - (. - stub##Code) + PAGE_SIZE + stub##Data__##field LEAF_ENTRY StubPrecodeCode ldr r12, DATA_SLOT(StubPrecode, MethodDesc) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 3122cdf153cd17..a643e5a049e79c 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -810,6 +810,16 @@ + + + $(ROOTFS_HOST_DIR) + + @@ -859,7 +869,7 @@ <_MonoSkipInitCompiler Condition="'$(CrossBuild)' == 'true'">false <_MonoAotCrossOffsetsCommand Condition="'$(MonoUseCrossTool)' == 'true'">$(PythonCmd) $(MonoProjectRoot)mono/tools/offsets-tool/offsets-tool.py @(MonoAotCrossOffsetsToolParams, ' ') <_MonoAotCMakeConfigureCommand>cmake @(MonoAOTCMakeArgs, ' ') $(MonoCMakeExtraArgs) "$(MonoProjectRoot.TrimEnd('\/'))" - <_MonoAotCMakeConfigureCommand Condition="'$(_MonoSkipInitCompiler)' != 'true' and '$(HostOS)' != 'windows'">sh -c 'build_arch="$(_CompilerTargetArch)" compiler="$(MonoCCompiler)" . "$(RepositoryEngineeringCommonDir)native/init-compiler.sh" && @(_MonoAotBuildEnv, ' ') $(_MonoAotCMakeConfigureCommand)' + <_MonoAotCMakeConfigureCommand Condition="'$(_MonoSkipInitCompiler)' != 'true' and '$(HostOS)' != 'windows'">sh -c 'build_arch="$(_CompilerTargetArch)" ROOTFS_DIR="$(MonoCrossDir)" compiler="$(MonoCCompiler)" . "$(RepositoryEngineeringCommonDir)native/init-compiler.sh" && @(_MonoAotBuildEnv, ' ') $(_MonoAotCMakeConfigureCommand)' <_MonoAotCMakeConfigureCommand Condition="'$(_MonoSkipInitCompiler)' == 'true' and '$(HostOS)' != 'windows'">$(_MonoAOTCCOption) $(_MonoAOTCXXOption) @(_MonoAotBuildEnv, ' ') $(_MonoAotCMakeConfigureCommand) <_MonoAotCMakeConfigureCommand Condition="'$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" $(_CompilerTargetArch) && cd /D "$(MonoObjCrossDir)" && @(_MonoAotBuildEnv, ' ') $(_MonoAotCMakeConfigureCommand) <_MonoAotCMakeBuildCommand>cmake --build . --target install --config $(Configuration) From 3516014c9efde23f26cc898687c578290e595211 Mon Sep 17 00:00:00 2001 From: Alexey Zakharov Date: Fri, 31 May 2024 01:31:46 +0200 Subject: [PATCH 755/783] Ensure LoaderAllocator can't be collected while we clean handles on collectible LoaderAllocators (#102872) (cherry picked from commit eb84218fd176b5eaef40cf999cc63b6862f36251) --- src/coreclr/vm/threadstatics.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/coreclr/vm/threadstatics.cpp b/src/coreclr/vm/threadstatics.cpp index e3430acf8e4ff2..0216ae054a181a 100644 --- a/src/coreclr/vm/threadstatics.cpp +++ b/src/coreclr/vm/threadstatics.cpp @@ -52,13 +52,22 @@ void ThreadLocalBlock::FreeTLM(SIZE_T i, BOOL isThreadShuttingdown) ThreadLocalModule::CollectibleDynamicEntry *entry = (ThreadLocalModule::CollectibleDynamicEntry*)pThreadLocalModule->m_pDynamicClassTable[k].m_pDynamicEntry; PTR_LoaderAllocator pLoaderAllocator = entry->m_pLoaderAllocator; - if (entry->m_hGCStatics != NULL) - { - pLoaderAllocator->FreeHandle(entry->m_hGCStatics); - } - if (entry->m_hNonGCStatics != NULL) + // LoaderAllocator may be collected when the thread is shutting down. + // We enter coop mode to ensure that we get a valid value of the exposed object and + // can safely clean up handles if it is not yet collected. + GCX_COOP(); + + LOADERALLOCATORREF loaderAllocator = pLoaderAllocator->GetExposedObject(); + if (loaderAllocator != NULL) { - pLoaderAllocator->FreeHandle(entry->m_hNonGCStatics); + if (entry->m_hGCStatics != NULL) + { + pLoaderAllocator->FreeHandle(entry->m_hGCStatics); + } + if (entry->m_hNonGCStatics != NULL) + { + pLoaderAllocator->FreeHandle(entry->m_hNonGCStatics); + } } } delete pThreadLocalModule->m_pDynamicClassTable[k].m_pDynamicEntry; From 67133a6768e4750dee143d9eb89fb3baf3e23280 Mon Sep 17 00:00:00 2001 From: Juan Hoyos <19413848+hoyosjs@users.noreply.github.com> Date: Fri, 31 May 2024 11:02:02 -0700 Subject: [PATCH 756/783] Update DIA to 17.10.0-beta1.24272.1 (#102641) --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 26f979c5617d2f..ad4ed3a86fa76a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -165,7 +165,7 @@ 1.0.0-prerelease.23566.3 1.0.0-prerelease.23566.3 - 17.8.7-beta1.24113.1 + 17.10.0-beta1.24272.1 2.0.0-beta4.23307.1 3.0.3 2.1.0 From cff625b40a8877beeef603fbded73e91560dc31e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:53:07 -0700 Subject: [PATCH 757/783] Fix a bug in PAL version of _vsnprint_f (#103003) When the formatted string cannot fully fit in the buffer (including its null terminator) `_vsnprint_f` should return -1. However, in the case where the number of chars was the same as the buffer size it was returning the buffer size. Co-authored-by: Jakob Botsch Nielsen --- src/coreclr/pal/src/safecrt/vsprintf.cpp | 2 +- .../palsuite/c_runtime/_vsnprintf_s/test1/test1.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/coreclr/pal/src/safecrt/vsprintf.cpp b/src/coreclr/pal/src/safecrt/vsprintf.cpp index b8ff745f563ceb..360222d5dc6798 100644 --- a/src/coreclr/pal/src/safecrt/vsprintf.cpp +++ b/src/coreclr/pal/src/safecrt/vsprintf.cpp @@ -95,7 +95,7 @@ DLLEXPORT int __cdecl _vsnprintf_s ( retvalue = vsnprintf(string, sizeInBytes, format, ap); string[sizeInBytes - 1] = '\0'; /* we allow truncation if count == _TRUNCATE */ - if (retvalue > (int)sizeInBytes && count == _TRUNCATE) + if (retvalue >= (int)sizeInBytes && count == _TRUNCATE) { if (errno == ERANGE) { diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/_vsnprintf_s/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/_vsnprintf_s/test1/test1.cpp index fb5ab3a2d7af41..62b725208769c2 100644 --- a/src/coreclr/pal/tests/palsuite/c_runtime/_vsnprintf_s/test1/test1.cpp +++ b/src/coreclr/pal/tests/palsuite/c_runtime/_vsnprintf_s/test1/test1.cpp @@ -49,6 +49,18 @@ PALTEST(c_runtime__vsnprintf_s_test1_paltest_vsnprintf_test1, "c_runtime/_vsnpri Fail("ERROR: expected %s (up to %d chars), got %s\n", checkstr, 8, buf); } + char buf8[8] = {0}; + + ret = Testvsnprintf(buf8, 8, "abcdefgh"); + if (ret >= 0) + { + Fail("ERROR: expected negative return value, got %d", ret); + } + if (memcmp(buf8, "abcdefg\0", 8) != 0) + { + Fail("ERROR: Expected 7 chars + null terminator"); + } + PAL_Terminate(); return PASS; } From ca2841138e665611e4ebf4e7e350b673b8268b3b Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Tue, 4 Jun 2024 09:37:51 +0200 Subject: [PATCH 758/783] Fix calculation of channel bindings hash in managed NTLM implementation (#102565) --- .../NegotiateAuthenticationPal.ManagedNtlm.cs | 21 +++++++++++++++---- .../Net/NegotiateAuthenticationPal.Unix.cs | 4 ++-- .../Pal.Managed/SafeChannelBindingHandle.cs | 10 ++++----- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.ManagedNtlm.cs b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.ManagedNtlm.cs index 866a754af72922..794e2ac5790e2f 100644 --- a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.ManagedNtlm.cs +++ b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.ManagedNtlm.cs @@ -416,10 +416,23 @@ private unsafe void WriteChannelBindingHash(Span hashBuffer) { if (_channelBinding != null) { - IntPtr cbtData = _channelBinding.DangerousGetHandle(); - int cbtDataSize = _channelBinding.Size; - int written = MD5.HashData(new Span((void*)cbtData, cbtDataSize), hashBuffer); - Debug.Assert(written == MD5.HashSizeInBytes); + int appDataOffset = sizeof(SecChannelBindings); + IntPtr cbtData = (nint)_channelBinding.DangerousGetHandle() + appDataOffset; + int cbtDataSize = _channelBinding.Size - appDataOffset; + + // Channel bindings are calculated according to RFC 4121, section 4.1.1.2, + // so we need to include zeroed initiator fields and length prefix for the + // application data. + Span prefix = stackalloc byte[sizeof(uint) * 5]; + prefix.Clear(); + BinaryPrimitives.WriteInt32LittleEndian(prefix.Slice(sizeof(uint) * 4), cbtDataSize); + using (var md5 = IncrementalHash.CreateHash(HashAlgorithmName.MD5)) + { + md5.AppendData(prefix); + md5.AppendData(new Span((void*)cbtData, cbtDataSize)); + int written = md5.GetHashAndReset(hashBuffer); + Debug.Assert(written == MD5.HashSizeInBytes); + } } else { diff --git a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Unix.cs b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Unix.cs index ed1fe4e2e91937..4dba6bcfbd86af 100644 --- a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Unix.cs +++ b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Unix.cs @@ -551,7 +551,7 @@ Interop.NetSecurityNative.Status status } } - private NegotiateAuthenticationStatusCode InitializeSecurityContext( + private unsafe NegotiateAuthenticationStatusCode InitializeSecurityContext( ref SafeGssCredHandle credentialsHandle, ref SafeGssContextHandle? contextHandle, ref SafeGssNameHandle? targetNameHandle, @@ -594,7 +594,7 @@ private NegotiateAuthenticationStatusCode InitializeSecurityContext( { // If a TLS channel binding token (cbt) is available then get the pointer // to the application specific data. - int appDataOffset = Marshal.SizeOf(); + int appDataOffset = sizeof(SecChannelBindings); Debug.Assert(appDataOffset < channelBinding.Size); IntPtr cbtAppData = channelBinding.DangerousGetHandle() + appDataOffset; int cbtAppDataSize = channelBinding.Size - appDataOffset; diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Managed/SafeChannelBindingHandle.cs b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Managed/SafeChannelBindingHandle.cs index 35daf739b88af8..0b8699fd0eaa04 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Managed/SafeChannelBindingHandle.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Managed/SafeChannelBindingHandle.cs @@ -11,7 +11,7 @@ namespace System.Net.Security internal sealed class SafeChannelBindingHandle : ChannelBinding { private const int CertHashMaxSize = 128; - private static readonly int s_secChannelBindingSize = Marshal.SizeOf(); + private static unsafe int SecChannelBindingSize => sizeof(SecChannelBindings); private readonly int _cbtPrefixByteArraySize; internal int Length { get; private set; } @@ -36,8 +36,8 @@ internal unsafe SafeChannelBindingHandle(ChannelBindingKind kind) "tls-unique:"u8; _cbtPrefixByteArraySize = cbtPrefix.Length; - handle = Marshal.AllocHGlobal(s_secChannelBindingSize + _cbtPrefixByteArraySize + CertHashMaxSize); - IntPtr cbtPrefixPtr = handle + s_secChannelBindingSize; + handle = Marshal.AllocHGlobal(SecChannelBindingSize + _cbtPrefixByteArraySize + CertHashMaxSize); + IntPtr cbtPrefixPtr = handle + SecChannelBindingSize; cbtPrefix.CopyTo(new Span((byte*)cbtPrefixPtr, cbtPrefix.Length)); CertHashPtr = cbtPrefixPtr + _cbtPrefixByteArraySize; Length = CertHashMaxSize; @@ -46,12 +46,12 @@ internal unsafe SafeChannelBindingHandle(ChannelBindingKind kind) internal void SetCertHashLength(int certHashLength) { int cbtLength = _cbtPrefixByteArraySize + certHashLength; - Length = s_secChannelBindingSize + cbtLength; + Length = SecChannelBindingSize + cbtLength; SecChannelBindings channelBindings = new SecChannelBindings() { ApplicationDataLength = cbtLength, - ApplicationDataOffset = s_secChannelBindingSize + ApplicationDataOffset = SecChannelBindingSize }; Marshal.StructureToPtr(channelBindings, handle, true); } From bfaf24e2fef15d89408853fbfb92f4bf4a6b6ab8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 09:38:50 +0200 Subject: [PATCH 759/783] [release/8.0] Removed unused sessions from SSL_CTX internal cache (#102095) * Disable OpenSSL internal SSL_SESSION cache for clients * Attempt no. 2 * Revert "Disable OpenSSL internal SSL_SESSION cache for clients" This reverts commit 56a308e88171bb797d13d50953b83262cd8289cd. --------- Co-authored-by: Radek Zikmund --- .../Interop.OpenSsl.cs | 2 +- .../Interop.SslCtx.cs | 36 +++++++++++++------ .../entrypoints.c | 1 + .../opensslshim.h | 2 ++ .../pal_ssl.c | 5 +++ .../pal_ssl.h | 5 +++ 6 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index c526f37b0b9fbf..110d4714ba5d12 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -787,7 +787,7 @@ private static unsafe void RemoveSessionCallback(IntPtr ctx, IntPtr session) IntPtr name = Ssl.SessionGetHostname(session); Debug.Assert(name != IntPtr.Zero); - ctxHandle.RemoveSession(name); + ctxHandle.RemoveSession(name, session); } #if DEBUG diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs index 5baa776d9d5a8a..d92e15e940e65e 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs @@ -39,6 +39,9 @@ internal static partial class Ssl [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetCaching")] internal static unsafe partial int SslCtxSetCaching(SafeSslContextHandle ctx, int mode, int cacheSize, int contextIdLength, Span contextId, delegate* unmanaged neewSessionCallback, delegate* unmanaged removeSessionCallback); + [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxRemoveSession")] + internal static unsafe partial void SslCtxRemoveSession(SafeSslContextHandle ctx, IntPtr session); + internal static bool AddExtraChainCertificates(SafeSslContextHandle ctx, ReadOnlyCollection chain) { // send pre-computed list of intermediates. @@ -142,27 +145,38 @@ internal bool TryAddSession(IntPtr namePtr, IntPtr session) // This will use strdup() so it is safe to pass in raw pointer. Interop.Ssl.SessionSetHostname(session, namePtr); + IntPtr oldSession = IntPtr.Zero; + lock (_sslSessions) { if (!_sslSessions.TryAdd(targetName, session)) { - if (_sslSessions.Remove(targetName, out IntPtr oldSession)) - { - Interop.Ssl.SessionFree(oldSession); - } - + // session to this target host exists, replace it + _sslSessions.Remove(targetName, out oldSession); bool added = _sslSessions.TryAdd(targetName, session); Debug.Assert(added); } } + if (oldSession != IntPtr.Zero) + { + // remove old session also from the internal OpenSSL cache + // and drop reference count. Since SSL_CTX_remove_session + // will call session_remove_cb, we need to do this outside + // of _sslSessions lock to avoid deadlock with another thread + // which could be holding SSL_CTX lock and trying to acquire + // _sslSessions lock. + Interop.Ssl.SslCtxRemoveSession(this, oldSession); + Interop.Ssl.SessionFree(oldSession); + } + return true; } return false; } - internal void RemoveSession(IntPtr namePtr) + internal void RemoveSession(IntPtr namePtr, IntPtr session) { Debug.Assert(_sslSessions != null); @@ -171,11 +185,14 @@ internal void RemoveSession(IntPtr namePtr) if (_sslSessions != null && targetName != null) { - IntPtr oldSession; - bool removed; + IntPtr oldSession = IntPtr.Zero; + bool removed = false; lock (_sslSessions) { - removed = _sslSessions.Remove(targetName, out oldSession); + if (_sslSessions.TryGetValue(targetName, out IntPtr existingSession) && existingSession == session) + { + removed = _sslSessions.Remove(targetName, out oldSession); + } } if (removed) @@ -209,7 +226,6 @@ internal bool TrySetSession(SafeSslHandle sslHandle, string name) // This will increase reference count on the session as needed. // We need to hold lock here to prevent session being deleted before the call is done. Interop.Ssl.SslSetSession(sslHandle, session); - return true; } } diff --git a/src/native/libs/System.Security.Cryptography.Native/entrypoints.c b/src/native/libs/System.Security.Cryptography.Native/entrypoints.c index f69959f36a4b51..1045645f1713af 100644 --- a/src/native/libs/System.Security.Cryptography.Native/entrypoints.c +++ b/src/native/libs/System.Security.Cryptography.Native/entrypoints.c @@ -299,6 +299,7 @@ static const Entry s_cryptoNative[] = DllImportEntry(CryptoNative_IsSslStateOK) DllImportEntry(CryptoNative_SslCtxAddExtraChainCert) DllImportEntry(CryptoNative_SslCtxSetCaching) + DllImportEntry(CryptoNative_SslCtxRemoveSession) DllImportEntry(CryptoNative_SslCtxSetCiphers) DllImportEntry(CryptoNative_SslCtxSetDefaultOcspCallback) DllImportEntry(CryptoNative_SslCtxSetEncryptionPolicy) diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index 1f1b1851f098aa..f94ddc01274c44 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -525,6 +525,7 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len); REQUIRED_FUNCTION(SSL_CTX_new) \ REQUIRED_FUNCTION(SSL_CTX_sess_set_new_cb) \ REQUIRED_FUNCTION(SSL_CTX_sess_set_remove_cb) \ + REQUIRED_FUNCTION(SSL_CTX_remove_session) \ LIGHTUP_FUNCTION(SSL_CTX_set_alpn_protos) \ LIGHTUP_FUNCTION(SSL_CTX_set_alpn_select_cb) \ REQUIRED_FUNCTION(SSL_CTX_set_cipher_list) \ @@ -1040,6 +1041,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #define SSL_CTX_new SSL_CTX_new_ptr #define SSL_CTX_sess_set_new_cb SSL_CTX_sess_set_new_cb_ptr #define SSL_CTX_sess_set_remove_cb SSL_CTX_sess_set_remove_cb_ptr +#define SSL_CTX_remove_session SSL_CTX_remove_session_ptr #define SSL_CTX_set_alpn_protos SSL_CTX_set_alpn_protos_ptr #define SSL_CTX_set_alpn_select_cb SSL_CTX_set_alpn_select_cb_ptr #define SSL_CTX_set_cipher_list SSL_CTX_set_cipher_list_ptr diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c index e6bd41143c1655..e320d1c73d776b 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c @@ -701,6 +701,11 @@ int CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode, int cacheSize, int con return retValue; } +int CryptoNative_SslCtxRemoveSession(SSL_CTX* ctx, SSL_SESSION* session) +{ + return SSL_CTX_remove_session(ctx, session); +} + const char* CryptoNative_SslGetServerName(SSL* ssl) { return SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h index 3c63564cc4e59f..9c9d7026119c5c 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h @@ -167,6 +167,11 @@ Sets session caching. 0 is disabled. */ PALEXPORT int CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode, int cacheSize, int contextIdLength, uint8_t* contextId, SslCtxNewSessionCallback newSessionCb, SslCtxRemoveSessionCallback removeSessionCb); +/* +Removes a session from internal cache. +*/ +PALEXPORT int CryptoNative_SslCtxRemoveSession(SSL_CTX* ctx, SSL_SESSION* session); + /* Sets callback to log TLS session keys */ From 5e7120c954c3a0d27ee5ee7658ae5a8898a5ebc4 Mon Sep 17 00:00:00 2001 From: David Mason Date: Tue, 4 Jun 2024 07:28:29 -0700 Subject: [PATCH 760/783] [Release/8.0-staging] Fix issue where the IPC server can fully consume a CPU core and prevent incoming connections (#102530) * 8 fix for ipc * Update ds-ipc-pal-namedpipe.c --- src/native/eventpipe/ds-ipc-pal-namedpipe.c | 25 +++++++++++++++++++++ src/native/eventpipe/ds-ipc-pal-socket.c | 5 +++++ src/native/eventpipe/ds-ipc-pal.h | 3 +++ src/native/eventpipe/ds-ipc.c | 6 ++++- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/native/eventpipe/ds-ipc-pal-namedpipe.c b/src/native/eventpipe/ds-ipc-pal-namedpipe.c index 01a12275a421b1..151b3d95cc4610 100644 --- a/src/native/eventpipe/ds-ipc-pal-namedpipe.c +++ b/src/native/eventpipe/ds-ipc-pal-namedpipe.c @@ -173,6 +173,27 @@ ds_ipc_free (DiagnosticsIpc *ipc) ep_rt_object_free (ipc); } +void +ds_ipc_reset (DiagnosticsIpc *ipc) +{ + if (!ipc) + return; + + if (ipc->pipe != INVALID_HANDLE_VALUE) { + DisconnectNamedPipe (ipc->pipe); + CloseHandle (ipc->pipe); + ipc->pipe = INVALID_HANDLE_VALUE; + } + + if (ipc->overlap.hEvent != INVALID_HANDLE_VALUE) { + CloseHandle (ipc->overlap.hEvent); + } + + memset(&ipc->overlap, 0, sizeof(OVERLAPPED)); // clear the overlapped objects state + ipc->overlap.hEvent = INVALID_HANDLE_VALUE; + ipc->is_listening = false; +} + int32_t ds_ipc_poll ( DiagnosticsIpcPollHandle *poll_handles_data, @@ -192,6 +213,10 @@ ds_ipc_poll ( // SERVER EP_ASSERT (poll_handles_data [i].ipc->mode == DS_IPC_CONNECTION_MODE_LISTEN); handles [i] = poll_handles_data [i].ipc->overlap.hEvent; + if (handles [i] == INVALID_HANDLE_VALUE) { + // Invalid handle, wait will fail. Signal error + poll_handles_data [i].events = DS_IPC_POLL_EVENTS_ERR; + } } else { // CLIENT bool success = true; diff --git a/src/native/eventpipe/ds-ipc-pal-socket.c b/src/native/eventpipe/ds-ipc-pal-socket.c index d93233c506b787..7ad0b0f5d4859c 100644 --- a/src/native/eventpipe/ds-ipc-pal-socket.c +++ b/src/native/eventpipe/ds-ipc-pal-socket.c @@ -1064,6 +1064,11 @@ ds_ipc_free (DiagnosticsIpc *ipc) ep_rt_object_free (ipc); } +void +ds_ipc_reset (DiagnosticsIpc *ipc) +{ +} + int32_t ds_ipc_poll ( DiagnosticsIpcPollHandle *poll_handles_data, diff --git a/src/native/eventpipe/ds-ipc-pal.h b/src/native/eventpipe/ds-ipc-pal.h index 98e0fba180e69b..8e246ed671955c 100644 --- a/src/native/eventpipe/ds-ipc-pal.h +++ b/src/native/eventpipe/ds-ipc-pal.h @@ -35,6 +35,9 @@ ds_ipc_alloc ( void ds_ipc_free (DiagnosticsIpc *ipc); +void +ds_ipc_reset (DiagnosticsIpc *ipc); + // Poll // Parameters: // - IpcPollHandle * poll_handles_data: Array of IpcPollHandles to poll diff --git a/src/native/eventpipe/ds-ipc.c b/src/native/eventpipe/ds-ipc.c index 1256e3b00333cb..d3b7292514dd07 100644 --- a/src/native/eventpipe/ds-ipc.c +++ b/src/native/eventpipe/ds-ipc.c @@ -839,7 +839,11 @@ listen_port_reset ( ds_ipc_error_callback_func callback) { EP_ASSERT (object != NULL); - return; +#ifdef _WIN32 + DiagnosticsListenPort *listen_port = (DiagnosticsListenPort *)object; + ds_ipc_reset (listen_port->port.ipc); + ds_ipc_listen (listen_port->port.ipc, callback); +#endif // _WIN32 } static DiagnosticsPortVtable listen_port_vtable = { From d2f465abe2678c517e64201fa561b8a26c694cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20P=C3=ADchov=C3=A1?= <11718369+ManickaP@users.noreply.github.com> Date: Wed, 5 Jun 2024 08:53:06 +0200 Subject: [PATCH 761/783] [release/8.0-staging] Remove noisy test (#102610) Backport of #100640 to release/8.0-staging /cc @carlossanlop @liveans ## Customer Impact Noisy test, impacts us. ## Regression No ## Testing ## Risk LOW, only test code change --- .../tests/FunctionalTests/MsQuicTests.cs | 54 ------------------- 1 file changed, 54 deletions(-) diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 51c4279308e56a..5627009287a209 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -1055,60 +1055,6 @@ public BufferSegment Append(ReadOnlyMemory memory) } } - [Fact] - [OuterLoop("May take several seconds")] - public async Task ByteMixingOrNativeAVE_MinimalFailingTest() - { - const int writeSize = 64 * 1024; - const int NumberOfWrites = 512; - byte[] data1 = new byte[writeSize * NumberOfWrites]; - byte[] data2 = new byte[writeSize * NumberOfWrites]; - Array.Fill(data1, (byte)1); - Array.Fill(data2, (byte)2); - - Task t1 = RunTest(data1); - Task t2 = RunTest(data2); - - async Task RunTest(byte[] data) - { - await RunClientServer( - iterations: 20, - serverFunction: async connection => - { - await using QuicStream stream = await connection.AcceptInboundStreamAsync(); - - byte[] buffer = new byte[data.Length]; - int bytesRead = await ReadAll(stream, buffer); - Assert.Equal(data.Length, bytesRead); - AssertExtensions.SequenceEqual(data, buffer); - - for (int pos = 0; pos < data.Length; pos += writeSize) - { - await stream.WriteAsync(data[pos..(pos + writeSize)]); - } - await stream.WriteAsync(Memory.Empty, completeWrites: true); - }, - clientFunction: async connection => - { - await using QuicStream stream = await connection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional); - - for (int pos = 0; pos < data.Length; pos += writeSize) - { - await stream.WriteAsync(data[pos..(pos + writeSize)]); - } - await stream.WriteAsync(Memory.Empty, completeWrites: true); - - byte[] buffer = new byte[data.Length]; - int bytesRead = await ReadAll(stream, buffer); - Assert.Equal(data.Length, bytesRead); - AssertExtensions.SequenceEqual(data, buffer); - } - ); - } - - await (new[] { t1, t2 }).WhenAllOrAnyFailed(millisecondsTimeout: 1000000); - } - [Fact] public async Task ManagedAVE_MinimalFailingTest() { From b040b7a85fa9159908b9401fc7b4e89d8e18aefb Mon Sep 17 00:00:00 2001 From: Radek Zikmund <32671551+rzikm@users.noreply.github.com> Date: Fri, 7 Jun 2024 07:09:30 +0200 Subject: [PATCH 762/783] [release/8.0] Fix NegotiateStream connections between Linux clients and Windows servers (#102216) * Fix NegotiateStream connections between Linux clients and Windows servers (#99909) * Send the NegotiateSeal NTLM flag when client asked for ProtectionLevel.EncryptAndSign. Process the last handshake done message in NegotiateStream. In case of SPNEGO protocol it may contain message integrity check. Additionally, if the negotiated protocol is NTLM then we need to reset the encryption key after the message integrity check is verified. * Add test for the NegotiateSeal flag * Fix the test * Dummy commit * Fix the new _remoteOk logic in NegotiateStream to fire only when HandshakeComplete. If HandshakeComplete is not true, then the authentication blob will get processed with the normal flow. * Fix the value of NegotiateSeal in the final authentication message of Managed NTLM * Fix build * Remove unwanted test change --------- Co-authored-by: Filip Navara Co-authored-by: wfurt --- .../System/Net/Security/FakeNtlmServer.cs | 14 ++++--- .../NegotiateAuthenticationPal.ManagedNtlm.cs | 21 ++++++++-- .../System/Net/Security/NegotiateStream.cs | 11 +++++- .../UnitTests/NegotiateAuthenticationTests.cs | 38 ++++++++++++++++++- 4 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Security/FakeNtlmServer.cs b/src/libraries/Common/tests/System/Net/Security/FakeNtlmServer.cs index cb7a3a785e7faf..1117b3412f35a4 100644 --- a/src/libraries/Common/tests/System/Net/Security/FakeNtlmServer.cs +++ b/src/libraries/Common/tests/System/Net/Security/FakeNtlmServer.cs @@ -42,6 +42,8 @@ public FakeNtlmServer(NetworkCredential expectedCredential) public bool IsAuthenticated { get; private set; } public bool IsMICPresent { get; private set; } public string? ClientSpecifiedSpn { get; private set; } + public Flags InitialClientFlags { get; private set; } + public Flags NegotiatedFlags => _negotiatedFlags; private NetworkCredential _expectedCredential; @@ -83,7 +85,7 @@ private enum MessageType : uint } [Flags] - private enum Flags : uint + public enum Flags : uint { NegotiateUnicode = 0x00000001, NegotiateOEM = 0x00000002, @@ -177,17 +179,17 @@ private static ReadOnlySpan GetField(ReadOnlySpan payload, int field case MessageType.Negotiate: // We don't negotiate, we just verify Assert.True(incomingBlob.Length >= 32); - Flags flags = (Flags)BinaryPrimitives.ReadUInt32LittleEndian(incomingBlob.AsSpan(12, 4)); - Assert.Equal(_requiredFlags, (flags & _requiredFlags)); - Assert.True((flags & (Flags.NegotiateOEM | Flags.NegotiateUnicode)) != 0); - if (flags.HasFlag(Flags.NegotiateDomainSupplied)) + InitialClientFlags = (Flags)BinaryPrimitives.ReadUInt32LittleEndian(incomingBlob.AsSpan(12, 4)); + Assert.Equal(_requiredFlags, (InitialClientFlags & _requiredFlags)); + Assert.True((InitialClientFlags & (Flags.NegotiateOEM | Flags.NegotiateUnicode)) != 0); + if (InitialClientFlags.HasFlag(Flags.NegotiateDomainSupplied)) { string domain = Encoding.ASCII.GetString(GetField(incomingBlob, 16)); Assert.Equal(_expectedCredential.Domain, domain); } _expectedMessageType = MessageType.Authenticate; _negotiateMessage = incomingBlob; - return _challengeMessage = GenerateChallenge(flags); + return _challengeMessage = GenerateChallenge(InitialClientFlags); case MessageType.Authenticate: // Validate the authentication! diff --git a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.ManagedNtlm.cs b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.ManagedNtlm.cs index 794e2ac5790e2f..00f3369e6acec8 100644 --- a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.ManagedNtlm.cs +++ b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.ManagedNtlm.cs @@ -262,8 +262,14 @@ public override void Dispose() { Debug.Assert(incomingBlob.IsEmpty); + Flags requiredFlags = s_requiredFlags; + if (_protectionLevel == ProtectionLevel.EncryptAndSign) + { + requiredFlags |= Flags.NegotiateSeal; + } + _negotiateMessage = new byte[sizeof(NegotiateMessage)]; - CreateNtlmNegotiateMessage(_negotiateMessage); + CreateNtlmNegotiateMessage(_negotiateMessage, requiredFlags); outgoingBlob = _negotiateMessage; statusCode = NegotiateAuthenticationStatusCode.ContinueNeeded; @@ -278,7 +284,7 @@ public override void Dispose() return outgoingBlob; } - private static unsafe void CreateNtlmNegotiateMessage(Span asBytes) + private static unsafe void CreateNtlmNegotiateMessage(Span asBytes, Flags requiredFlags) { Debug.Assert(HeaderLength == NtlmHeader.Length); Debug.Assert(asBytes.Length == sizeof(NegotiateMessage)); @@ -288,7 +294,7 @@ private static unsafe void CreateNtlmNegotiateMessage(Span asBytes) asBytes.Clear(); NtlmHeader.CopyTo(asBytes); message.Header.MessageType = MessageType.Negotiate; - message.Flags = s_requiredFlags; + message.Flags = requiredFlags; message.Version = s_version; } @@ -573,6 +579,13 @@ private static byte[] DeriveKey(ReadOnlySpan exportedSessionKey, ReadOnlyS return null; } + // We already negotiate signing, so we only need to check sealing/encryption. + if ((flags & Flags.NegotiateSeal) == 0 && _protectionLevel == ProtectionLevel.EncryptAndSign) + { + statusCode = NegotiateAuthenticationStatusCode.QopNotSupported; + return null; + } + ReadOnlySpan targetInfo = GetField(challengeMessage.TargetInfo, blob); byte[] targetInfoBuffer = ProcessTargetInfo(targetInfo, out DateTime time, out bool hasNbNames); @@ -607,7 +620,7 @@ private static byte[] DeriveKey(ReadOnlySpan exportedSessionKey, ReadOnlyS NtlmHeader.CopyTo(responseAsSpan); response.Header.MessageType = MessageType.Authenticate; - response.Flags = s_requiredFlags; + response.Flags = s_requiredFlags | (flags & Flags.NegotiateSeal); response.Version = s_version; // Calculate hash for hmac - same for lm2 and ntlm2 diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStream.cs b/src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStream.cs index f26a837e0c110f..8026a955635c7c 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStream.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStream.cs @@ -883,7 +883,16 @@ private async Task ReceiveBlobAsync(CancellationToken cancellationTo if (_framer.ReadHeader.MessageId == FrameHeader.HandshakeDoneId) { - _remoteOk = true; + if (HandshakeComplete && message.Length > 0) + { + Debug.Assert(_context != null); + _context.GetOutgoingBlob(message, out NegotiateAuthenticationStatusCode statusCode); + _remoteOk = statusCode is NegotiateAuthenticationStatusCode.Completed; + } + else + { + _remoteOk = true; + } } else if (_framer.ReadHeader.MessageId != FrameHeader.HandshakeId) { diff --git a/src/libraries/System.Net.Security/tests/UnitTests/NegotiateAuthenticationTests.cs b/src/libraries/System.Net.Security/tests/UnitTests/NegotiateAuthenticationTests.cs index ee909c5b091072..2bb25b13e6aa1d 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/NegotiateAuthenticationTests.cs +++ b/src/libraries/System.Net.Security/tests/UnitTests/NegotiateAuthenticationTests.cs @@ -190,6 +190,42 @@ public void NtlmIncorrectExchangeTest() Assert.False(fakeNtlmServer.IsAuthenticated); } + [ConditionalFact(nameof(IsNtlmAvailable))] + public void NtlmEncryptionTest() + { + using FakeNtlmServer fakeNtlmServer = new FakeNtlmServer(s_testCredentialRight); + + NegotiateAuthentication ntAuth = new NegotiateAuthentication( + new NegotiateAuthenticationClientOptions + { + Package = "NTLM", + Credential = s_testCredentialRight, + TargetName = "HTTP/foo", + RequiredProtectionLevel = ProtectionLevel.EncryptAndSign + }); + + NegotiateAuthenticationStatusCode statusCode; + byte[]? negotiateBlob = ntAuth.GetOutgoingBlob((byte[])null, out statusCode); + Assert.Equal(NegotiateAuthenticationStatusCode.ContinueNeeded, statusCode); + Assert.NotNull(negotiateBlob); + + byte[]? challengeBlob = fakeNtlmServer.GetOutgoingBlob(negotiateBlob); + Assert.NotNull(challengeBlob); + // Validate that the client sent NegotiateSeal flag + Assert.Equal(FakeNtlmServer.Flags.NegotiateSeal, (fakeNtlmServer.InitialClientFlags & FakeNtlmServer.Flags.NegotiateSeal)); + + byte[]? authenticateBlob = ntAuth.GetOutgoingBlob(challengeBlob, out statusCode); + Assert.Equal(NegotiateAuthenticationStatusCode.Completed, statusCode); + Assert.NotNull(authenticateBlob); + + byte[]? empty = fakeNtlmServer.GetOutgoingBlob(authenticateBlob); + Assert.Null(empty); + Assert.True(fakeNtlmServer.IsAuthenticated); + + // Validate that the NegotiateSeal flag survived the full exchange + Assert.Equal(FakeNtlmServer.Flags.NegotiateSeal, (fakeNtlmServer.NegotiatedFlags & FakeNtlmServer.Flags.NegotiateSeal)); + } + [ConditionalFact(nameof(IsNtlmAvailable))] [ActiveIssue("https://github.com/dotnet/runtime/issues/65678", TestPlatforms.OSX | TestPlatforms.iOS | TestPlatforms.MacCatalyst)] public void NtlmSignatureTest() @@ -218,7 +254,7 @@ public void NtlmSignatureTest() fakeNtlmServer.Unwrap(output.WrittenSpan, temp); Assert.Equal(s_Hello, temp); - // Test creating signature on server side and decoding it with VerifySignature on client side + // Test creating signature on server side and decoding it with VerifySignature on client side byte[] serverSignedMessage = new byte[16 + s_Hello.Length]; fakeNtlmServer.Wrap(s_Hello, serverSignedMessage); output.Clear(); From 188b412d83356f3c6cbda8c5d64db8b428066ed5 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Mon, 10 Jun 2024 18:37:26 +0200 Subject: [PATCH 763/783] Fix handling exceptions on shutdown (#101915) A recent partial backport of a change to enable propagating exceptions on shutdown was missing two places in the code that were under a different condition than the global exception handling disabling that was removed. I must have made a mistake when testing that change (not setting watson registry settings properly or using a stale build). This change makes it work correctly. --- src/coreclr/vm/excep.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index b88d6a959bb321..9fe9376fd58efa 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -6696,14 +6696,6 @@ VEH_ACTION WINAPI CLRVectoredExceptionHandlerPhase3(PEXCEPTION_POINTERS pExcepti VEH_ACTION WINAPI CLRVectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo) { - // It is not safe to execute code inside VM after we shutdown EE. One example is DisablePreemptiveGC - // will block forever. - if (g_fForbidEnterEE) - { - return VEH_CONTINUE_SEARCH; - } - - // // DO NOT USE CONTRACTS HERE AS THIS ROUTINE MAY NEVER RETURN. You can use // static contracts, but currently this is all WRAPPER_NO_CONTRACT. @@ -7385,12 +7377,6 @@ LONG WINAPI CLRVectoredExceptionHandlerShim(PEXCEPTION_POINTERS pExceptionInfo) // WARNING WARNING WARNING WARNING WARNING WARNING WARNING // - // If runtime have been disabled, then simply return. - if (g_fForbidEnterEE) - { - return EXCEPTION_CONTINUE_SEARCH; - } - // WARNING // // We must preserve this so that GCStress=4 eh processing doesnt kill last error. From 4a8d5a007971d19f389ca17f7b8eb4f9bb199991 Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Mon, 10 Jun 2024 18:31:17 +0000 Subject: [PATCH 764/783] Limit the size of OID supported by AsnDecoder/AsnReader --- .../Cryptography/DSAKeyFormatHelper.cs | 82 +++++-- .../DSA/DSAKeyFileTests.cs | 146 ++++++++++++ .../src/Resources/Strings.resx | 3 + .../src/System.Formats.Asn1.csproj | 6 + .../src/System/Formats/Asn1/AsnDecoder.Oid.cs | 53 +++++ .../Formats/Asn1/LocalAppContextSwitches.cs | 17 ++ .../tests/Reader/ReadObjectIdentifier.cs | 219 ++++++++++++++---- .../tests/System.Formats.Asn1.Tests.csproj | 1 + 8 files changed, 464 insertions(+), 63 deletions(-) create mode 100644 src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/LocalAppContextSwitches.cs diff --git a/src/libraries/Common/src/System/Security/Cryptography/DSAKeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/DSAKeyFormatHelper.cs index 63c7b451e142b4..57f3344c18954c 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/DSAKeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/DSAKeyFormatHelper.cs @@ -25,16 +25,6 @@ internal static void ReadDsaPrivateKey( throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } - DssParms parms = DssParms.Decode(algId.Parameters.Value, AsnEncodingRules.BER); - - ret = new DSAParameters - { - P = parms.P.ToByteArray(isUnsigned: true, isBigEndian: true), - Q = parms.Q.ToByteArray(isUnsigned: true, isBigEndian: true), - }; - - ret.G = parms.G.ExportKeyParameter(ret.P.Length); - BigInteger x; try @@ -57,6 +47,34 @@ internal static void ReadDsaPrivateKey( throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } + DssParms parms = DssParms.Decode(algId.Parameters.Value, AsnEncodingRules.BER); + + // Sanity checks from FIPS 186-4 4.1/4.2. Since FIPS 186-5 withdrew DSA/DSS + // these will never change again. + // + // This technically allows a non-standard combination of 1024-bit P and 256-bit Q, + // but that will get filtered out by the underlying provider. + // These checks just prevent obviously bad data from wasting work on reinterpretation. + + if (parms.P.Sign < 0 || + parms.Q.Sign < 0 || + !IsValidPLength(parms.P.GetBitLength()) || + !IsValidQLength(parms.Q.GetBitLength()) || + parms.G <= 1 || + parms.G >= parms.P || + x <= 1 || + x >= parms.Q) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + ret = new DSAParameters + { + P = parms.P.ToByteArray(isUnsigned: true, isBigEndian: true), + Q = parms.Q.ToByteArray(isUnsigned: true, isBigEndian: true), + }; + + ret.G = parms.G.ExportKeyParameter(ret.P.Length); ret.X = x.ExportKeyParameter(ret.Q.Length); // The public key is not contained within the format, calculate it. @@ -69,6 +87,11 @@ internal static void ReadDsaPublicKey( in AlgorithmIdentifierAsn algId, out DSAParameters ret) { + if (!algId.Parameters.HasValue) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + BigInteger y; try @@ -88,13 +111,27 @@ internal static void ReadDsaPublicKey( throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } - if (!algId.Parameters.HasValue) + DssParms parms = DssParms.Decode(algId.Parameters.Value, AsnEncodingRules.BER); + + // Sanity checks from FIPS 186-4 4.1/4.2. Since FIPS 186-5 withdrew DSA/DSS + // these will never change again. + // + // This technically allows a non-standard combination of 1024-bit P and 256-bit Q, + // but that will get filtered out by the underlying provider. + // These checks just prevent obviously bad data from wasting work on reinterpretation. + + if (parms.P.Sign < 0 || + parms.Q.Sign < 0 || + !IsValidPLength(parms.P.GetBitLength()) || + !IsValidQLength(parms.Q.GetBitLength()) || + parms.G <= 1 || + parms.G >= parms.P || + y <= 1 || + y >= parms.P) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } - DssParms parms = DssParms.Decode(algId.Parameters.Value, AsnEncodingRules.BER); - ret = new DSAParameters { P = parms.P.ToByteArray(isUnsigned: true, isBigEndian: true), @@ -105,6 +142,25 @@ internal static void ReadDsaPublicKey( ret.Y = y.ExportKeyParameter(ret.P.Length); } + private static bool IsValidPLength(long pBitLength) + { + return pBitLength switch + { + // FIPS 186-3/186-4 + 1024 or 2048 or 3072 => true, + // FIPS 186-1/186-2 + >= 512 and < 1024 => pBitLength % 64 == 0, + _ => false, + }; + } + + private static bool IsValidQLength(long qBitLength) + { + // FIPS 186-1/186-2 only allows 160 + // FIPS 186-3/186-4 allow 160/224/256 + return qBitLength is 160 or 224 or 256; + } + internal static void ReadSubjectPublicKeyInfo( ReadOnlySpan source, out int bytesRead, diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAKeyFileTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAKeyFileTests.cs index 980a8a9194c83e..3d655f77ea96b1 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAKeyFileTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAKeyFileTests.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Formats.Asn1; +using System.Numerics; using System.Security.Cryptography.Encryption.RC2.Tests; using System.Text; using Test.Cryptography; @@ -302,6 +304,150 @@ public static void ReadWriteDsa2048SubjectPublicKeyInfo() DSATestData.GetDSA2048Params()); } + [Fact] + [SkipOnPlatform(TestPlatforms.OSX, "DSASecurityTransforms goes straight to OS, has different failure mode")] + public static void ImportNonsensePublicParameters() + { + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + + DSAParameters validParameters = DSATestData.GetDSA2048Params(); + BigInteger p = new BigInteger(validParameters.P, true, true); + BigInteger q = new BigInteger(validParameters.Q, true, true); + BigInteger g = new BigInteger(validParameters.G, true, true); + BigInteger y = new BigInteger(validParameters.Y, true, true); + + using (DSA dsa = DSAFactory.Create()) + { + // 1 < y < p, 1 < g < p, q is 160/224/256 bits + // p is 512..1024 % 64, or 1024/2048/3072 bits + ImportSPKI(dsa, p, q, g, p, writer); + ImportSPKI(dsa, p, q, g, BigInteger.One, writer); + ImportSPKI(dsa, p, q, g, BigInteger.MinusOne, writer); + ImportSPKI(dsa, p, q, p, y, writer); + ImportSPKI(dsa, p, q, -g, y, writer); + ImportSPKI(dsa, p, q, BigInteger.One, y, writer); + ImportSPKI(dsa, p, q, BigInteger.MinusOne, y, writer); + ImportSPKI(dsa, p, q << 1, g, y, writer); + ImportSPKI(dsa, p, q >> 1, g, y, writer); + ImportSPKI(dsa, p, -q, g, y, writer); + ImportSPKI(dsa, p >> 1, q, g, y, writer); + ImportSPKI(dsa, p << 1, q, g, y, writer); + ImportSPKI(dsa, BigInteger.One << 4095, q, 2, 97, writer); + } + + static void ImportSPKI( + DSA key, + BigInteger p, + BigInteger q, + BigInteger g, + BigInteger y, + AsnWriter writer) + { + writer.Reset(); + writer.WriteInteger(y); + byte[] encodedPublicKey = writer.Encode(); + writer.Reset(); + + using (writer.PushSequence()) + { + using (writer.PushSequence()) + { + writer.WriteObjectIdentifier("1.2.840.10040.4.1"); + + using (writer.PushSequence()) + { + writer.WriteInteger(p); + writer.WriteInteger(q); + writer.WriteInteger(g); + } + } + + writer.WriteBitString(encodedPublicKey); + } + + byte[] spki = writer.Encode(); + writer.Reset(); + + AssertExtensions.ThrowsContains( + () => key.ImportSubjectPublicKeyInfo(spki, out _), + "corrupted"); + } + } + + [Fact] + public static void ImportNonsensePrivateParameters() + { + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + + DSAParameters validParameters = DSATestData.GetDSA2048Params(); + BigInteger p = new BigInteger(validParameters.P, true, true); + BigInteger q = new BigInteger(validParameters.Q, true, true); + BigInteger g = new BigInteger(validParameters.G, true, true); + BigInteger x = new BigInteger(validParameters.X, true, true); + + using (DSA dsa = DSAFactory.Create()) + { + // 1 < x < q, 1 < g < p, q is 160/224/256 bits + // p is 512..1024 % 64, or 1024/2048/3072 bits + ImportPkcs8(dsa, p, q, g, q, writer); + ImportPkcs8(dsa, p, q, g, BigInteger.One, writer); + // x = -1 gets re-interpreted as x = 255 because of a CAPI compat issue. + //ImportPkcs8(dsa, p, q, g, BigInteger.MinusOne, writer); + ImportPkcs8(dsa, p, q, g, -x, writer); + ImportPkcs8(dsa, p, q, p, x, writer); + ImportPkcs8(dsa, p, q, -g, x, writer); + ImportPkcs8(dsa, p, q, BigInteger.One, x, writer); + ImportPkcs8(dsa, p, q, BigInteger.MinusOne, x, writer); + ImportPkcs8(dsa, p, q << 1, g, x, writer); + ImportPkcs8(dsa, p, q >> 1, g, x, writer); + ImportPkcs8(dsa, p >> 1, q, g, x, writer); + ImportPkcs8(dsa, p << 1, q, g, x, writer); + ImportPkcs8(dsa, -q, q, g, x, writer); + ImportPkcs8(dsa, BigInteger.One << 4095, q, 2, 97, writer); + ImportPkcs8(dsa, -p, q, g, x, writer); + } + + static void ImportPkcs8( + DSA key, + BigInteger p, + BigInteger q, + BigInteger g, + BigInteger x, + AsnWriter writer) + { + writer.Reset(); + + using (writer.PushSequence()) + { + writer.WriteInteger(0); + + using (writer.PushSequence()) + { + writer.WriteObjectIdentifier("1.2.840.10040.4.1"); + + using (writer.PushSequence()) + { + writer.WriteInteger(p); + writer.WriteInteger(q); + writer.WriteInteger(g); + } + } + + using (writer.PushOctetString()) + { + writer.WriteInteger(x); + } + } + + byte[] pkcs8 = writer.Encode(); + writer.Reset(); + + AssertExtensions.ThrowsContains( + () => key.ImportPkcs8PrivateKey(pkcs8, out _), + "corrupted"); + } + } + [Fact] public static void NoFuzzySubjectPublicKeyInfo() { diff --git a/src/libraries/System.Formats.Asn1/src/Resources/Strings.resx b/src/libraries/System.Formats.Asn1/src/Resources/Strings.resx index 3b028a6f3c90d5..c05cd4bee55a45 100644 --- a/src/libraries/System.Formats.Asn1/src/Resources/Strings.resx +++ b/src/libraries/System.Formats.Asn1/src/Resources/Strings.resx @@ -144,6 +144,9 @@ The encoded named bit list value is larger than the value size of the '{0}' enum. + + The encoded object identifier (OID) exceeds the limits supported by this library. Supported OIDs are limited to 64 arcs and each subidentifier is limited to a 128-bit value. + The encoded value uses a constructed encoding, which is invalid for '{0}' values. diff --git a/src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csproj b/src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csproj index a899353cd4a050..f8831d6ee17e0a 100644 --- a/src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csproj +++ b/src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csproj @@ -4,6 +4,8 @@ true $(DefineConstants);CP_NO_ZEROMEMORY true + true + 1 Provides classes that can read and write the ASN.1 BER, CER, and DER data formats. Commonly Used Types: @@ -12,6 +14,9 @@ System.Formats.Asn1.AsnWriter + + Common\System\LocalAppContextSwitches.Common.cs + Common\System\Security\Cryptography\CryptoPool.cs @@ -49,6 +54,7 @@ System.Formats.Asn1.AsnWriter + diff --git a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Oid.cs b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Oid.cs index fac90e12aec1c2..e46f04b6f308ad 100644 --- a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Oid.cs +++ b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Oid.cs @@ -90,15 +90,55 @@ private static void ReadSubIdentifier( throw new AsnContentException(); } + // Set semanticBits to a value such that on the first + // iteration of the loop it becomes the correct value. + // So each entry here is [real semantic bits for this value] - 7. + int semanticBits = source[0] switch + { + >= 0b1100_0000 => 0, + >= 0b1010_0000 => -1, + >= 0b1001_0000 => -2, + >= 0b1000_1000 => -3, + >= 0b1000_0100 => -4, + >= 0b1000_0010 => -5, + >= 0b1000_0001 => -6, + _ => 0, + }; + // First, see how long the segment is int end = -1; int idx; + // None of T-REC-X.660-201107, T-REC-X.680-201508, or T-REC-X.690-201508 + // have any recommendations for a minimum (or maximum) size of a + // sub-identifier. + // + // T-REC-X.667-201210 (and earlier versions) discuss the no-registration- + // required UUID space at 2.25.{UUID}, where UUIDs are defined as 128-bit + // values. This gives us a minimum lower bound of 128-bit. + // + // Windows Crypt32 has historically only supported 64-bit values, and + // the "size limitations" FAQ on oid-info.com says that the largest arc + // value is a 39-digit value that corresponds to a 2.25.UUID value. + // + // So, until something argues for a bigger number, our bit-limit is 128. + const int MaxAllowedBits = 128; + for (idx = 0; idx < source.Length; idx++) { // If the high bit isn't set this marks the end of the sub-identifier. bool endOfIdentifier = (source[idx] & 0x80) == 0; + if (!LocalAppContextSwitches.AllowAnySizeOid) + { + semanticBits += 7; + + if (semanticBits > MaxAllowedBits) + { + throw new AsnContentException(SR.ContentException_OidTooBig); + } + } + if (endOfIdentifier) { end = idx; @@ -265,8 +305,21 @@ private static string ReadObjectIdentifier(ReadOnlySpan contents) contents = contents.Slice(bytesRead); + const int MaxArcs = 64; + int remainingArcs = MaxArcs - 2; + while (!contents.IsEmpty) { + if (!LocalAppContextSwitches.AllowAnySizeOid) + { + if (remainingArcs <= 0) + { + throw new AsnContentException(SR.ContentException_OidTooBig); + } + + remainingArcs--; + } + ReadSubIdentifier(contents, out bytesRead, out smallValue, out largeValue); // Exactly one should be non-null. Debug.Assert((smallValue == null) != (largeValue == null)); diff --git a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/LocalAppContextSwitches.cs b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/LocalAppContextSwitches.cs new file mode 100644 index 00000000000000..62722d7f4d0008 --- /dev/null +++ b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/LocalAppContextSwitches.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; + +namespace System +{ + internal static partial class LocalAppContextSwitches + { + private static int s_allowAnySizeOid; + public static bool AllowAnySizeOid + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetCachedSwitchValue("System.Formats.Asn1.AllowAnySizeOid", ref s_allowAnySizeOid); + } + } +} diff --git a/src/libraries/System.Formats.Asn1/tests/Reader/ReadObjectIdentifier.cs b/src/libraries/System.Formats.Asn1/tests/Reader/ReadObjectIdentifier.cs index c1add074220a06..6584fd47b8f6ba 100644 --- a/src/libraries/System.Formats.Asn1/tests/Reader/ReadObjectIdentifier.cs +++ b/src/libraries/System.Formats.Asn1/tests/Reader/ReadObjectIdentifier.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Text; +using Microsoft.DotNet.RemoteExecutor; using Test.Cryptography; using Xunit; @@ -198,70 +199,188 @@ public static void ExpectedTag_IgnoresConstructed( [InlineData(AsnEncodingRules.BER)] [InlineData(AsnEncodingRules.CER)] [InlineData(AsnEncodingRules.DER)] - public static void ReadVeryLongOid(AsnEncodingRules ruleSet) + public static void ReadMaximumArcOid(AsnEncodingRules ruleSet) { - byte[] inputData = new byte[100000]; - // 06 83 02 00 00 (OBJECT IDENTIFIER, 65536 bytes). - inputData[0] = 0x06; - inputData[1] = 0x83; - inputData[2] = 0x01; - inputData[3] = 0x00; - inputData[4] = 0x00; - // and the rest are all zero. - - // The first byte produces "0.0". Each of the remaining 65535 bytes produce - // another ".0". - const int ExpectedLength = 65536 * 2 + 1; - StringBuilder builder = new StringBuilder(ExpectedLength); - builder.Append('0'); - - for (int i = 0; i <= ushort.MaxValue; i++) + const int MaxArcs = 64; + // MaxArcs content bytes (all 0x7F) (which includes one for failure), plus one for the tag + // plus one for the encoded length. + byte[] input = new byte[MaxArcs + 2]; + input.AsSpan().Fill(0x7F); + input[0] = 0x06; + // The first two arcs are encoded in the first sub-identifier, so MaxArcs - 1. + input[1] = MaxArcs - 1; + + string decoded = AsnDecoder.ReadObjectIdentifier(input, ruleSet, out int consumed); + Assert.Equal(input.Length - 1, consumed); + + StringBuilder expected = new StringBuilder(4 * MaxArcs); + expected.Append("2.47"); + + for (int i = 2; i < MaxArcs; i++) { - builder.Append('.'); - builder.Append(0); + expected.Append(".127"); } - AsnReader reader = new AsnReader(inputData, ruleSet); - string oidString = reader.ReadObjectIdentifier(); + Assert.Equal(expected.ToString(), decoded); - Assert.Equal(ExpectedLength, oidString.Length); - Assert.Equal(builder.ToString(), oidString); + input[1] = MaxArcs; + AsnContentException ex = Assert.Throws( + () => AsnDecoder.ReadObjectIdentifier(input, ruleSet, out _)); + Assert.Contains("OID", ex.Message); } [Theory] [InlineData(AsnEncodingRules.BER)] [InlineData(AsnEncodingRules.CER)] [InlineData(AsnEncodingRules.DER)] - public static void ReadVeryLongOidArc(AsnEncodingRules ruleSet) + public static void ReadMaximumInitialSubIdentifier(AsnEncodingRules ruleSet) { - byte[] inputData = new byte[255]; - // 06 81 93 (OBJECT IDENTIFIER, 147 bytes). - inputData[0] = 0x06; - inputData[1] = 0x81; - inputData[2] = 0x93; - - // With 147 bytes we get 147*7 = 1029 value bits. - // The smallest legal number to encode would have a top byte of 0x81, - // leaving 1022 bits remaining. If they're all zero then we have 2^1022. - // - // Since it's our first sub-identifier it's really encoding "2.(2^1022 - 80)". - inputData[3] = 0x81; - // Leave the last byte as 0. - new Span(inputData, 4, 145).Fill(0x80); - - const string ExpectedOid = - "2." + - "449423283715578976932326297697256183404494244735576643183575" + - "202894331689513752407831771193306018840052800284699678483394" + - "146974422036041556232118576598685310944419733562163713190755" + - "549003115235298632707380212514422095376705856157203684782776" + - "352068092908376276711465745599868114846199290762088390824060" + - "56034224"; + // First sub-identifier is 2^128 - 1, second is 1 + byte[] valid = + { + 0x06, 0x14, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x01, + }; - AsnReader reader = new AsnReader(inputData, ruleSet); + // First sub-identifier is 2^128, second is 1 + byte[] invalid = + { + 0x06, 0x14, 0x84, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x00, 0x01, + }; + + string oid = AsnDecoder.ReadObjectIdentifier(valid, ruleSet, out int consumed); + Assert.Equal(valid.Length, consumed); + Assert.Equal("2.340282366920938463463374607431768211375.1", oid); + + AsnContentException ex = Assert.Throws( + () => AsnDecoder.ReadObjectIdentifier(invalid, ruleSet, out _)); + Assert.Contains("OID", ex.Message); + } - string oidString = reader.ReadObjectIdentifier(); - Assert.Equal(ExpectedOid, oidString); + [Theory] + [InlineData(AsnEncodingRules.BER)] + [InlineData(AsnEncodingRules.CER)] + [InlineData(AsnEncodingRules.DER)] + public static void ReadMaximumNonInitialSubIdentifier(AsnEncodingRules ruleSet) + { + // First sub-identifier is 1, second is 2^128 - 1 + byte[] valid = + { + 0x06, 0x14, 0x01, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, + }; + + // First sub-identifier is 1, second is 2^128 + byte[] invalid = new byte[] + { + 0x06, 0x14, 0x01, 0x84, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, + }; + + string oid = AsnDecoder.ReadObjectIdentifier(valid, ruleSet, out int consumed); + Assert.Equal(valid.Length, consumed); + Assert.Equal("0.1.340282366920938463463374607431768211455", oid); + + AsnContentException ex = Assert.Throws( + () => AsnDecoder.ReadObjectIdentifier(invalid, ruleSet, out _)); + Assert.Contains("OID", ex.Message); + } + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public static void ReadVeryLongOid_WithAppContext() + { + RemoteExecutor.Invoke( + static () => + { + AppContext.SetSwitch("System.Formats.Asn1.AllowAnySizeOid", true); + + byte[] inputData = new byte[100000]; + // 06 83 02 00 00 (OBJECT IDENTIFIER, 65536 bytes). + inputData[0] = 0x06; + inputData[1] = 0x83; + inputData[2] = 0x01; + inputData[3] = 0x00; + inputData[4] = 0x00; + // and the rest are all zero. + + // The first byte produces "0.0". Each of the remaining 65535 bytes produce + // another ".0". + const int ExpectedLength = 65536 * 2 + 1; + StringBuilder builder = new StringBuilder(ExpectedLength); + builder.Append('0'); + + for (int i = 0; i <= ushort.MaxValue; i++) + { + builder.Append('.'); + builder.Append(0); + } + + AsnEncodingRules[] ruleSets = + { + AsnEncodingRules.BER, + AsnEncodingRules.CER, + AsnEncodingRules.DER, + }; + + foreach (AsnEncodingRules ruleSet in ruleSets) + { + AsnReader reader = new AsnReader(inputData, ruleSet); + string oidString = reader.ReadObjectIdentifier(); + + Assert.Equal(ExpectedLength, oidString.Length); + Assert.Equal(builder.ToString(), oidString); + } + }).Dispose(); + } + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public static void ReadVeryLongOidArc_WithAppContext() + { + RemoteExecutor.Invoke( + static () => + { + AppContext.SetSwitch("System.Formats.Asn1.AllowAnySizeOid", true); + + byte[] inputData = new byte[255]; + // 06 81 93 (OBJECT IDENTIFIER, 147 bytes). + inputData[0] = 0x06; + inputData[1] = 0x81; + inputData[2] = 0x93; + + // With 147 bytes we get 147*7 = 1029 value bits. + // The smallest legal number to encode would have a top byte of 0x81, + // leaving 1022 bits remaining. If they're all zero then we have 2^1022. + // + // Since it's our first sub-identifier it's really encoding "2.(2^1022 - 80)". + inputData[3] = 0x81; + // Leave the last byte as 0. + new Span(inputData, 4, 145).Fill(0x80); + + const string ExpectedOid = + "2." + + "449423283715578976932326297697256183404494244735576643183575" + + "202894331689513752407831771193306018840052800284699678483394" + + "146974422036041556232118576598685310944419733562163713190755" + + "549003115235298632707380212514422095376705856157203684782776" + + "352068092908376276711465745599868114846199290762088390824060" + + "56034224"; + + AsnEncodingRules[] ruleSets = + { + AsnEncodingRules.BER, + AsnEncodingRules.CER, + AsnEncodingRules.DER, + }; + + foreach (AsnEncodingRules ruleSet in ruleSets) + { + AsnReader reader = new AsnReader(inputData, ruleSet); + + string oidString = reader.ReadObjectIdentifier(); + Assert.Equal(ExpectedOid, oidString); + } + }).Dispose(); } } } diff --git a/src/libraries/System.Formats.Asn1/tests/System.Formats.Asn1.Tests.csproj b/src/libraries/System.Formats.Asn1/tests/System.Formats.Asn1.Tests.csproj index 68bdc72edf895f..83d8041222f6c9 100644 --- a/src/libraries/System.Formats.Asn1/tests/System.Formats.Asn1.Tests.csproj +++ b/src/libraries/System.Formats.Asn1/tests/System.Formats.Asn1.Tests.csproj @@ -2,6 +2,7 @@ true $(NetCoreAppCurrent);$(NetFrameworkMinimum) + true From 7b381d47f734f152430a496524bc73858d0d2bbb Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 11:48:47 -0700 Subject: [PATCH 765/783] [release/8.0-staging] Update dependencies from dotnet/runtime-assets (#102494) * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 * Update dependencies from https://github.com/dotnet/runtime-assets build 20240520.1 Microsoft.DotNet.CilStrip.Sources , System.ComponentModel.TypeConverter.TestData , System.Data.Common.TestData , System.Drawing.Common.TestData , System.Formats.Tar.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Runtime.Numerics.TestData , System.Runtime.TimeZoneData , System.Security.Cryptography.X509Certificates.TestData , System.Text.RegularExpressions.TestData , System.Windows.Extensions.TestData From Version 8.0.0-beta.24211.2 -> To Version 8.0.0-beta.24270.1 --------- Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 1 - eng/Version.Details.xml | 56 ++++++++++++++++++++--------------------- eng/Versions.props | 28 ++++++++++----------- 3 files changed, 42 insertions(+), 43 deletions(-) diff --git a/NuGet.config b/NuGet.config index 3e394d788ef3af..f6e25f4daf50d1 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,6 @@ - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3a2af9bbaf8539..e619a5f8c0c67d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -185,57 +185,57 @@ https://github.com/dotnet/arcade 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 https://github.com/dotnet/llvm-project @@ -358,9 +358,9 @@ https://github.com/dotnet/hotreload-utils 61f137aacabdbd8f279415287a2dd70e150f5eb1 - + https://github.com/dotnet/runtime-assets - dc8ac7417ae48bfbf2516a346723107af0ad603d + 20ef600733c107d19f57de4955dfb025d39b99e3 https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index ad4ed3a86fa76a..a68243225e11d2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -143,20 +143,20 @@ 4.5.0 8.0.0-rc.1.23406.6 - 8.0.0-beta.24211.2 - 8.0.0-beta.24211.2 - 8.0.0-beta.24211.2 - 8.0.0-beta.24211.2 - 8.0.0-beta.24211.2 - 8.0.0-beta.24211.2 - 8.0.0-beta.24211.2 - 8.0.0-beta.24211.2 - 8.0.0-beta.24211.2 - 8.0.0-beta.24211.2 - 8.0.0-beta.24211.2 - 8.0.0-beta.24211.2 - 8.0.0-beta.24211.2 - 8.0.0-beta.24211.2 + 8.0.0-beta.24270.1 + 8.0.0-beta.24270.1 + 8.0.0-beta.24270.1 + 8.0.0-beta.24270.1 + 8.0.0-beta.24270.1 + 8.0.0-beta.24270.1 + 8.0.0-beta.24270.1 + 8.0.0-beta.24270.1 + 8.0.0-beta.24270.1 + 8.0.0-beta.24270.1 + 8.0.0-beta.24270.1 + 8.0.0-beta.24270.1 + 8.0.0-beta.24270.1 + 8.0.0-beta.24270.1 1.0.0-prerelease.23566.3 1.0.0-prerelease.23566.3 From 95ab6fe36e70b3e576e003977364acee50b69968 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 11:49:16 -0700 Subject: [PATCH 766/783] [release/8.0] Update dependencies from dotnet/emsdk (#102505) * Update dependencies from https://github.com/dotnet/emsdk build 20240521.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.7-servicing.24270.2 -> To Version 8.0.7-servicing.24271.1 * Block v8, same as on net8-staging and net9 branches. * Update dependencies from https://github.com/dotnet/emsdk build 20240527.3 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.7-servicing.24270.2 -> To Version 8.0.7-servicing.24277.3 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Ilona Tomkowicz --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- ...em.Globalization.Calendars.Hybrid.WASM.Tests.csproj | 10 +++++++++- .../System.Globalization.Hybrid.WASM.Tests.csproj | 8 ++++++++ 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/NuGet.config b/NuGet.config index d74a62c8f125c8..1bea60ba70c248 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index aba57a86483449..99589f6331a8d2 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - a3c7d8205559d673de8b7cdafd6d80d5f4d2cfed + f0463b32eee396d2d1caac58b271d683c7da2333 - + https://github.com/dotnet/emsdk - a3c7d8205559d673de8b7cdafd6d80d5f4d2cfed + f0463b32eee396d2d1caac58b271d683c7da2333 diff --git a/src/libraries/System.Globalization.Calendars/tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj b/src/libraries/System.Globalization.Calendars/tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj index 5b898363764087..79d84271152dc4 100644 --- a/src/libraries/System.Globalization.Calendars/tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj +++ b/src/libraries/System.Globalization.Calendars/tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj @@ -5,6 +5,14 @@ true true + + + WasmTestOnBrowser + $(TestArchiveRoot)browserornodejs/ + $(TestArchiveTestsRoot)$(OSPlatformConfig)/ + $(DefineConstants);TARGET_BROWSER + true + @@ -106,4 +114,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj b/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj index a39604c1cfaccd..f4e811abb490be 100644 --- a/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj +++ b/src/libraries/System.Globalization/tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj @@ -6,6 +6,14 @@ true true + + + WasmTestOnBrowser + $(TestArchiveRoot)browserornodejs/ + $(TestArchiveTestsRoot)$(OSPlatformConfig)/ + $(DefineConstants);TARGET_BROWSER + true + From 16715378e5557c4f0fc865e6e3f68785058e65e9 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 11:52:01 -0700 Subject: [PATCH 767/783] [release/8.0-staging] Update dependencies from dotnet/emsdk (#102506) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/dotnet/emsdk build 20240521.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.6-servicing.24264.1 -> To Version 8.0.7-servicing.24271.1 * Update dependencies from https://github.com/dotnet/emsdk build 20240527.3 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.6-servicing.24264.1 -> To Version 8.0.7-servicing.24277.3 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- NuGet.config | 1 + eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/NuGet.config b/NuGet.config index f6e25f4daf50d1..1bea60ba70c248 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,6 +9,7 @@ + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e619a5f8c0c67d..d2b215265a4c93 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -90,13 +90,13 @@ 45dd3a73dd5b64b010c4251303b3664bb30df029 - + https://github.com/dotnet/emsdk - 16d77ddacb12870344abbc4831387cc3e8f97168 + f0463b32eee396d2d1caac58b271d683c7da2333 - + https://github.com/dotnet/emsdk - 16d77ddacb12870344abbc4831387cc3e8f97168 + f0463b32eee396d2d1caac58b271d683c7da2333 diff --git a/eng/Versions.props b/eng/Versions.props index a68243225e11d2..abc824d58b29d6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -240,7 +240,7 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport --> - 8.0.6 + 8.0.7 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda From 7446a8b922319b88727dce93009fb60a9fed7bc8 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Mon, 10 Jun 2024 12:15:25 -0700 Subject: [PATCH 768/783] [workload] Use the same naming as net9 workload (#103049) * Use the same naming as net9 workload * Add aliases to the versioned packs * Fixup AOTCompiler import * Fix aliases * Update WorkloadManifest.json.in Fix alias * Update WorkloadManifest.targets.in --- ...ad.Mono.Toolchain.Current.Manifest.pkgproj | 1 + .../WorkloadManifest.json.in | 253 +++++++++++------- .../WorkloadManifest.targets.in | 68 ++--- 3 files changed, 196 insertions(+), 126 deletions(-) diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest.pkgproj b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest.pkgproj index e327fcf2635a2a..b7d58cbebf6ba2 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest.pkgproj +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest.pkgproj @@ -42,6 +42,7 @@ + <_WorkloadManifestValues Include="NetVersion" Value="net8" /> <_WorkloadManifestValues Include="WorkloadVersion" Value="$(PackageVersion)" /> <_WorkloadManifestValues Include="PackageVersion" Value="$(PackageVersion)" /> <_WorkloadManifestValues Include="PackageVersionNet6" Value="$(PackageVersionNet6)" /> diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in index 076e642d2b6209..a6ca85da25d9bb 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in @@ -5,30 +5,30 @@ }, "workloads": { "wasm-tools": { - "description": ".NET WebAssembly build tools for net8.0", + "description": ".NET WebAssembly build tools for ${NetVersion}.0", "packs": [ - "Microsoft.NET.Runtime.WebAssembly.Sdk", - "Microsoft.NETCore.App.Runtime.Mono.browser-wasm", - "Microsoft.NETCore.App.Runtime.AOT.Cross.browser-wasm" + "Microsoft.NET.Runtime.WebAssembly.Sdk.${NetVersion}", + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.browser-wasm", + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.browser-wasm" ], "extends": [ "microsoft-net-runtime-mono-tooling", "microsoft-net-sdk-emscripten" ], "platforms": [ "win-x64", "win-arm64", "linux-x64", "linux-arm64", "osx-x64", "osx-arm64"] }, "wasm-experimental": { - "description": ".NET WebAssembly experimental tooling for net8.0", + "description": ".NET WebAssembly experimental tooling for ${NetVersion}.0", "packs": [ - "Microsoft.NET.Runtime.WebAssembly.Templates", - "Microsoft.NETCore.App.Runtime.Mono.multithread.browser-wasm", + "Microsoft.NET.Runtime.WebAssembly.Templates.${NetVersion}", + "Microsoft.NETCore.App.Runtime.Mono.multithread.${NetVersion}.browser-wasm", ], "extends": [ "wasm-tools" ], "platforms": [ "win-x64", "win-arm64", "linux-x64", "linux-arm64", "osx-x64", "osx-arm64" ] }, "wasi-experimental": { - "description": ".NET WASI experimental for net8.0", + "description": ".NET WASI experimental for ${NetVersion}.0", "packs": [ - "Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk", - "Microsoft.NETCore.App.Runtime.Mono.wasi-wasm", - "Microsoft.NET.Runtime.WebAssembly.Templates" + "Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk.${NetVersion}", + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.wasi-wasm", + "Microsoft.NET.Runtime.WebAssembly.Templates.${NetVersion}" ], "extends": [ "microsoft-net-runtime-mono-tooling" ], "platforms": [ "win-x64", "win-arm64", "linux-x64", "linux-arm64", "osx-x64", "osx-arm64" ] @@ -36,7 +36,7 @@ "mobile-librarybuilder": { "description": "Mobile SDK for building a self-contained .NET native library", "packs": [ - "Microsoft.NET.Runtime.LibraryBuilder.Sdk" + "Microsoft.NET.Runtime.LibraryBuilder.Sdk.${NetVersion}" ], "extends": [ "microsoft-net-runtime-android-aot", "microsoft-net-runtime-ios", "microsoft-net-runtime-maccatalyst", "microsoft-net-runtime-tvos" ], "platforms": [ "win-x64", "win-arm64", "osx-x64", "osx-arm64" ] @@ -45,10 +45,10 @@ "abstract": true, "description": "Android Mono Runtime", "packs": [ - "Microsoft.NETCore.App.Runtime.Mono.android-arm", - "Microsoft.NETCore.App.Runtime.Mono.android-arm64", - "Microsoft.NETCore.App.Runtime.Mono.android-x64", - "Microsoft.NETCore.App.Runtime.Mono.android-x86" + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.android-arm", + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.android-arm64", + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.android-x64", + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.android-x86" ], "extends": [ "microsoft-net-runtime-mono-tooling" ], "platforms": [ "win-x64", "win-arm64", "linux-x64", "osx-x64", "osx-arm64" ] @@ -57,10 +57,10 @@ "abstract": true, "description": "Android Mono AOT Workload", "packs": [ - "Microsoft.NETCore.App.Runtime.AOT.Cross.android-x86", - "Microsoft.NETCore.App.Runtime.AOT.Cross.android-x64", - "Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm", - "Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm64" + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.android-x86", + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.android-x64", + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.android-arm", + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.android-arm64" ], "extends": [ "microsoft-net-runtime-android" ], "platforms": [ "win-x64", "win-arm64", "linux-x64", "osx-x64", "osx-arm64" ] @@ -69,9 +69,9 @@ "abstract": true, "description": "iOS Mono Runtime and AOT Workload", "packs": [ - "Microsoft.NETCore.App.Runtime.AOT.Cross.ios-arm64", - "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-arm64", - "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-x64" + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.ios-arm64", + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.iossimulator-arm64", + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.iossimulator-x64" ], "extends": [ "runtimes-ios" ], "platforms": [ "win-x64", "win-arm64", "osx-arm64", "osx-x64" ] @@ -80,9 +80,9 @@ "abstract": true, "description": "iOS Mono Runtime Packs", "packs": [ - "Microsoft.NETCore.App.Runtime.Mono.ios-arm64", - "Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64", - "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x64" + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.ios-arm64", + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.iossimulator-arm64", + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.iossimulator-x64" ], "extends": [ "microsoft-net-runtime-mono-tooling" ], "platforms": [ "win-x64", "win-arm64", "osx-arm64", "osx-x64" ] @@ -91,8 +91,8 @@ "abstract": true, "description": "MacCatalyst Mono Runtime and AOT Workload", "packs": [ - "Microsoft.NETCore.App.Runtime.AOT.Cross.maccatalyst-arm64", - "Microsoft.NETCore.App.Runtime.AOT.Cross.maccatalyst-x64" + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.maccatalyst-arm64", + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.maccatalyst-x64" ], "extends": [ "runtimes-maccatalyst" ], "platforms": [ "win-x64", "win-arm64", "osx-arm64", "osx-x64" ] @@ -101,8 +101,8 @@ "abstract": true, "description": "MacCatalyst Mono Runtime Packs", "packs": [ - "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-arm64", - "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-x64" + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.maccatalyst-arm64", + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.maccatalyst-x64" ], "extends": [ "microsoft-net-runtime-mono-tooling" ], "platforms": [ "win-x64", "win-arm64", "osx-arm64", "osx-x64" ] @@ -111,8 +111,8 @@ "abstract": true, "description": "MacOS CoreCLR and Mono Runtime Workload", "packs": [ - "Microsoft.NETCore.App.Runtime.Mono.osx-arm64", - "Microsoft.NETCore.App.Runtime.Mono.osx-x64", + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.osx-arm64", + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.osx-x64", "Microsoft.NETCore.App.Runtime.osx-arm64", "Microsoft.NETCore.App.Runtime.osx-x64" ], @@ -123,9 +123,9 @@ "abstract": true, "description": "tvOS Mono Runtime and AOT Workload", "packs": [ - "Microsoft.NETCore.App.Runtime.AOT.Cross.tvos-arm64", - "Microsoft.NETCore.App.Runtime.AOT.Cross.tvossimulator-arm64", - "Microsoft.NETCore.App.Runtime.AOT.Cross.tvossimulator-x64" + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.tvos-arm64", + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.tvossimulator-arm64", + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.tvossimulator-x64" ], "extends": [ "runtimes-tvos" ], "platforms": [ "win-x64", "win-arm64", "osx-arm64", "osx-x64" ] @@ -134,9 +134,9 @@ "abstract": true, "description": "tvOS Mono Runtime Packs", "packs": [ - "Microsoft.NETCore.App.Runtime.Mono.tvos-arm64", - "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-arm64", - "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-x64" + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.tvos-arm64", + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.tvossimulator-arm64", + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.tvossimulator-x64" ], "extends": [ "microsoft-net-runtime-mono-tooling" ], "platforms": [ "win-x64", "win-arm64", "osx-arm64", "osx-x64" ] @@ -154,53 +154,83 @@ "abstract": true, "description": "Shared native build tooling for Mono runtime", "packs": [ - "Microsoft.NET.Runtime.MonoAOTCompiler.Task", - "Microsoft.NET.Runtime.MonoTargets.Sdk" + "Microsoft.NET.Runtime.MonoAOTCompiler.Task.${NetVersion}", + "Microsoft.NET.Runtime.MonoTargets.Sdk.${NetVersion}" ] } }, "packs": { - "Microsoft.NET.Runtime.MonoAOTCompiler.Task": { + "Microsoft.NET.Runtime.MonoAOTCompiler.Task.${NetVersion}": { "kind": "Sdk", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NET.Runtime.MonoAOTCompiler.Task" + } }, - "Microsoft.NET.Runtime.MonoTargets.Sdk": { + "Microsoft.NET.Runtime.MonoTargets.Sdk.${NetVersion}": { "kind": "Sdk", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NET.Runtime.MonoTargets.Sdk" + } }, - "Microsoft.NET.Runtime.LibraryBuilder.Sdk": { + "Microsoft.NET.Runtime.LibraryBuilder.Sdk.${NetVersion}": { "kind": "Sdk", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NET.Runtime.LibraryBuilder.Sdk" + } }, - "Microsoft.NET.Runtime.WebAssembly.Sdk": { + "Microsoft.NET.Runtime.WebAssembly.Sdk.${NetVersion}": { "kind": "Sdk", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NET.Runtime.WebAssembly.Sdk" + } }, - "Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk": { + "Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk.${NetVersion}": { "kind": "Sdk", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk" + } }, - "Microsoft.NET.Runtime.WebAssembly.Templates": { + "Microsoft.NET.Runtime.WebAssembly.Templates.${NetVersion}": { "kind": "template", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NET.Runtime.WebAssembly.Templates" + } }, - "Microsoft.NETCore.App.Runtime.Mono.android-arm": { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.android-arm": { "kind": "framework", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.android-arm" + } }, - "Microsoft.NETCore.App.Runtime.Mono.android-arm64": { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.android-arm64": { "kind": "framework", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.android-arm64" + } }, - "Microsoft.NETCore.App.Runtime.Mono.android-x64": { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.android-x64": { "kind": "framework", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.android-x64" + } }, - "Microsoft.NETCore.App.Runtime.Mono.android-x86": { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.android-x86": { "kind": "framework", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.android-x86" + } }, - "Microsoft.NETCore.App.Runtime.AOT.Cross.android-x86": { + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.android-x86": { "kind": "Sdk", "version": "${PackageVersion}", "alias-to": { @@ -212,7 +242,7 @@ "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-arm64.Cross.android-x86" } }, - "Microsoft.NETCore.App.Runtime.AOT.Cross.android-x64": { + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.android-x64": { "kind": "Sdk", "version": "${PackageVersion}", "alias-to": { @@ -224,7 +254,7 @@ "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-arm64.Cross.android-x64" } }, - "Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm": { + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.android-arm": { "kind": "Sdk", "version": "${PackageVersion}", "alias-to": { @@ -236,7 +266,7 @@ "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-arm64.Cross.android-arm" } }, - "Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm64": { + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.android-arm64": { "kind": "Sdk", "version": "${PackageVersion}", "alias-to": { @@ -248,43 +278,64 @@ "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-arm64.Cross.android-arm64" } }, - "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-arm64": { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.maccatalyst-arm64": { "kind": "framework", "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-arm64" + } }, - "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-x64": { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.maccatalyst-x64": { "kind": "framework", "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-x64" + } }, - "Microsoft.NETCore.App.Runtime.Mono.osx-arm64": { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.osx-arm64": { "kind": "framework", "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.osx-arm64" + } }, - "Microsoft.NETCore.App.Runtime.Mono.osx-x64": { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.osx-x64": { "kind": "framework", "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.osx-x64" + } }, "Microsoft.NETCore.App.Runtime.osx-arm64": { "kind": "framework", - "version": "${PackageVersion}", + "version": "${PackageVersion}" }, "Microsoft.NETCore.App.Runtime.osx-x64": { "kind": "framework", - "version": "${PackageVersion}", + "version": "${PackageVersion}" }, - "Microsoft.NETCore.App.Runtime.Mono.ios-arm64" : { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.ios-arm64" : { "kind": "framework", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.ios-arm64" + } }, - "Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64" : { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.iossimulator-arm64" : { "kind": "framework", "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64" + } }, - "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x64" : { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.iossimulator-x64" : { "kind": "framework", "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x64" + } }, - "Microsoft.NETCore.App.Runtime.AOT.Cross.tvos-arm64": { + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.tvos-arm64": { "kind": "Sdk", "version": "${PackageVersion}", "alias-to": { @@ -292,19 +343,28 @@ "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-arm64.Cross.tvos-arm64", } }, - "Microsoft.NETCore.App.Runtime.Mono.tvos-arm64" : { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.tvos-arm64" : { "kind": "framework", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.tvos-arm64" + } }, - "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-arm64" : { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.tvossimulator-arm64" : { "kind": "framework", "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-arm64" + } }, - "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-x64" : { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.tvossimulator-x64" : { "kind": "framework", "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-x64" + } }, - "Microsoft.NETCore.App.Runtime.AOT.Cross.maccatalyst-arm64": { + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.maccatalyst-arm64": { "kind": "Sdk", "version": "${PackageVersion}", "alias-to": { @@ -312,7 +372,7 @@ "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.maccatalyst-arm64" } }, - "Microsoft.NETCore.App.Runtime.AOT.Cross.maccatalyst-x64": { + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.maccatalyst-x64": { "kind": "Sdk", "version": "${PackageVersion}", "alias-to": { @@ -320,7 +380,7 @@ "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.maccatalyst-x64" } }, - "Microsoft.NETCore.App.Runtime.AOT.Cross.tvossimulator-arm64": { + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.tvossimulator-arm64": { "kind": "Sdk", "version": "${PackageVersion}", "alias-to": { @@ -328,7 +388,7 @@ "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvossimulator-arm64" } }, - "Microsoft.NETCore.App.Runtime.AOT.Cross.tvossimulator-x64": { + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.tvossimulator-x64": { "kind": "Sdk", "version": "${PackageVersion}", "alias-to": { @@ -344,7 +404,7 @@ "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-arm64.Cross.ios-arm64", } }, - "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-arm64": { + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.iossimulator-arm64": { "kind": "Sdk", "version": "${PackageVersion}", "alias-to": { @@ -352,7 +412,7 @@ "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-arm64" } }, - "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-x64": { + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.iossimulator-x64": { "kind": "Sdk", "version": "${PackageVersion}", "alias-to": { @@ -360,7 +420,7 @@ "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-x64" } }, - "Microsoft.NETCore.App.Runtime.AOT.Cross.browser-wasm": { + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.browser-wasm": { "kind": "Sdk", "version": "${PackageVersion}", "alias-to": { @@ -372,17 +432,26 @@ "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-arm64.Cross.browser-wasm" } }, - "Microsoft.NETCore.App.Runtime.Mono.browser-wasm" : { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.browser-wasm" : { "kind": "framework", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.browser-wasm" + } }, - "Microsoft.NETCore.App.Runtime.Mono.multithread.browser-wasm" : { + "Microsoft.NETCore.App.Runtime.Mono.multithread.${NetVersion}.browser-wasm" : { "kind": "framework", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.multithread.browser-wasm" + } }, - "Microsoft.NETCore.App.Runtime.Mono.wasi-wasm" : { + "Microsoft.NETCore.App.Runtime.Mono.${NetVersion}.wasi-wasm" : { "kind": "framework", - "version": "${PackageVersion}" + "version": "${PackageVersion}", + "alias-to": { + "any": "Microsoft.NETCore.App.Runtime.Mono.wasi-wasm" + } }, "Microsoft.NETCore.App.Runtime.win-x64" : { "kind": "framework", diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in index 70658c5c21a1f7..313514d0b6574e 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in @@ -82,70 +82,70 @@ - + - - + + - - + + - - - - + + + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + - - - - - + + + + + - - - - + + + + From 025271a4427c6e38e104f86b4b690db28391cbad Mon Sep 17 00:00:00 2001 From: Juan Sebastian Hoyos Ayala Date: Mon, 10 Jun 2024 19:48:30 +0000 Subject: [PATCH 769/783] Use GetTempPath2 on Windows if available ## Description Since Windows 10 Build 20348, there is a new API to get the temporary files path called [`GetTempPath2`](https://learn.microsoft.com/windows/win32/api/fileapi/nf-fileapi-gettemppath2w). This API returns a directory inaccessible to non-SYSTEM processes if the calling process runs as SYSTEM, and [it is recommended to call this function instead of `GetTempPath`](https://learn.microsoft.com/windows/win32/api/fileapi/nf-fileapi-gettemppathw#remarks). This PR tries to find `GetTempPath2A` / `GetTempPath2W` and uses that, otherwise it falls back to `GetTempPathA` / `GetTempPathW`. *Note:* this PR removes an unused function called `WszGetTempPath` that which referenced GetTempPathW ## Customer Impact - [ ] Customer reported - [X] Found internally This was found by code inspection. ## Regression - [ ] Yes - [X] No ## Testing PR validation ## Risk Low --- src/coreclr/debug/createdump/createdump.h | 3 ++ .../debug/createdump/createdumpmain.cpp | 2 +- .../debug/createdump/createdumpwindows.cpp | 35 ++++++++++++++++ src/coreclr/inc/longfilepathwrappers.h | 4 -- src/coreclr/inc/winwrap.h | 3 -- src/coreclr/utilcode/longfilepathwrappers.cpp | 41 ------------------- src/native/corehost/hostmisc/pal.windows.cpp | 34 ++++++++++++++- 7 files changed, 72 insertions(+), 50 deletions(-) diff --git a/src/coreclr/debug/createdump/createdump.h b/src/coreclr/debug/createdump/createdump.h index 50cf53dccfc7aa..baaa128c54f027 100644 --- a/src/coreclr/debug/createdump/createdump.h +++ b/src/coreclr/debug/createdump/createdump.h @@ -151,6 +151,9 @@ extern MINIDUMP_TYPE GetMiniDumpType(DumpType dumpType); #ifdef HOST_WINDOWS extern std::string GetLastErrorString(); +extern DWORD GetTempPathWrapper(IN DWORD nBufferLength, OUT LPSTR lpBuffer); +#else +#define GetTempPathWrapper GetTempPathA #endif extern void printf_status(const char* format, ...); extern void printf_error(const char* format, ...); diff --git a/src/coreclr/debug/createdump/createdumpmain.cpp b/src/coreclr/debug/createdump/createdumpmain.cpp index e39538c4cb1c38..f2663169727fde 100644 --- a/src/coreclr/debug/createdump/createdumpmain.cpp +++ b/src/coreclr/debug/createdump/createdumpmain.cpp @@ -205,7 +205,7 @@ int createdump_main(const int argc, const char* argv[]) ArrayHolder tmpPath = new char[MAX_LONGPATH]; if (options.DumpPathTemplate == nullptr) { - if (::GetTempPathA(MAX_LONGPATH, tmpPath) == 0) + if (GetTempPathWrapper(MAX_LONGPATH, tmpPath) == 0) { printf_error("GetTempPath failed\n"); return -1; diff --git a/src/coreclr/debug/createdump/createdumpwindows.cpp b/src/coreclr/debug/createdump/createdumpwindows.cpp index d1b843f1a2fd2b..43e6f2c12bd521 100644 --- a/src/coreclr/debug/createdump/createdumpwindows.cpp +++ b/src/coreclr/debug/createdump/createdumpwindows.cpp @@ -135,3 +135,38 @@ GetLastErrorString() return result; } + +typedef DWORD(WINAPI *pfnGetTempPathA)(DWORD nBufferLength, LPSTR lpBuffer); + +static volatile pfnGetTempPathA +g_pfnGetTempPathA = nullptr; + + +DWORD +GetTempPathWrapper( + IN DWORD nBufferLength, + OUT LPSTR lpBuffer) +{ + if (g_pfnGetTempPathA == nullptr) + { + HMODULE hKernel32 = LoadLibraryExW(L"kernel32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); + + pfnGetTempPathA pLocalGetTempPathA = NULL; + if (hKernel32 != NULL) + { + // store to thread local variable to prevent data race + pLocalGetTempPathA = (pfnGetTempPathA)::GetProcAddress(hKernel32, "GetTempPath2A"); + } + + if (pLocalGetTempPathA == NULL) // method is only available with Windows 10 Creators Update or later + { + g_pfnGetTempPathA = &GetTempPathA; + } + else + { + g_pfnGetTempPathA = pLocalGetTempPathA; + } + } + + return g_pfnGetTempPathA(nBufferLength, lpBuffer); +} \ No newline at end of file diff --git a/src/coreclr/inc/longfilepathwrappers.h b/src/coreclr/inc/longfilepathwrappers.h index ee394aa0b77586..6407680900dc14 100644 --- a/src/coreclr/inc/longfilepathwrappers.h +++ b/src/coreclr/inc/longfilepathwrappers.h @@ -59,10 +59,6 @@ SearchPathWrapper( _Out_opt_ LPWSTR * lpFilePart ); -DWORD WINAPI GetTempPathWrapper( - SString& lpBuffer - ); - DWORD GetModuleFileNameWrapper( _In_opt_ HMODULE hModule, diff --git a/src/coreclr/inc/winwrap.h b/src/coreclr/inc/winwrap.h index 652c0b80653310..98570ed3eac1d9 100644 --- a/src/coreclr/inc/winwrap.h +++ b/src/coreclr/inc/winwrap.h @@ -204,9 +204,6 @@ //Can not use extended syntax #define WszGetFullPathName GetFullPathNameW -//Long Files will not work on these till redstone -#define WszGetTempPath GetTempPathWrapper - //APIS which have a buffer as an out parameter #define WszGetEnvironmentVariable GetEnvironmentVariableWrapper #define WszSearchPath SearchPathWrapper diff --git a/src/coreclr/utilcode/longfilepathwrappers.cpp b/src/coreclr/utilcode/longfilepathwrappers.cpp index 120b3c04c9322d..079fce749ae638 100644 --- a/src/coreclr/utilcode/longfilepathwrappers.cpp +++ b/src/coreclr/utilcode/longfilepathwrappers.cpp @@ -184,47 +184,6 @@ GetModuleFileNameWrapper( return ret; } -DWORD WINAPI GetTempPathWrapper( - SString& lpBuffer - ) -{ - CONTRACTL - { - NOTHROW; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - DWORD ret = 0; - DWORD lastError = 0; - - EX_TRY - { - //Change the behaviour in Redstone to retry - COUNT_T size = MAX_LONGPATH; - - ret = GetTempPathW( - size, - lpBuffer.OpenUnicodeBuffer(size - 1) - ); - - lastError = GetLastError(); - lpBuffer.CloseBuffer(ret); - } - EX_CATCH_HRESULT(hr); - - if (hr != S_OK) - { - SetLastError(hr); - } - else if (ret == 0) - { - SetLastError(lastError); - } - - return ret; -} - DWORD WINAPI GetEnvironmentVariableWrapper( _In_opt_ LPCTSTR lpName, _Out_opt_ SString& lpBuffer diff --git a/src/native/corehost/hostmisc/pal.windows.cpp b/src/native/corehost/hostmisc/pal.windows.cpp index b11610492d3214..ca0608cd56935e 100644 --- a/src/native/corehost/hostmisc/pal.windows.cpp +++ b/src/native/corehost/hostmisc/pal.windows.cpp @@ -10,6 +10,38 @@ #include #include +namespace +{ + typedef DWORD(WINAPI *get_temp_path_func_ptr)(DWORD buffer_len, LPWSTR buffer); + static volatile get_temp_path_func_ptr s_get_temp_path_func = nullptr; + + DWORD get_temp_path(DWORD buffer_len, LPWSTR buffer) + { + if (s_get_temp_path_func == nullptr) + { + HMODULE kernel32 = ::LoadLibraryExW(L"kernel32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); + + get_temp_path_func_ptr get_temp_path_func_local = NULL; + if (kernel32 != NULL) + { + // store to thread local variable to prevent data race + get_temp_path_func_local = (get_temp_path_func_ptr)::GetProcAddress(kernel32, "GetTempPath2W"); + } + + if (get_temp_path_func_local == NULL) // method is only available with Windows 10 Creators Update or later + { + s_get_temp_path_func = &GetTempPathW; + } + else + { + s_get_temp_path_func = get_temp_path_func_local; + } + } + + return s_get_temp_path_func(buffer_len, buffer); + } +} + bool GetModuleFileNameWrapper(HMODULE hModule, pal::string_t* recv) { pal::string_t path; @@ -639,7 +671,7 @@ bool get_extraction_base_parent_directory(pal::string_t& directory) const size_t max_len = MAX_PATH + 1; pal::char_t temp_path[max_len]; - size_t len = GetTempPathW(max_len, temp_path); + size_t len = get_temp_path(max_len, temp_path); if (len == 0) { return false; From 26e8cc8665a38f932281439f1f2b425af8d08bca Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Mon, 10 Jun 2024 13:03:15 -0700 Subject: [PATCH 770/783] Remove cached cgroup values (#102971) (#103166) --- src/coreclr/gc/env/gcenv.os.h | 2 +- src/coreclr/gc/gc.cpp | 2 +- src/coreclr/gc/unix/gcenv.unix.cpp | 5 ++--- src/coreclr/gc/windows/gcenv.windows.cpp | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/coreclr/gc/env/gcenv.os.h b/src/coreclr/gc/env/gcenv.os.h index c38892b0cadc20..753b751f798c63 100644 --- a/src/coreclr/gc/env/gcenv.os.h +++ b/src/coreclr/gc/env/gcenv.os.h @@ -417,7 +417,7 @@ class GCToOSInterface // Remarks: // If a process runs with a restricted memory limit, it returns the limit. If there's no limit // specified, it returns amount of actual physical memory. - static uint64_t GetPhysicalMemoryLimit(bool* is_restricted=NULL); + static uint64_t GetPhysicalMemoryLimit(bool* is_restricted=NULL, bool refresh=false); // Get memory status // Parameters: diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 86022c70550a50..1cf604da8a87bc 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -52808,7 +52808,7 @@ int gc_heap::refresh_memory_limit() size_t old_heap_hard_limit_poh = heap_hard_limit_oh[poh]; bool old_hard_limit_config_p = hard_limit_config_p; - total_physical_mem = GCToOSInterface::GetPhysicalMemoryLimit (&is_restricted_physical_mem); + total_physical_mem = GCToOSInterface::GetPhysicalMemoryLimit (&is_restricted_physical_mem, true); bool succeed = true; diff --git a/src/coreclr/gc/unix/gcenv.unix.cpp b/src/coreclr/gc/unix/gcenv.unix.cpp index dd591a54426351..0dc9790e0662fd 100644 --- a/src/coreclr/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/gc/unix/gcenv.unix.cpp @@ -1121,14 +1121,13 @@ size_t GCToOSInterface::GetVirtualMemoryLimit() // Remarks: // If a process runs with a restricted memory limit, it returns the limit. If there's no limit // specified, it returns amount of actual physical memory. -uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted) +uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted, bool refresh) { size_t restricted_limit; if (is_restricted) *is_restricted = false; - // The limit was not cached - if (g_RestrictedPhysicalMemoryLimit == 0) + if (g_RestrictedPhysicalMemoryLimit == 0 || refresh) { restricted_limit = GetRestrictedPhysicalMemoryLimit(); VolatileStore(&g_RestrictedPhysicalMemoryLimit, restricted_limit); diff --git a/src/coreclr/gc/windows/gcenv.windows.cpp b/src/coreclr/gc/windows/gcenv.windows.cpp index f12a64d7ed1ab3..0d2af7904c89c9 100644 --- a/src/coreclr/gc/windows/gcenv.windows.cpp +++ b/src/coreclr/gc/windows/gcenv.windows.cpp @@ -960,7 +960,7 @@ size_t GCToOSInterface::GetVirtualMemoryLimit() // Remarks: // If a process runs with a restricted memory limit, it returns the limit. If there's no limit // specified, it returns amount of actual physical memory. -uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted) +uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted, bool refresh) { if (is_restricted) *is_restricted = false; From a04bc0c17edc1089544a9b9a6a10cdf696a906fa Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Mon, 10 Jun 2024 23:14:14 +0300 Subject: [PATCH 771/783] [mono][interp] Fix type of args when inlining method (#102801) The vars allocated from pushing values on the execution stack might not reflect exactly the actual type of the var. Consider this pattern: condbr BB0 newobj Derived // push var0 of type Derived br BB1 BB0: newobj Base // push var1 of type Base // here we will end up inserting a `mov var1 -> var0` BB1: // top of stack will be seen as being var0 call Because we first reach BB1 with the stack contents of var0, BB1 will end up accessing top of the stack as var0. However the type of var0 at this point is not Derived, since it can also be a Base object. We currently don't update the type of var0, but just update the type information of the top of stack entry when entering BB1. When inlining, after this commit, we use the type information from the stack, rather than the type of the var present on the stack. --- src/mono/mono/mini/interp/transform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 0150c3d32e3e03..bdb2b3f45eaf08 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -4998,7 +4998,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, arg_locals = (guint32*) g_malloc ((!!signature->hasthis + signature->param_count) * sizeof (guint32)); /* Allocate locals to store inlined method args from stack */ for (int i = signature->param_count - 1; i >= 0; i--) { - MonoType *type = td->locals [td->sp [-1].local].type; + MonoType *type = get_type_from_stack (td->sp [-1].type, td->sp [-1].klass); local = create_interp_local (td, type); arg_locals [i + !!signature->hasthis] = local; store_local (td, local); From 4d4640ffaac85cf1546940355be4a8459f32511f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:32:06 -0700 Subject: [PATCH 772/783] Update dependencies from https://github.com/dotnet/hotreload-utils build 20240521.1 (#102496) Microsoft.DotNet.HotReload.Utils.Generator.BuildTool From Version 8.0.0-alpha.0.24229.2 -> To Version 8.0.0-alpha.0.24271.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d2b215265a4c93..f7b7268e34b8ef 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -354,9 +354,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 67613417f5e1af250e6ddfba79f8f2885d8e90fb - + https://github.com/dotnet/hotreload-utils - 61f137aacabdbd8f279415287a2dd70e150f5eb1 + c804541158619aae93105f54698ca7f149d28232 https://github.com/dotnet/runtime-assets diff --git a/eng/Versions.props b/eng/Versions.props index abc824d58b29d6..fc841bcad594db 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -186,7 +186,7 @@ 8.0.0-prerelease.24229.2 8.0.0-prerelease.24229.2 8.0.0-prerelease.24229.2 - 8.0.0-alpha.0.24229.2 + 8.0.0-alpha.0.24271.1 2.4.2 1.0.0 2.4.5 From 25139d0e36c3fb288a78aaf45e93bf1b6ba46d3b Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Lopez Date: Mon, 10 Jun 2024 21:53:36 +0000 Subject: [PATCH 773/783] newlines in domain literals newlines in domain literals This adds validation for embedded newlines in email addresses. There is opt-in System.Net.Mail.EnableFullDomainLiterals switch to allow previous behavior --- .../DataAnnotations/EmailAddressAttribute.cs | 8 +++ .../EmailAddressAttributeTests.cs | 1 + .../src/System/Net/Mail/MailAddress.cs | 9 +++ .../tests/Functional/SmtpClientTest.cs | 59 +++++++++++++++++++ 4 files changed, 77 insertions(+) diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs index 2e28b0cb6ac3df..de5a86a64ac8c0 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs @@ -7,6 +7,9 @@ namespace System.ComponentModel.DataAnnotations AllowMultiple = false)] public sealed class EmailAddressAttribute : DataTypeAttribute { + private static bool EnableFullDomainLiterals { get; } = + AppContext.TryGetSwitch("System.Net.AllowFullDomainLiterals", out bool enable) ? enable : false; + public EmailAddressAttribute() : base(DataType.EmailAddress) { @@ -27,6 +30,11 @@ public override bool IsValid(object? value) return false; } + if (!EnableFullDomainLiterals && (valueAsString.Contains('\r') || valueAsString.Contains('\n'))) + { + return false; + } + // only return true if there is only 1 '@' character // and it is neither the first nor the last character int index = valueAsString.IndexOf('@'); diff --git a/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/EmailAddressAttributeTests.cs b/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/EmailAddressAttributeTests.cs index a0c67ed7d2b92b..da80016608e402 100644 --- a/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/EmailAddressAttributeTests.cs +++ b/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/EmailAddressAttributeTests.cs @@ -29,6 +29,7 @@ protected override IEnumerable InvalidValues() yield return new TestCase(new EmailAddressAttribute(), 0); yield return new TestCase(new EmailAddressAttribute(), ""); yield return new TestCase(new EmailAddressAttribute(), " \r \t \n" ); + yield return new TestCase(new EmailAddressAttribute(), "someName@[\r\n\tsomeDomain]"); yield return new TestCase(new EmailAddressAttribute(), "@someDomain.com"); yield return new TestCase(new EmailAddressAttribute(), "@someDomain@abc.com"); yield return new TestCase(new EmailAddressAttribute(), "someName"); diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddress.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddress.cs index 47ac65dbf9b5d4..644f7502ff7763 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddress.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddress.cs @@ -15,6 +15,9 @@ namespace System.Net.Mail // public partial class MailAddress { + private static bool EnableFullDomainLiterals { get; } = + AppContext.TryGetSwitch("System.Net.AllowFullDomainLiterals", out bool enable) ? enable : false; + // These components form an e-mail address when assembled as follows: // "EncodedDisplayname" private readonly Encoding _displayNameEncoding; @@ -216,6 +219,12 @@ private string GetHost(bool allowUnicode) throw new SmtpException(SR.Format(SR.SmtpInvalidHostName, Address), argEx); } } + + if (!EnableFullDomainLiterals && domain.AsSpan().IndexOfAny('\r', '\n') >= 0) + { + throw new SmtpException(SR.Format(SR.SmtpInvalidHostName, Address)); + } + return domain; } diff --git a/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs b/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs index 306368df202183..a9cf0bca251ce8 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs @@ -9,11 +9,15 @@ // (C) 2006 John Luke // +using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Net.NetworkInformation; using System.Net.Sockets; +using System.Reflection; using System.Threading; using System.Threading.Tasks; +using Microsoft.DotNet.RemoteExecutor; using Systen.Net.Mail.Tests; using System.Net.Test.Common; using Xunit; @@ -573,5 +577,60 @@ public void TestGssapiAuthentication() Assert.Equal("GSSAPI", server.AuthMethodUsed, StringComparer.OrdinalIgnoreCase); } + + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [InlineData("foo@[\r\n bar]")] + [InlineData("foo@[bar\r\n ]")] + [InlineData("foo@[bar\r\n baz]")] + public void MultiLineDomainLiterals_Enabled_Success(string input) + { + RemoteExecutor.Invoke(static (string @input) => + { + AppContext.SetSwitch("System.Net.AllowFullDomainLiterals", true); + + var address = new MailAddress(@input); + + // Using address with new line breaks the protocol so we cannot easily use LoopbackSmtpServer + // Instead we call internal method that does the extra validation. + string? host = (string?)typeof(MailAddress).InvokeMember("GetAddress", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, address, new object[] { true }); + Assert.Equal(input, host); + }, input).Dispose(); + } + + [Theory] + [MemberData(nameof(SendMail_MultiLineDomainLiterals_Data))] + public async Task SendMail_MultiLineDomainLiterals_Disabled_Throws(string from, string to, bool asyncSend) + { + using var server = new LoopbackSmtpServer(); + + using SmtpClient client = server.CreateClient(); + client.Credentials = new NetworkCredential("Foo", "Bar"); + + using var msg = new MailMessage(@from, @to, "subject", "body"); + + await Assert.ThrowsAsync(async () => + { + if (asyncSend) + { + await client.SendMailAsync(msg).WaitAsync(TimeSpan.FromSeconds(30)); + } + else + { + client.Send(msg); + } + }); + } + + public static IEnumerable SendMail_MultiLineDomainLiterals_Data() + { + foreach (bool async in new[] { true, false }) + { + foreach (string address in new[] { "foo@[\r\n bar]", "foo@[bar\r\n ]", "foo@[bar\r\n baz]" }) + { + yield return new object[] { address, "foo@example.com", async }; + yield return new object[] { "foo@example.com", address, async }; + } + } + } } } From 106b02ffe95afaf6e213faf6c15678158274633c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:14:50 -0700 Subject: [PATCH 774/783] Set version in ZIP local header to ZIP64 when file offset is >4GB (#102053) (#103006) * ZipArchiveEntry didn't set ZIP64 in local headers for small files if their offset are > 4GB. * Added System.IO.Compression and System.IO.Packaging tests. --------- Co-authored-by: Gan Keyu --- .../System/IO/Compression/ZipArchiveEntry.cs | 22 +-- .../tests/ZipArchive/zip_LargeFiles.cs | 129 ++++++++++++++---- .../tests/LargeFilesTests.Net.cs | 97 +++++++++++++ .../tests/LargeFilesTests.cs | 78 +++++++++++ .../tests/System.IO.Packaging.Tests.csproj | 4 + .../System.IO.Packaging/tests/Tests.cs | 68 --------- .../tests/XunitAssemblyAttributes.cs | 9 ++ 7 files changed, 306 insertions(+), 101 deletions(-) create mode 100644 src/libraries/System.IO.Packaging/tests/LargeFilesTests.Net.cs create mode 100644 src/libraries/System.IO.Packaging/tests/LargeFilesTests.cs create mode 100644 src/libraries/System.IO.Packaging/tests/XunitAssemblyAttributes.cs diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs index 3d415f8e3690f1..7a5ff6136cae94 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs @@ -469,7 +469,7 @@ internal void WriteCentralDirectoryFileHeader() bool zip64Needed = false; - if (SizesTooLarge() + if (AreSizesTooLarge #if DEBUG_FORCE_ZIP64 || _archive._forceZip64 #endif @@ -490,7 +490,7 @@ internal void WriteCentralDirectoryFileHeader() } - if (_offsetOfLocalHeader > uint.MaxValue + if (IsOffsetTooLarge #if DEBUG_FORCE_ZIP64 || _archive._forceZip64 #endif @@ -797,7 +797,11 @@ private bool IsOpenable(bool needToUncompress, bool needToLoadIntoMemory, out st return true; } - private bool SizesTooLarge() => _compressedSize > uint.MaxValue || _uncompressedSize > uint.MaxValue; + private bool AreSizesTooLarge => _compressedSize > uint.MaxValue || _uncompressedSize > uint.MaxValue; + + private bool IsOffsetTooLarge => _offsetOfLocalHeader > uint.MaxValue; + + private bool ShouldUseZIP64 => AreSizesTooLarge || IsOffsetTooLarge; // return value is true if we allocated an extra field for 64 bit headers, un/compressed size private bool WriteLocalFileHeader(bool isEmptyFile) @@ -813,6 +817,9 @@ private bool WriteLocalFileHeader(bool isEmptyFile) bool zip64Used = false; uint compressedSizeTruncated, uncompressedSizeTruncated; + // save offset + _offsetOfLocalHeader = writer.BaseStream.Position; + // if we already know that we have an empty file don't worry about anything, just do a straight shot of the header if (isEmptyFile) { @@ -840,7 +847,7 @@ private bool WriteLocalFileHeader(bool isEmptyFile) { // We are in seekable mode so we will not need to write a data descriptor _generalPurposeBitFlag &= ~BitFlagValues.DataDescriptor; - if (SizesTooLarge() + if (ShouldUseZIP64 #if DEBUG_FORCE_ZIP64 || (_archive._forceZip64 && _archive.Mode == ZipArchiveMode.Update) #endif @@ -865,9 +872,6 @@ private bool WriteLocalFileHeader(bool isEmptyFile) } } - // save offset - _offsetOfLocalHeader = writer.BaseStream.Position; - // calculate extra field. if zip64 stuff + original extraField aren't going to fit, dump the original extraField, because this is more important int bigExtraFieldLength = (zip64Used ? zip64ExtraField.TotalSize : 0) + (_lhUnknownExtraFields != null ? ZipGenericExtraField.TotalSize(_lhUnknownExtraFields) : 0); @@ -964,7 +968,7 @@ private void WriteCrcAndSizesInLocalHeader(bool zip64HeaderUsed) long finalPosition = _archive.ArchiveStream.Position; BinaryWriter writer = new BinaryWriter(_archive.ArchiveStream); - bool zip64Needed = SizesTooLarge() + bool zip64Needed = ShouldUseZIP64 #if DEBUG_FORCE_ZIP64 || _archive._forceZip64 #endif @@ -1048,7 +1052,7 @@ private void WriteDataDescriptor() writer.Write(ZipLocalFileHeader.DataDescriptorSignature); writer.Write(_crc32); - if (SizesTooLarge()) + if (AreSizesTooLarge) { writer.Write(_compressedSize); writer.Write(_uncompressedSize); diff --git a/src/libraries/System.IO.Compression/tests/ZipArchive/zip_LargeFiles.cs b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_LargeFiles.cs index d240a176b2b7a2..b4623e653af84d 100644 --- a/src/libraries/System.IO.Compression/tests/ZipArchive/zip_LargeFiles.cs +++ b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_LargeFiles.cs @@ -1,48 +1,129 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Collections.Generic; -using System.Linq; +using System.Reflection; using Xunit; -namespace System.IO.Compression.Tests +namespace System.IO.Compression.Tests; + +[Collection(nameof(DisableParallelization))] +public class zip_LargeFiles : ZipFileTestBase { - [Collection(nameof(DisableParallelization))] - public class zip_LargeFiles : ZipFileTestBase + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsSpeedOptimized), nameof(PlatformDetection.Is64BitProcess))] // don't run it on slower runtimes + [OuterLoop("It requires almost 12 GB of free disk space")] + public static void UnzipOver4GBZipFile() { - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsSpeedOptimized), nameof(PlatformDetection.Is64BitProcess))] // don't run it on slower runtimes - [OuterLoop("It requires almost 12 GB of free disk space")] - public static void UnzipOver4GBZipFile() + byte[] buffer = GC.AllocateUninitializedArray(1_000_000_000); // 1 GB + + string zipArchivePath = Path.Combine(Path.GetTempPath(), "over4GB.zip"); + DirectoryInfo tempDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "over4GB")); + + try + { + for (byte i = 0; i < 6; i++) + { + File.WriteAllBytes(Path.Combine(tempDir.FullName, $"{i}.test"), buffer); + } + + ZipFile.CreateFromDirectory(tempDir.FullName, zipArchivePath, CompressionLevel.NoCompression, includeBaseDirectory: false); + + using ZipArchive zipArchive = ZipFile.OpenRead(zipArchivePath); + foreach (ZipArchiveEntry entry in zipArchive.Entries) + { + using Stream entryStream = entry.Open(); + + Assert.True(entryStream.CanRead); + Assert.Equal(buffer.Length, entryStream.Length); + } + } + finally { - byte[] buffer = GC.AllocateUninitializedArray(1_000_000_000); // 1 GB + File.Delete(zipArchivePath); + + tempDir.Delete(recursive: true); + } + } + + private static void FillWithHardToCompressData(byte[] buffer) + { + Random.Shared.NextBytes(buffer); + } - string zipArchivePath = Path.Combine(Path.GetTempPath(), "over4GB.zip"); - DirectoryInfo tempDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "over4GB")); + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsSpeedOptimized), nameof(PlatformDetection.Is64BitProcess))] // don't run it on slower runtimes + [OuterLoop("It requires 5~6 GB of free disk space and a lot of CPU time for compressed tests")] + [InlineData(false)] + [InlineData(true)] + public static void CheckZIP64VersionIsSet_ForSmallFilesAfterBigFiles(bool isCompressed) + { + // issue #94899 + + CompressionLevel compressLevel = isCompressed ? CompressionLevel.Optimal : CompressionLevel.NoCompression; + byte[] smallBuffer = GC.AllocateUninitializedArray(1000); + byte[] largeBuffer = GC.AllocateUninitializedArray(1_000_000_000); // ~1 GB + string zipArchivePath = Path.Combine(Path.GetTempPath(), "over4GB.zip"); + string LargeFileName = "largefile"; + string SmallFileName = "smallfile"; + uint ZipLocalFileHeader_OffsetToVersionFromHeaderStart = 4; + ushort Zip64Version = 45; - try + try + { + using FileStream fs = File.Open(zipArchivePath, FileMode.Create, FileAccess.ReadWrite); + + // Create + using (ZipArchive archive = new(fs, ZipArchiveMode.Create, true)) { - for (byte i = 0; i < 6; i++) + ZipArchiveEntry file = archive.CreateEntry(LargeFileName, compressLevel); + + using (Stream stream = file.Open()) { - File.WriteAllBytes(Path.Combine(tempDir.FullName, $"{i}.test"), buffer); + // Write 5GB of data + for (var i = 0; i < 5; i++) + { + if (isCompressed) + { + FillWithHardToCompressData(largeBuffer); + } + + stream.Write(largeBuffer); + } } - ZipFile.CreateFromDirectory(tempDir.FullName, zipArchivePath, CompressionLevel.NoCompression, includeBaseDirectory: false); + file = archive.CreateEntry(SmallFileName, compressLevel); - using ZipArchive zipArchive = ZipFile.OpenRead(zipArchivePath); - foreach (ZipArchiveEntry entry in zipArchive.Entries) + using (Stream stream = file.Open()) { - using Stream entryStream = entry.Open(); - - Assert.True(entryStream.CanRead); - Assert.Equal(buffer.Length, entryStream.Length); + stream.Write(smallBuffer); } } - finally + + fs.Position = 0; + + // Validate + using (ZipArchive archive = new(fs, ZipArchiveMode.Read)) { - File.Delete(zipArchivePath); + using var reader = new BinaryReader(fs); - tempDir.Delete(recursive: true); + FieldInfo offsetOfLHField = typeof(ZipArchiveEntry).GetField("_offsetOfLocalHeader", BindingFlags.NonPublic | BindingFlags.Instance); + + if (offsetOfLHField is null || offsetOfLHField.FieldType != typeof(long)) + { + Assert.Fail("Cannot find the private field of _offsetOfLocalHeader in ZipArchiveEntry or the type is not long. Code may be changed after the test is written."); + } + + foreach (ZipArchiveEntry entry in archive.Entries) + { + fs.Position = (long)offsetOfLHField.GetValue(entry) + ZipLocalFileHeader_OffsetToVersionFromHeaderStart; + ushort versionNeeded = reader.ReadUInt16(); + + // Version is not ZIP64 for files with Local Header at >4GB offset. + Assert.Equal(Zip64Version, versionNeeded); + } } } + finally + { + File.Delete(zipArchivePath); + } } } diff --git a/src/libraries/System.IO.Packaging/tests/LargeFilesTests.Net.cs b/src/libraries/System.IO.Packaging/tests/LargeFilesTests.Net.cs new file mode 100644 index 00000000000000..c073c09b8f92f7 --- /dev/null +++ b/src/libraries/System.IO.Packaging/tests/LargeFilesTests.Net.cs @@ -0,0 +1,97 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO.Compression; +using System.Net.Mime; +using System.Reflection; +using Xunit; + +namespace System.IO.Packaging.Tests; + +public partial class LargeFilesTests +{ + private static void FillWithHardToCompressData(byte[] buffer) + { + Random.Shared.NextBytes(buffer); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsSpeedOptimized), nameof(PlatformDetection.Is64BitProcess))] // don't run it on slower runtimes + [InlineData(false)] + [InlineData(true)] + [OuterLoop("It requires 5~6 GB of free disk space and a lot of CPU time for compressed tests")] + public static void CheckZIP64VersionIsSet_ForSmallFilesAfterBigFiles(bool isCompressed) + { + // issue #94899 + + CompressionOption compressionOption = isCompressed ? CompressionOption.Normal : CompressionOption.NotCompressed; + byte[] smallBuffer = GC.AllocateUninitializedArray(1000); + byte[] largeBuffer = GC.AllocateUninitializedArray(1_000_000_000); // ~1 GB + string zipArchivePath = Path.Combine(Path.GetTempPath(), "over4GB.zip"); + Uri largePartUri = PackUriHelper.CreatePartUri(new Uri("large.bin", UriKind.Relative)); + Uri smallPartUri = PackUriHelper.CreatePartUri(new Uri("small.bin", UriKind.Relative)); + uint ZipLocalFileHeader_OffsetToVersionFromHeaderStart = 4; + ushort Zip64Version = 45; + + try + { + using FileStream fs = File.Open(zipArchivePath, FileMode.Create, FileAccess.ReadWrite); + + // Create + using (Package package = Package.Open(fs, FileMode.Create, FileAccess.Write)) + { + PackagePart partLarge = package.CreatePart(largePartUri, MediaTypeNames.Application.Octet, compressionOption); + + using (Stream streamLarge = partLarge.GetStream()) + { + // Write 5GB of data + + for (var i = 0; i < 5; i++) + { + if (isCompressed) + { + FillWithHardToCompressData(largeBuffer); + } + + streamLarge.Write(largeBuffer); + } + } + + PackagePart partSmall = package.CreatePart(smallPartUri, MediaTypeNames.Application.Octet, compressionOption); + + using (Stream streamSmall = partSmall.GetStream()) + { + streamSmall.Write(smallBuffer); + } + } + + + fs.Position = 0; + + // Validate + using (ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Read)) + { + using var reader = new BinaryReader(fs); + + FieldInfo offsetOfLHField = typeof(ZipArchiveEntry).GetField("_offsetOfLocalHeader", BindingFlags.NonPublic | BindingFlags.Instance); + + if (offsetOfLHField is null || offsetOfLHField.FieldType != typeof(long)) + { + Assert.Fail("Cannot find the private field of _offsetOfLocalHeader in ZipArchiveEntry or the type is not long. Code may be changed after the test is written."); + } + + foreach (ZipArchiveEntry entry in archive.Entries) + { + fs.Position = (long)offsetOfLHField.GetValue(entry) + ZipLocalFileHeader_OffsetToVersionFromHeaderStart; + ushort versionNeeded = reader.ReadUInt16(); + + // Version is not ZIP64 for files with Local Header at >4GB offset. + Assert.Equal(Zip64Version, versionNeeded); + } + } + } + finally + { + File.Delete(zipArchivePath); + } + } +} diff --git a/src/libraries/System.IO.Packaging/tests/LargeFilesTests.cs b/src/libraries/System.IO.Packaging/tests/LargeFilesTests.cs new file mode 100644 index 00000000000000..e5e2350d7632bd --- /dev/null +++ b/src/libraries/System.IO.Packaging/tests/LargeFilesTests.cs @@ -0,0 +1,78 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.IO.Packaging.Tests; + +[Collection(nameof(DisableParallelization))] +public partial class LargeFileTests +{ + [Fact] + [OuterLoop] + public void VeryLargePart() + { + // FileAccess.Write is important, this tells ZipPackage to open the underlying ZipArchive in + // ZipArchiveMode.Create mode as opposed to ZipArchiveMode.Update + // When ZipArchive is opened in Create it will write entries directly to the zip stream + // When ZipArchive is opened in Update it will write uncompressed data to memory until + // the archive is closed. + using (Stream stream = new MemoryStream()) + { + Uri partUri = PackUriHelper.CreatePartUri(new Uri("test.bin", UriKind.Relative)); + + // should compress *very well* + byte[] buffer = new byte[1024 * 1024]; + for (int i = 0; i < buffer.Length; i++) + { + buffer[i] = (byte)(i % 2); + } + + const long SizeInMb = 6 * 1024; // 6GB + long totalLength = SizeInMb * buffer.Length; + + // issue on .NET Framework we cannot use FileAccess.Write on a ZipArchive + using (Package package = Package.Open(stream, FileMode.Create, PlatformDetection.IsNetFramework ? FileAccess.ReadWrite : FileAccess.Write)) + { + PackagePart part = package.CreatePart(partUri, + System.Net.Mime.MediaTypeNames.Application.Octet, + CompressionOption.Fast); + + + using (Stream partStream = part.GetStream()) + { + for (long i = 0; i < SizeInMb; i++) + { + partStream.Write(buffer, 0, buffer.Length); + } + } + } + + // reopen for read and make sure we can get the part length & data matches + stream.Seek(0, SeekOrigin.Begin); + using (Package readPackage = Package.Open(stream)) + { + PackagePart part = readPackage.GetPart(partUri); + + using (Stream partStream = part.GetStream()) + { + Assert.Equal(totalLength, partStream.Length); + byte[] readBuffer = new byte[buffer.Length]; + for (long i = 0; i < SizeInMb; i++) + { + int totalRead = 0; + while (totalRead < readBuffer.Length) + { + int actualRead = partStream.Read(readBuffer, totalRead, readBuffer.Length - totalRead); + Assert.InRange(actualRead, 1, readBuffer.Length - totalRead); + totalRead += actualRead; + } + + Assert.Equal(readBuffer.Length, totalRead); + Assert.True(buffer.AsSpan().SequenceEqual(readBuffer)); + } + } + } + } + } +} diff --git a/src/libraries/System.IO.Packaging/tests/System.IO.Packaging.Tests.csproj b/src/libraries/System.IO.Packaging/tests/System.IO.Packaging.Tests.csproj index 78bc14a789b086..c7bdadf60c902c 100644 --- a/src/libraries/System.IO.Packaging/tests/System.IO.Packaging.Tests.csproj +++ b/src/libraries/System.IO.Packaging/tests/System.IO.Packaging.Tests.csproj @@ -3,10 +3,14 @@ $(NetCoreAppCurrent);$(NetFrameworkCurrent) + + + + diff --git a/src/libraries/System.IO.Packaging/tests/Tests.cs b/src/libraries/System.IO.Packaging/tests/Tests.cs index 4d547db5e1c199..c3d8c6d3a39963 100644 --- a/src/libraries/System.IO.Packaging/tests/Tests.cs +++ b/src/libraries/System.IO.Packaging/tests/Tests.cs @@ -3771,74 +3771,6 @@ private void ForEachPartWithFileName(Package package, Action Date: Tue, 11 Jun 2024 11:16:51 -0500 Subject: [PATCH 775/783] Fix missing substitution (#103287) --- .../WorkloadManifest.json.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in index a6ca85da25d9bb..b9e4b4539a7563 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in @@ -396,7 +396,7 @@ "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvossimulator-x64" } }, - "Microsoft.NETCore.App.Runtime.AOT.Cross.ios-arm64": { + "Microsoft.NETCore.App.Runtime.AOT.Cross.${NetVersion}.ios-arm64": { "kind": "Sdk", "version": "${PackageVersion}", "alias-to": { From 7ab201156d03240d660c2ff291274f7f995f5743 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Tue, 11 Jun 2024 16:37:25 +0000 Subject: [PATCH 776/783] Bypassing Serialization Binders with BinaryFormatter Mutation --- .../Formatters/Binary/BinaryObjectWriter.cs | 19 ++++++++++++------- .../tests/BinaryFormatterTests.cs | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectWriter.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectWriter.cs index 925e6eca7e207e..2e6620a3c13f75 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectWriter.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectWriter.cs @@ -367,7 +367,7 @@ private void WriteMembers(NameInfo memberNameInfo, return; } - if (!WriteKnownValueClass(memberNameInfo, memberTypeNameInfo, memberData!)) + if (!WriteKnownValueClass(memberNameInfo, memberTypeNameInfo, memberData!, ref assignUniqueIdToValueType)) { if (outType == null) { @@ -616,10 +616,10 @@ private void WriteArrayMember(WriteObjectInfo objectInfo, NameInfo arrayElemType actualTypeInfo._isArrayItem = true; } - if (!WriteKnownValueClass(arrayElemTypeNameInfo, actualTypeInfo, data!)) + bool assignUniqueIdForValueTypes = false; + if (!WriteKnownValueClass(arrayElemTypeNameInfo, actualTypeInfo, data!, ref assignUniqueIdForValueTypes)) { object obj = data!; - bool assignUniqueIdForValueTypes = false; if (ReferenceEquals(arrayElemTypeNameInfo._type, Converter.s_typeofObject)) { assignUniqueIdForValueTypes = true; @@ -799,11 +799,12 @@ private long Schedule(object obj, bool assignUniqueIdToValueType, Type? type, Wr } // Determines if a type is a primitive type, if it is it is written - private bool WriteKnownValueClass(NameInfo memberNameInfo, NameInfo typeNameInfo, object data) + private bool WriteKnownValueClass(NameInfo memberNameInfo, NameInfo typeNameInfo, object data, ref bool assignUniqueIdToValueType) { if (ReferenceEquals(typeNameInfo._type, Converter.s_typeofString)) { WriteString(memberNameInfo, typeNameInfo, data); + return true; } else { @@ -817,18 +818,22 @@ private bool WriteKnownValueClass(NameInfo memberNameInfo, NameInfo typeNameInfo if (typeNameInfo._isArray) // null if an array { _serWriter.WriteItem(memberNameInfo, typeNameInfo, data); + return true; } - else + else if (memberNameInfo._type == typeNameInfo._type + || memberNameInfo._type == typeof(object) + || (memberNameInfo._type != null && Nullable.GetUnderlyingType(memberNameInfo._type) != null)) { _serWriter.WriteMember(memberNameInfo, typeNameInfo, data); + return true; } } } - return true; + assignUniqueIdToValueType = true; + return false; } - // Writes an object reference to the stream. private void WriteObjectRef(NameInfo nameInfo, long objectId) => _serWriter!.WriteMemberObjectRef(nameInfo, (int)objectId); diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTests.cs b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTests.cs index 95891b7bcfa3a3..cbc6107a5ad3b3 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTests.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTests.cs @@ -536,6 +536,25 @@ public void Roundtrip_ArrayContainingArrayAtNonZeroLowerBound() BinaryFormatterHelpers.Clone(Array.CreateInstance(typeof(uint[]), new[] { 5 }, new[] { 1 })); } + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, ".NET Framework has not been patched yet.")] + public void BypassingSerializationBinders() + { + Tuple tuple = new Tuple(42, new byte[] { 1, 2, 3, 4 }); + BinaryFormatter formatter = new BinaryFormatter(); + + using (MemoryStream stream = new MemoryStream()) + { + formatter.Serialize(stream, tuple); + + stream.Position = 0; + + Tuple deserialized = (Tuple)formatter.Deserialize(stream); + Assert.Equal(tuple.Item1, deserialized.Item1); + Assert.Equal(tuple.Item2, deserialized.Item2); + } + } + private static void ValidateEqualityComparer(object obj) { Type objType = obj.GetType(); From 6b7900d82e600f49fee8e6c9c8cc3bee838d9fb4 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:16:36 -0700 Subject: [PATCH 777/783] Update dependencies from https://github.com/dotnet/emsdk build 20240610.3 (#103291) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.7-servicing.24277.3 -> To Version 8.0.7-servicing.24310.3 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 1bea60ba70c248..532a7d4a54f8f6 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index da4282cc396150..0aec0da872178e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - f0463b32eee396d2d1caac58b271d683c7da2333 + 41fe641713abfc3ed87a017c93f0a649f5172fb1 - + https://github.com/dotnet/emsdk - f0463b32eee396d2d1caac58b271d683c7da2333 + 41fe641713abfc3ed87a017c93f0a649f5172fb1 From 7a45dc80f7b6750a92587f97e8de10d522314420 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 19:58:18 -0700 Subject: [PATCH 778/783] [release/8.0] Update dependencies from dotnet/emsdk (#103388) * Update dependencies from https://github.com/dotnet/emsdk build 20240612.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.7-servicing.24310.3 -> To Version 8.0.7-servicing.24312.2 * Update dependencies from https://github.com/dotnet/emsdk build 20240612.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.7-servicing.24310.3 -> To Version 8.0.7-servicing.24312.2 --------- Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 532a7d4a54f8f6..d46745fb69416d 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0aec0da872178e..ac008664d5338a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - 41fe641713abfc3ed87a017c93f0a649f5172fb1 + 727397ca6ba44045f3049fdb12d3908da3de8cee - + https://github.com/dotnet/emsdk - 41fe641713abfc3ed87a017c93f0a649f5172fb1 + 727397ca6ba44045f3049fdb12d3908da3de8cee From a82225ee6e7c2f1cc8e064b6320756b547faa358 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:01:46 -0500 Subject: [PATCH 779/783] Update dependencies from https://github.com/dotnet/emsdk build 20240613.1 (#103426) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.7-servicing.24312.2 -> To Version 8.0.7-servicing.24313.1 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index d46745fb69416d..b2329569aa4b76 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ac008664d5338a..b3b3b4e6f82ea1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - 727397ca6ba44045f3049fdb12d3908da3de8cee + a64772f521c578bc9925578b1384d3a08a02d31d - + https://github.com/dotnet/emsdk - 727397ca6ba44045f3049fdb12d3908da3de8cee + a64772f521c578bc9925578b1384d3a08a02d31d From 7916fff60ba5dc132c46ca14fc997e70045a6a73 Mon Sep 17 00:00:00 2001 From: vseanreesermsft <78103370+vseanreesermsft@users.noreply.github.com> Date: Tue, 2 Jul 2024 13:47:16 -0700 Subject: [PATCH 780/783] Update branding to 8.0.8 (#104312) --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 7528b6bfbf306d..b972545c2ba0e9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,11 +1,11 @@ - 8.0.7 + 8.0.8 8 0 - 7 + 8 8.0.100 7.0.20 6.0.$([MSBuild]::Add($(PatchVersion),25)) From 4a37e7305c99720bb14e328353a33456c49cb652 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 13:49:49 -0700 Subject: [PATCH 781/783] [release/8.0] Update dependencies from dotnet/emsdk (#103439) * Update dependencies from https://github.com/dotnet/emsdk build 20240613.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.7-servicing.24313.1 -> To Version 8.0.7-servicing.24313.2 * Update dependencies from https://github.com/dotnet/emsdk build 20240615.1 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.7-servicing.24313.1 -> To Version 8.0.7-servicing.24315.1 * Update dependencies from https://github.com/dotnet/emsdk build 20240615.3 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.7-servicing.24313.1 -> To Version 8.0.7-servicing.24315.3 * Update dependencies from https://github.com/dotnet/emsdk build 20240617.3 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.7-servicing.24313.1 -> To Version 8.0.7-servicing.24317.3 * Update dependencies from https://github.com/dotnet/emsdk build 20240624.2 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.7-servicing.24313.1 -> To Version 8.0.7-servicing.24324.2 * Update dependencies from https://github.com/dotnet/emsdk build 20240702.3 Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.7-servicing.24313.1 -> To Version 8.0.7-servicing.24352.3 --------- Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index b2329569aa4b76..acc903241aff80 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b3b3b4e6f82ea1..7ba81cd60285c2 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -92,11 +92,11 @@ https://github.com/dotnet/emsdk - a64772f521c578bc9925578b1384d3a08a02d31d + be13dabf6f89f0ee48705e71c5ccee961e200934 - + https://github.com/dotnet/emsdk - a64772f521c578bc9925578b1384d3a08a02d31d + be13dabf6f89f0ee48705e71c5ccee961e200934 From 1d8fcf1017d5c47233743470af1dc29382249fd0 Mon Sep 17 00:00:00 2001 From: Farhad Alizada <104755925+f-alizada@users.noreply.github.com> Date: Wed, 3 Jul 2024 20:30:16 +0200 Subject: [PATCH 782/783] Onboard new inter-branch merge flow [Workflow] (#103807) --- .github/workflows/inter-branch-merge-flow.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/workflows/inter-branch-merge-flow.yml diff --git a/.github/workflows/inter-branch-merge-flow.yml b/.github/workflows/inter-branch-merge-flow.yml new file mode 100644 index 00000000000000..7cd5b0c7a53ff1 --- /dev/null +++ b/.github/workflows/inter-branch-merge-flow.yml @@ -0,0 +1,13 @@ +name: Inter-branch merge workflow +on: + push: + branches: + - release/** + +permissions: + contents: write + pull-requests: write + +jobs: + Merge: + uses: dotnet/arcade/.github/workflows/inter-branch-merge-base.yml@main From fef6581b7b901e61255cd2ae73f17651bd17388d Mon Sep 17 00:00:00 2001 From: Steve Molloy Date: Thu, 11 Jul 2024 11:16:28 -0700 Subject: [PATCH 783/783] Don't dispose timers if we're in our UnhandledException handler. (#103937) --- .../src/System/Runtime/Caching/MemoryCache.cs | 6 ++++++ .../Runtime/Caching/MemoryCacheStatistics.cs | 15 +++++++++++++-- .../src/System/Runtime/Caching/SRef.cs | 5 +++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/MemoryCache.cs b/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/MemoryCache.cs index e740eed69ed514..e2c99f5a92e050 100644 --- a/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/MemoryCache.cs +++ b/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/MemoryCache.cs @@ -40,6 +40,7 @@ public class MemoryCache : ObjectCache, IEnumerable, IDisposable private bool _throwOnDisposed; private EventHandler _onAppDomainUnload; private UnhandledExceptionEventHandler _onUnhandledException; + private int _inUnhandledExceptionHandler; #if NETCOREAPP [UnsupportedOSPlatformGuard("browser")] private static bool _countersSupported => !OperatingSystem.IsBrowser(); @@ -238,14 +239,19 @@ private void OnAppDomainUnload(object unusedObject, EventArgs unusedEventArgs) Dispose(); } + internal bool InUnhandledExceptionHandler => _inUnhandledExceptionHandler > 0; private void OnUnhandledException(object sender, UnhandledExceptionEventArgs eventArgs) { + Interlocked.Increment(ref _inUnhandledExceptionHandler); + // if the CLR is terminating, dispose the cache. // This will dispose the perf counters if (eventArgs.IsTerminating) { Dispose(); } + + Interlocked.Decrement(ref _inUnhandledExceptionHandler); } private static void ValidatePolicy(CacheItemPolicy policy) diff --git a/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/MemoryCacheStatistics.cs b/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/MemoryCacheStatistics.cs index 96cfc3bda655bd..0599e8febc593c 100644 --- a/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/MemoryCacheStatistics.cs +++ b/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/MemoryCacheStatistics.cs @@ -340,8 +340,19 @@ public void Dispose() GCHandleRef timerHandleRef = _timerHandleRef; if (timerHandleRef != null && Interlocked.CompareExchange(ref _timerHandleRef, null, timerHandleRef) == timerHandleRef) { - timerHandleRef.Dispose(); - Dbg.Trace("MemoryCacheStats", "Stopped CacheMemoryTimers"); + // If inside an unhandled exception handler, Timers may be succeptible to deadlocks. Use a safer approach. + if (_memoryCache.InUnhandledExceptionHandler) + { + // This does not stop/dispose the timer. But the callback on the timer is protected by _disposed, which we have already + // set above. + timerHandleRef.FreeHandle(); + Dbg.Trace("MemoryCacheStats", "Freed CacheMemoryTimers"); + } + else + { + timerHandleRef.Dispose(); + Dbg.Trace("MemoryCacheStats", "Stopped CacheMemoryTimers"); + } } } while (_inCacheManagerThread != 0) diff --git a/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/SRef.cs b/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/SRef.cs index 9a09ba1d9781ae..412f66971a7fea 100644 --- a/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/SRef.cs +++ b/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/SRef.cs @@ -59,6 +59,11 @@ public T Target public void Dispose() { Target.Dispose(); + FreeHandle(); + } + + internal void FreeHandle() + { // Safe to call Dispose more than once but not thread-safe if (_handle.IsAllocated) {